summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/HW.cpp11
-rw-r--r--Source/Core/Core/Src/HW/SystemTimers.cpp13
-rw-r--r--Source/Core/Core/Src/HW/WII_IPC.cpp158
-rw-r--r--Source/Core/Core/Src/HW/WII_IPC.h17
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp254
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h9
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h12
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp670
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h66
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp362
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h47
11 files changed, 902 insertions, 717 deletions
diff --git a/Source/Core/Core/Src/HW/HW.cpp b/Source/Core/Core/Src/HW/HW.cpp
index 8cfd88e20c..6a05409f76 100644
--- a/Source/Core/Core/Src/HW/HW.cpp
+++ b/Source/Core/Core/Src/HW/HW.cpp
@@ -62,8 +62,8 @@ namespace HW
SystemTimers::Init();
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{
- WII_IPC_HLE_Interface::Init();
WII_IPCInterface::Init();
+ WII_IPC_HLE_Interface::Init();
}
}
@@ -80,8 +80,8 @@ namespace HW
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{
- WII_IPC_HLE_Interface::Shutdown();
WII_IPCInterface::Shutdown();
+ WII_IPC_HLE_Interface::Shutdown();
}
State_Shutdown();
@@ -100,12 +100,17 @@ namespace HW
GPFifo::DoState(p);
ExpansionInterface::DoState(p);
AudioInterface::DoState(p);
- WII_IPCInterface::DoState(p);
+ if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
+ {
+ WII_IPCInterface::DoState(p);
+ WII_IPC_HLE_Interface::DoState(p);
+ }
}
// Restart Wiimote
void InitWiimote()
{
WII_IPCInterface::Init();
+ WII_IPC_HLE_Interface::Init();
}
}
diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp
index b499f71feb..dbb58cdc7e 100644
--- a/Source/Core/Core/Src/HW/SystemTimers.cpp
+++ b/Source/Core/Core/Src/HW/SystemTimers.cpp
@@ -102,6 +102,7 @@ broadway: 729
// So, ratio is 1 / (1/4 * 1/3 = 1/12) = 12.
// note: ZWW is ok and faster with TIMER_RATIO=8 though.
// !!! POSSIBLE STABLE PERF BOOST HACK THERE !!!
+
enum
{
TIMER_RATIO = 12
@@ -174,15 +175,14 @@ void AudioFifoCallback(u64 userdata, int cyclesLate)
void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate)
{
- WII_IPC_HLE_Interface::UpdateDevices();
- CoreTiming::ScheduleEvent(IPC_HLE_PERIOD-cyclesLate, et_IPC_HLE);
+ if (Core::GetStartupParameter().bWii)
+ WII_IPC_HLE_Interface::Update();
+
+ CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine()-cyclesLate, et_IPC_HLE);
}
void VICallback(u64 userdata, int cyclesLate)
{
- if (Core::GetStartupParameter().bWii)
- WII_IPC_HLE_Interface::Update();
-
VideoInterface::Update();
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerLine() - cyclesLate, et_VI);
}
@@ -252,6 +252,9 @@ void Init()
if (!UsingDSPLLE)
DSP_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
+ // AyuanX: TO BE TWEAKED
+ // If this update frequency is too high, WiiMote could easily jam the IPC Bus
+ // but if it is too low, sometimes IPC gets overflown by CPU :~~~(
IPC_HLE_PERIOD = (int)(GetTicksPerSecond() * 0.003f);
}
else
diff --git a/Source/Core/Core/Src/HW/WII_IPC.cpp b/Source/Core/Core/Src/HW/WII_IPC.cpp
index fda27297db..424487fdf2 100644
--- a/Source/Core/Core/Src/HW/WII_IPC.cpp
+++ b/Source/Core/Core/Src/HW/WII_IPC.cpp
@@ -85,36 +85,46 @@ union UIPC_Config
};
// STATE_TO_SAVE
-UIPC_Status g_IPC_Status;
-UIPC_Config g_IPC_Config;
-UIPC_Control g_IPC_Control;
-
-u32 g_Address = 0;
-u32 g_Reply = 0;
-u32 g_SensorBarPower = 0;
+bool g_ExeCmd = false;
+u32 g_Address = NULL;
+u32 g_Reply = NULL;
+u32 g_ReplyHead = NULL;
+u32 g_ReplyTail = NULL;
+u32 g_SensorBarPower = NULL;
+UIPC_Status g_IPC_Status(NULL);
+UIPC_Config g_IPC_Config(NULL);
+UIPC_Control g_IPC_Control(NULL);
void DoState(PointerWrap &p)
{
- p.Do(g_IPC_Status);
- p.Do(g_IPC_Config);
- p.Do(g_IPC_Control);
+ p.Do(g_ExeCmd);
p.Do(g_Address);
p.Do(g_Reply);
+ p.Do(g_ReplyHead);
+ p.Do(g_ReplyTail);
p.Do(g_SensorBarPower);
+ p.Do(g_IPC_Status);
+ p.Do(g_IPC_Config);
+ p.Do(g_IPC_Control);
}
-void UpdateInterrupts();
-
// Init
void Init()
{
- g_Address = 0;
- g_Reply = 0;
- g_SensorBarPower = 0;
+ g_ExeCmd = false;
+ g_Address = NULL;
+ g_Reply = NULL;
+ g_ReplyHead = NULL;
+ g_ReplyTail = NULL;
+ g_SensorBarPower = NULL;
+ g_IPC_Status = UIPC_Status(NULL);
+ g_IPC_Config = UIPC_Config(NULL);
+ g_IPC_Control = UIPC_Control(NULL);
+}
- g_IPC_Status = UIPC_Status();
- g_IPC_Config = UIPC_Config();
- g_IPC_Control = UIPC_Control();
+void Reset()
+{
+ Init();
}
void Shutdown()
@@ -127,16 +137,16 @@ void Read32(u32& _rReturnValue, const u32 _Address)
{
case IPC_CONTROL_REGISTER:
_rReturnValue = g_IPC_Control.Hex;
- INFO_LOG(WII_IPC, "IOP: Read32 from IPC_CONTROL_REGISTER(0x04) = 0x%08x", _rReturnValue);
+ INFO_LOG(WII_IPC, "IOP: Read32, IPC_CONTROL_REGISTER(0x04) = 0x%08x [R:%i A:%i E:%i]",
+ _rReturnValue, (_rReturnValue>>2)&1, (_rReturnValue>>1)&1, _rReturnValue&1);
// if ((REASON_REG & 0x14) == 0x14) CALL IPCReplayHanlder
// if ((REASON_REG & 0x22) != 0x22) Jumps to the end
-
break;
case IPC_REPLY_REGISTER: // looks a little bit like a callback function
_rReturnValue = g_Reply;
- INFO_LOG(WII_IPC, "IOP: Write32 to IPC_REPLAY_REGISTER(0x08) = 0x%08x ", _rReturnValue);
+ INFO_LOG(WII_IPC, "IOP: Read32, IPC_REPLY_REGISTER(0x08) = 0x%08x ", _rReturnValue);
break;
case IPC_SENSOR_BAR_POWER_REGISTER:
@@ -146,7 +156,7 @@ void Read32(u32& _rReturnValue, const u32 _Address)
default:
_dbg_assert_msg_(WII_IPC, 0, "IOP: Read32 from 0x%08x", _Address);
break;
- }
+ }
}
void Write32(const u32 _Value, const u32 _Address)
@@ -157,30 +167,36 @@ void Write32(const u32 _Value, const u32 _Address)
case IPC_COMMAND_REGISTER: // __ios_Ipc2 ... a value from __responses is loaded
{
g_Address = _Value;
- INFO_LOG(WII_IPC, "IOP: Write32 to IPC_ADDRESS_REGISTER(0x00) = 0x%08x", g_Address);
+ INFO_LOG(WII_IPC, "IOP: Write32, IPC_ADDRESS_REGISTER(0x00) = 0x%08x", g_Address);
}
break;
case IPC_CONTROL_REGISTER:
{
- INFO_LOG(WII_IPC, "IOP: Write32 to IPC_CONTROL_REGISTER(0x04) = 0x%08x (old: 0x%08x)", _Value, g_IPC_Control.Hex);
+ INFO_LOG(WII_IPC, "IOP: Write32, IPC_CONTROL_REGISTER(0x04) = 0x%08x [R:%i A:%i E:%i] (old: 0x%08x) ",
+ _Value, (_Value>>2)&1, (_Value>>1)&1, _Value&1, g_IPC_Control.Hex);
UIPC_Control TempControl(_Value);
_dbg_assert_msg_(WII_IPC, TempControl.pad == 0, "IOP: Write to UIPC_Control.pad", _Address);
-
if (TempControl.AckReady) { g_IPC_Control.AckReady = 0; }
if (TempControl.ReplyReady) { g_IPC_Control.ReplyReady = 0; }
- if (TempControl.Relaunch) { g_IPC_Control.Relaunch = 0; }
-
+
+ // Ayuanx: What is this Relaunch bit used for ???
+ // I have done considerable amount of tests that show no use of it at all
+ // So I'm commenting this out
+ //
+ //if (TempControl.Relaunch) { g_IPC_Control.Relaunch = 0; }
+
+ g_IPC_Control.Relaunch = TempControl.Relaunch;
g_IPC_Control.unk5 = TempControl.unk5;
g_IPC_Control.unk6 = TempControl.unk6;
g_IPC_Control.pad = TempControl.pad;
if (TempControl.ExecuteCmd)
{
- WII_IPC_HLE_Interface::AckCommand(g_Address);
- }
+ g_ExeCmd = true;
+ }
}
break;
@@ -189,21 +205,22 @@ void Write32(const u32 _Value, const u32 _Address)
UIPC_Status NewStatus(_Value);
if (NewStatus.INTERRUPT) g_IPC_Status.INTERRUPT = 0; // clear interrupt
- INFO_LOG(WII_IPC, "IOP: Write32 to IPC_STATUS_REGISTER(0x30) = 0x%08x", _Value);
+ INFO_LOG(WII_IPC, "IOP: Write32, IPC_STATUS_REGISTER(0x30) = 0x%08x", _Value);
}
break;
case IPC_CONFIG_REGISTER: // __OSInterruptInit (0x40000000)
{
- INFO_LOG(WII_IPC, "IOP: Write32 to IPC_CONFIG_REGISTER(0x33) = 0x%08x", _Value);
- g_IPC_Config.Hex = _Value;
-
-
- if (_Value&0x40000000)
- {
- WII_IPC_HLE_Interface::Reset();
- }
+ INFO_LOG(WII_IPC, "IOP: Write32, IPC_CONFIG_REGISTER(0x33) = 0x%08x", _Value);
+ g_IPC_Config.Hex = _Value;
+
+ if (_Value&0x40000000)
+ {
+ INFO_LOG(WII_IPC, "Reset triggered, Resetting ...");
+ Reset();
+ WII_IPC_HLE_Interface::Reset();
+ }
}
break;
@@ -217,11 +234,58 @@ void Write32(const u32 _Value, const u32 _Address)
}
break;
}
-
// update the interrupts
UpdateInterrupts();
}
+u32 GetAddress()
+{
+ return ((g_ExeCmd) ? g_Address : NULL);
+}
+
+void GenerateAck()
+{
+ g_ExeCmd = false;
+ g_IPC_Control.AckReady = 1;
+ UpdateInterrupts();
+}
+
+void GenerateReply(u32 _Address)
+{
+ g_Reply = _Address;
+ g_IPC_Control.ReplyReady = 1;
+ UpdateInterrupts();
+}
+
+void EnqReply(u32 _Address)
+{
+ // AyuanX: Replies are stored in a FIFO (depth 2), like ping-pong, and 2 is fairly enough
+ // Simple structure of fixed length will do good for DoState
+ //
+ if (g_ReplyHead == NULL)
+ {
+ g_ReplyHead = g_ReplyTail;
+ g_ReplyTail = _Address;
+ }
+ else
+ {
+ ERROR_LOG(WII_IPC, "Reply FIFO is full, something must be wrong!");
+ PanicAlert("WII_IPC: Reply FIFO is full, something must be wrong!");
+ }
+}
+
+u32 DeqReply()
+{
+ u32 _Address = (g_ReplyHead) ? g_ReplyHead : g_ReplyTail;
+
+ if (g_ReplyHead)
+ g_ReplyHead = NULL;
+ else
+ g_ReplyTail = NULL;
+
+ return _Address;
+}
+
void UpdateInterrupts()
{
if ((g_IPC_Control.AckReady == 1) ||
@@ -246,22 +310,6 @@ bool IsReady()
return ((g_IPC_Control.ReplyReady == 0) && (g_IPC_Control.AckReady == 0) && (g_IPC_Status.INTERRUPT == 0));
}
-void GenerateAck(u32 _AnswerAddress)
-{
- g_Reply = _AnswerAddress;
- g_IPC_Control.AckReady = 1;
-
- UpdateInterrupts();
-}
-
-void GenerateReply(u32 _AnswerAddress)
-{
- g_Reply = _AnswerAddress;
- g_IPC_Control.ReplyReady = 1;
-
- UpdateInterrupts();
-}
-
} // end of namespace IPC
diff --git a/Source/Core/Core/Src/HW/WII_IPC.h b/Source/Core/Core/Src/HW/WII_IPC.h
index 3ca4b012df..5b4947fa96 100644
--- a/Source/Core/Core/Src/HW/WII_IPC.h
+++ b/Source/Core/Core/Src/HW/WII_IPC.h
@@ -24,18 +24,23 @@ namespace WII_IPCInterface
{
void Init();
+void Reset();
void Shutdown();
void DoState(PointerWrap &p);
-void Update();
-bool IsReady();
-void GenerateReply(u32 _AnswerAddress);
-void GenerateAck(u32 _AnswerAddress);
-
void Read32(u32& _rReturnValue, const u32 _Address);
-
void Write32(const u32 _Value, const u32 _Address);
+u32 GetAddress();
+void GenerateAck();
+void GenerateReply(u32 _Address);
+void InsertReply(u32 _Address);
+void EnqReply(u32 _Address);
+u32 DeqReply();
+
+void UpdateInterrupts();
+bool IsReady();
+
} // end of namespace AudioInterface
#endif
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 6d45e9a8c3..91e111f138 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -66,6 +66,7 @@
#include "../Debugger/Debugger_SymbolMap.h"
#include "../PowerPC/PowerPC.h"
+
namespace WII_IPC_HLE_Interface
{
@@ -74,11 +75,6 @@ TDeviceMap g_DeviceMap;
// STATE_TO_SAVE
u32 g_LastDeviceID = 0x13370000;
-std::list<u32> g_Ack;
-u32 g_AckNumber = 0;
-std::queue<std::pair<u32,std::string> > g_ReplyQueue;
-void ExecuteCommand(u32 _Address);
-
std::string g_DefaultContentFile;
// General IPC functions
@@ -89,27 +85,22 @@ 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())
{
- delete itr->second;
- ++itr;
+ if (itr->second)
+ delete itr->second;
+ ++itr;
}
g_DeviceMap.clear();
-
- while (!g_ReplyQueue.empty())
- {
- g_ReplyQueue.pop();
- }
-
- g_Ack.clear();
}
void Shutdown()
{
Reset();
g_LastDeviceID = 0x13370000;
- g_AckNumber = 0;
g_DefaultContentFile.clear();
}
@@ -237,31 +228,7 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName
debugging I also noticed that the Ioctl arguments are stored temporarily in
0x933e.... with the same .... as in the _CommandAddress. */
// ----------------
-bool AckCommand(u32 _Address)
-{
-#if MAX_LOG_LEVEL >= DEBUG_LEVEL
- Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG);
-#endif
- INFO_LOG(WII_IPC_HLE, "AckCommand: 0%08x (num: %i) PC=0x%08x", _Address, g_AckNumber, PC);
- std::list<u32>::iterator itr = g_Ack.begin();
- while (itr != g_Ack.end())
- {
- if (*itr == _Address)
- {
- ERROR_LOG(WII_IPC_HLE, "execute a command two times");
- PanicAlert("execute a command two times");
- return false;
- }
-
- itr++;
- }
-
- g_Ack.push_back(_Address);
- g_AckNumber++;
-
- return true;
-}
// Let the game read the setting.txt file
void CopySettingsFile(std::string DeviceName)
@@ -289,12 +256,30 @@ void CopySettingsFile(std::string DeviceName)
}
}
+void DoState(PointerWrap &p)
+{
+ p.Do(g_LastDeviceID);
+ //p.Do(g_DefaultContentFile);
+
+ // AyuanX: I think maybe we really should create devices statically at initilization
+ 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!");
+}
+
void ExecuteCommand(u32 _Address)
{
- bool GenerateReply = false;
+ bool CmdSuccess = false;
u32 ClosedDeviceID = 0;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
+ u32 DeviceID = Memory::Read_U32(_Address + 8);
+ IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
+
+ INFO_LOG(WII_IPC_HLE, "-->> Execute Command Address: 0x%08x (code: %x, device: %x) ", _Address, Command, DeviceID);
+
switch (Command)
{
case COMMAND_OPEN_DEVICE:
@@ -308,7 +293,7 @@ void ExecuteCommand(u32 _Address)
if(DeviceName.find("setting.txt") != std::string::npos) CopySettingsFile(DeviceName);
u32 Mode = Memory::Read_U32(_Address + 0x10);
- u32 DeviceID = GetDeviceIDByName(DeviceName);
+ DeviceID = GetDeviceIDByName(DeviceName);
// check if a device with this name has been created already
if (DeviceID == 0)
@@ -317,16 +302,16 @@ void ExecuteCommand(u32 _Address)
// alternatively we could pre create all devices and put them in a directory tree structure
// then this would just return a pointer to the wanted device.
u32 CurrentDeviceID = g_LastDeviceID;
- IWII_IPC_HLE_Device* pDevice = CreateDevice(CurrentDeviceID, DeviceName);
+ pDevice = CreateDevice(CurrentDeviceID, DeviceName);
g_DeviceMap[CurrentDeviceID] = pDevice;
g_LastDeviceID++;
- GenerateReply = pDevice->Open(_Address, Mode);
+ 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, GenerateReply=%i)",
- pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode, (int)GenerateReply);
+ INFO_LOG(WII_IPC_FILEIO, "IOP: Open (Device=%s, DeviceID=%08x, Mode=%i, CmdSuccess=%i)",
+ pDevice->GetDeviceName().c_str(), CurrentDeviceID, Mode, (int)CmdSuccess);
}
else
{
@@ -337,13 +322,13 @@ void ExecuteCommand(u32 _Address)
else
{
// The device has already been opened and was not closed, reuse the same DeviceID.
+ pDevice = AccessDeviceByID(DeviceID);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
- // If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call
+ // If we return -6 here after a Open > Failed > CREATE_FILE > ReOpen call
// sequence Mario Galaxy and Mario Kart Wii will not start writing to the file,
// it will just (seemingly) wait for one or two seconds and then give an error
// message. So I'm trying to return the DeviceID instead to make it write to the file.
- // (Which was most likely the reason it created the file in the first place.) */
+ // (Which was most likely the reason it created the file in the first place.)
// F|RES: prolly the re-open is just a mode change
@@ -359,81 +344,69 @@ void ExecuteCommand(u32 _Address)
// Open > Failed > ... other stuff > ReOpen call sequence, in that case
// we have no file and no file handle, so we call Open again to basically
// get a -106 error so that the game call CreateFile and then ReOpen again.
+
if(pDevice->ReturnFileHandle())
Memory::Write_U32(DeviceID, _Address + 4);
else
- GenerateReply = pDevice->Open(_Address, newMode);
+ pDevice->Open(_Address, newMode);
}
else
{
// We have already opened this device, return -6
Memory::Write_U32(u32(-6), _Address + 4);
}
- GenerateReply = true;
- }
+ CmdSuccess = true;
+ }
}
break;
case COMMAND_CLOSE_DEVICE:
- {
- u32 DeviceID = Memory::Read_U32(_Address + 8);
-
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
+ {
if (pDevice != NULL)
{
pDevice->Close(_Address);
// Delete the device when CLOSE is called, this does not effect
// GenerateReply() for any other purpose than the logging because
- // it's a true / false only function //
+ // it's a true / false only function
ClosedDeviceID = DeviceID;
- GenerateReply = true;
+ CmdSuccess = true;
}
}
break;
case COMMAND_READ:
{
- u32 DeviceID = Memory::Read_U32(_Address+8);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
if (pDevice != NULL)
- GenerateReply = pDevice->Read(_Address);
+ CmdSuccess = pDevice->Read(_Address);
}
break;
case COMMAND_WRITE:
{
- u32 DeviceID = Memory::Read_U32(_Address+8);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
if (pDevice != NULL)
- GenerateReply = pDevice->Write(_Address);
+ CmdSuccess = pDevice->Write(_Address);
}
break;
case COMMAND_SEEK:
{
- u32 DeviceID = Memory::Read_U32(_Address+8);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
if (pDevice != NULL)
- GenerateReply = pDevice->Seek(_Address);
+ CmdSuccess = pDevice->Seek(_Address);
}
break;
case COMMAND_IOCTL:
{
- u32 DeviceID = Memory::Read_U32(_Address+8);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
if (pDevice != NULL)
- GenerateReply = pDevice->IOCtl(_Address);
+ CmdSuccess = pDevice->IOCtl(_Address);
}
break;
case COMMAND_IOCTLV:
{
- u32 DeviceID = Memory::Read_U32(_Address+8);
- IWII_IPC_HLE_Device* pDevice = AccessDeviceByID(DeviceID);
if (pDevice)
- GenerateReply = pDevice->IOCtlV(_Address);
+ CmdSuccess = pDevice->IOCtlV(_Address);
}
break;
@@ -443,88 +416,101 @@ void ExecuteCommand(u32 _Address)
break;
}
+
// It seems that the original hardware overwrites the command after it has been
// executed. We write 8 which is not any valid command.
- Memory::Write_U32(8, _Address);
+ //
+ // AyuanX: Is this really necessary?
+ // My experiment says no, so I'm just commenting this out
+ //
+ //Memory::Write_U32(8, _Address);
- // Generate a reply to the IPC command
- if (GenerateReply)
+ if (CmdSuccess)
{
- // Get device id
- u32 DeviceID = Memory::Read_U32(_Address + 8);
- IWII_IPC_HLE_Device* pDevice = NULL;
+ // Generate a reply to the IPC command
+ WII_IPCInterface::EnqReply(_Address);
- // Get the device from the device map
- if (DeviceID != 0) {
- if (g_DeviceMap.find(DeviceID) != g_DeviceMap.end())
- pDevice = g_DeviceMap[DeviceID];
-
- if (pDevice != NULL) {
- // Write reply, this will later be executed in Update()
- g_ReplyQueue.push(std::pair<u32, std::string>(_Address, pDevice->GetDeviceName()));
- } else {
+ u32 DeviceID = Memory::Read_U32(_Address + 8);
+ // DeviceID == 0 means it's used for devices that weren't created yet
+ if (DeviceID != 0)
+ {
+ if (g_DeviceMap.find(DeviceID) == g_DeviceMap.end())
ERROR_LOG(WII_IPC_HLE, "IOP: Reply to unknown device ID (DeviceID=%i)", DeviceID);
- g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
- }
- if (ClosedDeviceID > 0 && ClosedDeviceID == DeviceID)
+ if (ClosedDeviceID > 0 && (ClosedDeviceID == DeviceID))
DeleteDeviceByID(DeviceID);
-
- } else {
- // 0 is ok, as it's used for devices that weren't created yet
- g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
}
}
+ else
+ {
+ //INFO_LOG(WII_IPC_HLE, "<<-- Failed or Not Ready to Reply to Command Address: 0x%08x ", _Address);
+ }
}
// ===================================================
-/* This is called continuously from SystemTimers.cpp and WII_IPCInterface::IsReady()
- is controlled from WII_IPC.cpp. */
-// ----------------
-void UpdateDevices()
+// This is called continuously from SystemTimers.cpp
+// ---------------------------------------------------
+void Update()
{
- if (WII_IPCInterface::IsReady())
- {
- // check if an executed must be updated
- TDeviceMap::const_iterator itr = g_DeviceMap.begin();
- while(itr != g_DeviceMap.end())
- {
- u32 CommandAddr = itr->second->Update();
- if (CommandAddr != 0)
- {
- g_ReplyQueue.push(std::pair<u32, std::string>(CommandAddr, itr->second->GetDeviceName()));
- }
- ++itr;
- }
- }
+ if (WII_IPCInterface::IsReady() == false)
+ return;
+
+ UpdateDevices();
+
+ // if we have a reply to send
+ u32 _Reply = WII_IPCInterface::DeqReply();
+ if (_Reply != NULL)
+ {
+ WII_IPCInterface::GenerateReply(_Reply);
+ INFO_LOG(WII_IPC_HLE, "<<-- Reply to Command Address: 0x%08x", _Reply);
+ return;
+ }
+
+ // If there is a a new command
+ u32 _Address = WII_IPCInterface::GetAddress();
+ if (_Address != NULL)
+ {
+ WII_IPCInterface::GenerateAck();
+ INFO_LOG(WII_IPC_HLE, "||-- Acknowledge Command Address: 0x%08x", _Address);
+
+ ExecuteCommand(_Address);
+
+ // AyuanX: Since current HLE time slot is empty, we can piggyback a reply
+ // Besides, this trick makes a Ping-Pong Reply FIFO never get full
+ // I don't know whether original hardware supports this feature or not
+ // but it works here and we gain 1/3 extra bandwidth
+ //
+ u32 _Reply = WII_IPCInterface::DeqReply();
+ if (_Reply != NULL)
+ {
+ WII_IPCInterface::GenerateReply(_Reply);
+ INFO_LOG(WII_IPC_HLE, "<<-- Reply to Command Address: 0x%08x", _Reply);
+ }
+
+ #if MAX_LOG_LEVEL >= DEBUG_LEVEL
+ Debugger::PrintCallstack(LogTypes::WII_IPC_HLE, LogTypes::LDEBUG);
+ #endif
+
+ return;
+ }
+
}
-void Update()
+void UpdateDevices()
{
- if (WII_IPCInterface::IsReady())
- {
- // Check if we have to execute an acknowledge command...
- if (!g_ReplyQueue.empty())
- {
- WII_IPCInterface::GenerateReply(g_ReplyQueue.front().first);
- g_ReplyQueue.pop();
- return;
- }
+ // check if a device must be updated
+ TDeviceMap::const_iterator itr = g_DeviceMap.begin();
- // ...no we don't, we can now execute the IPC command
- if (g_ReplyQueue.empty() && !g_Ack.empty())
- {
- u32 _Address = g_Ack.front();
- g_Ack.pop_front();
- DEBUG_LOG(WII_IPC_HLE, "-- Execute Ack (0x%08x)", _Address);
- ExecuteCommand(_Address);
- DEBUG_LOG(WII_IPC_HLE, "-- End of ExecuteAck (0x%08x)", _Address);
-
- // Go back to WII_IPC.cpp and generate an acknowledgement
- WII_IPCInterface::GenerateAck(_Address);
- }
+ while(itr != g_DeviceMap.end())
+ {
+ if (itr->second->Update())
+ {
+ break;
+ }
+ ++itr;
}
}
+
} // end of namespace IPC
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 4c86ebd5be..6941eb0238 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h
@@ -18,9 +18,10 @@
#ifndef _WII_IPC_HLE_H_
#define _WII_IPC_HLE_H_
+#include "ChunkFile.h"
+
namespace WII_IPC_HLE_Interface
{
-
// Init
void Init();
@@ -30,6 +31,9 @@ void Shutdown();
// Reset
void Reset();
+// Do State
+void DoState(PointerWrap &p);
+
// Set default content file
void SetDefaultContentFile(const std::string& _rFilename);
@@ -39,8 +43,7 @@ void Update();
// Update Devices
void UpdateDevices();
-// Acknowledge command
-bool AckCommand(u32 _Address);
+void ExecuteCommand(u32 _Address);
enum ECommandType
{
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h
index 8a9db90739..d4c1dfd18e 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h
@@ -22,6 +22,8 @@
#include "../HW/Memmap.h"
#include "../HW/CPU.h"
+class PointerWrap;
+
class IWII_IPC_HLE_Device
{
public:
@@ -34,6 +36,9 @@ public:
virtual ~IWII_IPC_HLE_Device()
{}
+ virtual void DoState(PointerWrap &p)
+ {}
+
const std::string& GetDeviceName() const { return m_Name; }
u32 GetDeviceID() const { return m_DeviceID; }
@@ -114,14 +119,12 @@ protected:
}
}
- // STATE_TO_SAVE
const u32 m_Address;
u32 Parameter;
u32 NumberInBuffer;
u32 NumberPayloadBuffer;
u32 BufferVector;
- u32 BufferSize;
struct SBuffer { u32 m_Address, m_Size; };
std::vector<SBuffer> InBuffer;
@@ -152,9 +155,8 @@ protected:
LogTypes::LOG_LEVELS Verbosity = LogTypes::LDEBUG)
{
GENERIC_LOG(LogType, Verbosity, "======= DumpAsync ======");
- // write return value
+
u32 BufferOffset = BufferVector;
- Memory::Write_U32(1, _CommandAddress + 0x4);
for (u32 i = 0; i < NumberInBuffer; i++)
{
@@ -180,8 +182,6 @@ protected:
u32 OutBuffer = Memory::Read_U32(BufferOffset); BufferOffset += 4;
u32 OutBufferSize = Memory::Read_U32(BufferOffset); BufferOffset += 4;
- Memory::Write_U32(1, _CommandAddress + 0x4);
-
GENERIC_LOG(LogType, LogTypes::LINFO, "%s - IOCtlV OutBuffer[%i]:", GetDeviceName().c_str(), i);
GENERIC_LOG(LogType, LogTypes::LINFO, " OutBuffer: 0x%08x (0x%x):", OutBuffer, OutBufferSize);
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 28a756805b..494d99003b 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
@@ -22,15 +22,10 @@
#include "../Debugger/Debugger_SymbolMap.h"
#include "../Host.h"
#include "../PluginManager.h"
+#include "../HW/WII_IPC.h"
+#include "WII_IPC_HLE.h"
#include "WII_IPC_HLE_Device_usb.h"
-
-// Ugly hacks for "SendEventNumberOfCompletedPackets"
-int g_HCICount = 0;
-int g_GlobalHandle = 0;
-
-
-
// The device class
CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
@@ -42,10 +37,14 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
, m_HostMaxSCOSize(0)
, m_HostNumACLPackets(0)
, m_HostNumSCOPackets(0)
- , m_pACLBuffer(NULL)
- , m_pHCIBuffer(NULL)
+ , m_HCIBuffer(NULL)
+ , m_ACLBuffer(NULL)
+ , m_ACLFrame(0)
+ , m_LastCmd(NULL)
+ , m_PacketCount(0)
{
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, 0));
+ // Connect one Wiimote by default
m_ControllerBD.b[0] = 0x11;
m_ControllerBD.b[1] = 0x02;
@@ -66,6 +65,16 @@ 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()
{}
+void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
+{
+ p.Do(m_LastCmd);
+ p.Do(m_PacketCount);
+ p.Do(m_CtrlSetup);
+ p.Do(m_HCIBuffer);
+ p.Do(m_ACLBuffer);
+ p.Do(m_ACLFrame);
+}
+
// ===================================================
// Open
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::Open(u32 _CommandAddress, u32 _Mode)
@@ -96,27 +105,19 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtl(u32 _CommandAddress)
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
{
/*
-
- Memory::Write_U8(255, 0x80149950); // BTM LOG
- // 3 logs L2Cap
- // 4 logs l2_csm$
-
+ Memory::Write_U8(255, 0x80149950); // BTM LOG // 3 logs L2Cap // 4 logs l2_csm$
Memory::Write_U8(255, 0x80149949); // Security Manager
-
Memory::Write_U8(255, 0x80149048); // HID
+ Memory::Write_U8(3, 0x80152058); // low ?? // >= 4 and you will get a lot of event messages of the same type
+ Memory::Write_U8(1, 0x80152018); // WUD
+ Memory::Write_U8(1, 0x80151FC8); // DEBUGPrint
+ Memory::Write_U8(1, 0x80151488); // WPAD_LOG
+ Memory::Write_U8(1, 0x801514A8); // USB_LOG
+ Memory::Write_U8(1, 0x801514D8); // WUD_DEBUGPrint
+ Memory::Write_U8(1, 0x80148E09); // HID LOG
+*/
- Memory::Write_U8(3, 0x80152058); // low ?? // >= 4 and you will get a lot of event messages of the same type
-
- Memory::Write_U8(1, 0x80152018); // WUD
-
- Memory::Write_U8(1, 0x80151FC8); // DEBUGPrint */
-
-
- // even it it wasn't very useful yet...
- // Memory::Write_U8(1, 0x80151488); // WPAD_LOG
- // Memory::Write_U8(1, 0x801514A8); // USB_LOG
- // Memory::Write_U8(1, 0x801514D8); // WUD_DEBUGPrint
- // Memory::Write_U8(1, 0x80148E09); // HID LOG
+ bool _SendReply = false;
SIOCtlVBuffer CommandBuffer(_CommandAddress);
@@ -124,37 +125,31 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
{
case USB_IOCTL_HCI_COMMAND_MESSAGE:
{
- SHCICommandMessage CtrlSetup;
-
- // the USB stuff is little endian..
- CtrlSetup.bRequestType = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
- CtrlSetup.bRequest = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address);
- CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address);
- CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address);
- CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address);
- CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address;
- CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size;
+ // This is the HCI datapath from CPU to Wiimote, the USB stuff is little endian..
+ m_CtrlSetup.bRequestType = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address);
+ m_CtrlSetup.bRequest = *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[1].m_Address);
+ m_CtrlSetup.wValue = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[2].m_Address);
+ m_CtrlSetup.wIndex = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[3].m_Address);
+ m_CtrlSetup.wLength = *(u16*)Memory::GetPointer(CommandBuffer.InBuffer[4].m_Address);
+ m_CtrlSetup.m_PayLoadAddr = CommandBuffer.PayloadBuffer[0].m_Address;
+ m_CtrlSetup.m_PayLoadSize = CommandBuffer.PayloadBuffer[0].m_Size;
+ m_CtrlSetup.m_Address = CommandBuffer.m_Address;
// check termination
_dbg_assert_msg_(WII_IPC_WIIMOTE, *(u8*)Memory::GetPointer(CommandBuffer.InBuffer[5].m_Address) == 0,
"WIIMOTE: Termination != 0");
-#if 0
- INFO_LOG(WII_IPC_WIIMOTE, "USB_IOCTL_CTRLMSG (0x%08x) - execute command", _CommandAddress);
-
- DEBUG_LOG(WII_IPC_WIIMOTE, " bRequestType: 0x%x", CtrlSetup.bRequestType);
- DEBUG_LOG(WII_IPC_WIIMOTE, " bRequest: 0x%x", CtrlSetup.bRequest);
- DEBUG_LOG(WII_IPC_WIIMOTE, " wValue: 0x%x", CtrlSetup.wValue);
- DEBUG_LOG(WII_IPC_WIIMOTE, " wIndex: 0x%x", CtrlSetup.wIndex);
- DEBUG_LOG(WII_IPC_WIIMOTE, " wLength: 0x%x", CtrlSetup.wLength);
-#endif
-
- ExecuteHCICommandMessage(CtrlSetup);
-
- // control message has been sent executed
- Memory::Write_U32(0, _CommandAddress + 0x4);
-
- return true;
+ 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);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " wValue: 0x%x", m_CtrlSetup.wValue);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " wIndex: 0x%x", m_CtrlSetup.wIndex);
+ 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);
+
+ ExecuteHCICommandMessage(m_CtrlSetup);
+ // Replies are generated inside
}
break;
@@ -163,29 +158,39 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
u8 Command = Memory::Read_U8(CommandBuffer.InBuffer[0].m_Address);
switch (Command)
{
- case ACL_DATA_ENDPOINT_READ:
+ case ACL_DATA_BLK_OUT:
{
- // write
+ // This is the ACL datapath from CPU to Wiimote
+ // Here we only need to record the command address in case we need to delay the reply
+ m_CtrlSetup.m_Address = CommandBuffer.m_Address;
+
+ #if defined(_DEBUG) || defined(DEBUGFAST)
DumpAsync(CommandBuffer.BufferVector, _CommandAddress, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer);
+ #endif
- SIOCtlVBuffer pBulkBuffer(_CommandAddress);
- UACLHeader* pACLHeader = (UACLHeader*)Memory::GetPointer(pBulkBuffer.PayloadBuffer[0].m_Address);
+ CtrlBuffer BulkBuffer(_CommandAddress);
+ UACLHeader* pACLHeader = (UACLHeader*)Memory::GetPointer(BulkBuffer.m_buffer);
_dbg_assert_(WII_IPC_WIIMOTE, pACLHeader->BCFlag == 0);
_dbg_assert_(WII_IPC_WIIMOTE, pACLHeader->PBFlag == 2);
- SendToDevice(pACLHeader->ConnectionHandle, Memory::GetPointer(pBulkBuffer.PayloadBuffer[0].m_Address + 4), pACLHeader->Size);
+ SendToDevice(pACLHeader->ConnectionHandle, Memory::GetPointer(BulkBuffer.m_buffer + 4), pACLHeader->Size);
+ m_PacketCount++;
+
+ // If ACLFrame is not used, we can send a reply immediately
+ // or else we have to delay this reply
+ if (m_ACLFrame.m_number == 0)
+ _SendReply = true;
}
break;
case ACL_DATA_ENDPOINT:
{
- if (m_pACLBuffer)
- delete m_pACLBuffer;
- m_pACLBuffer = new SIOCtlVBuffer(_CommandAddress);
+ CtrlBuffer _TempCtrlBuffer(_CommandAddress);
+ m_ACLBuffer = _TempCtrlBuffer;
+ // Reply should not be sent here but when this buffer is filled
INFO_LOG(WII_IPC_WIIMOTE, "ACL_DATA_ENDPOINT: 0x%08x ", _CommandAddress);
- return false;
}
break;
@@ -206,14 +211,11 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
{
case HCI_EVENT_ENDPOINT:
{
- if (m_pHCIBuffer)
- {
- ERROR_LOG(WII_IPC_WIIMOTE, "Kill current hci buffer... there could be a comand inside");
- PanicAlert("Kill current hci buffer... there could be a comand inside");
- delete m_pHCIBuffer;
- }
- m_pHCIBuffer = new SIOCtlVBuffer(_CommandAddress);
- return false;
+ CtrlBuffer _TempCtrlBuffer(_CommandAddress);
+ m_HCIBuffer = _TempCtrlBuffer;
+ // Reply should not be sent here but when this buffer is filled
+
+ INFO_LOG(WII_IPC_WIIMOTE, "HCI_EVENT_ENDPOINT: 0x%08x ", _CommandAddress);
}
break;
@@ -230,21 +232,23 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::IOCtlV(u32 _CommandAddress)
{
_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown CWII_IPC_HLE_Device_usb_oh1_57e_305: %x", CommandBuffer.Parameter);
- INFO_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str());
+ DEBUG_LOG(WII_IPC_WIIMOTE, "%s - IOCtlV:", GetDeviceName().c_str());
DEBUG_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter);
DEBUG_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
DEBUG_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
DEBUG_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector);
- DEBUG_LOG(WII_IPC_WIIMOTE, " BufferSize: 0x%08x", CommandBuffer.BufferSize);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size);
+ #if defined(_DEBUG) || defined(DEBUGFAST)
DumpAsync(CommandBuffer.BufferVector, _CommandAddress, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer);
+ #endif
}
break;
}
// write return value
Memory::Write_U32(0, _CommandAddress + 0x4);
-
- return true;
+ return (_SendReply);
}
// ================
@@ -264,208 +268,276 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendToDevice(u16 _ConnectionHandle, u8
return;
}
- pWiiMote->SendACLFrame(_pData, _Size);
+ pWiiMote->ExecuteL2capCmd(_pData, _Size);
}
-// ================
+// ================
// ===================================================
-/* Here we queue the ACL frames we receive from the Wiimote plugin. They will consist of
- header + data. The header is for example 07 00 41 00 which means size 0x0007 and
- channel 0x0041. */
-// ----------------
-void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8* _pData, u32 _Size)
-{
- INFO_LOG(WII_IPC_WIIMOTE, "Queuing ACL frame.");
-
- // Queue the packet
- ACLFrame frame;
- frame.ConnectionHandle = _ConnectionHandle;
- frame.data = new u8[_Size];
- memcpy(frame.data, _pData, _Size);
- frame.size = _Size;
- m_AclFrameQue.push(frame);
-
- /* Debugging
- std::string Temp;
- for (u32 j = 0; j < _Size; j++)
- {
- char Buffer[128];
- sprintf(Buffer, "%02x ", frame.data[j]);
- Temp.append(Buffer);
- }
- LOGV(WII_IPC_WIIMOTE, 1, " Size: 0x%08x", _Size);
- LOGV(WII_IPC_WIIMOTE, 1, " Data: %s", Temp.c_str()); */
-
- g_HCICount++;
-}
+// Here we send ACL pakcets to CPU. They will consist of header + data.
+// The header is for example 07 00 41 00 which means size 0x0007 and channel 0x0041.
+// ---------------------------------------------------
-// ===================================================
-/* See IPC_HLE_PERIOD in SystemTimers.cpp for a documentation of this update. */
-// ----------------
-u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
+// 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
+//
+void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size)
{
- if (!m_EventQueue.empty() && m_pHCIBuffer)
+ if(m_ACLBuffer.m_address != NULL)
{
- SIOCtlVBuffer* pHCIBuffer = m_pHCIBuffer;
- m_pHCIBuffer = NULL;
+ INFO_LOG(WII_IPC_WIIMOTE, "Sending ACL Packet: 0x%08x ....", m_ACLBuffer.m_address);
- // copy the event to memory
- const SQueuedEvent& rEvent = m_EventQueue.front();
- u8* pHCIEvent = Memory::GetPointer(pHCIBuffer->PayloadBuffer[0].m_Address);
- memcpy(pHCIEvent, rEvent.m_buffer, rEvent.m_size);
+ UACLHeader* pHeader = (UACLHeader*)Memory::GetPointer(m_ACLBuffer.m_buffer);
+ pHeader->ConnectionHandle = _ConnectionHandle;
+ pHeader->BCFlag = 0;
+ pHeader->PBFlag = 2;
+ pHeader->Size = _Size;
- // return reply buffer size
- Memory::Write_U32((u32)rEvent.m_size, pHCIBuffer->m_Address + 0x4);
+ // Write the packet to the buffer
+ memcpy((u8*)pHeader + sizeof(UACLHeader), _pData, _Size);
- if (rEvent.m_connectionHandle > 0)
- {
- g_HCICount++;
- }
+ // Write the packet size as return value
+ Memory::Write_U32(sizeof(UACLHeader) + _Size, m_ACLBuffer.m_address + 0x4);
- m_EventQueue.pop();
+ // Send a reply to indicate ACL buffer is sent
+ WII_IPCInterface::EnqReply(m_ACLBuffer.m_address);
- u32 Addr = pHCIBuffer->m_Address;
- delete pHCIBuffer;
-
- return Addr;
+ // Invalidate ACL buffer
+ m_ACLBuffer.m_address = NULL;
+ m_ACLBuffer.m_buffer = NULL;
+ m_ACLFrame.m_number = 0;
}
-
- // check if we can fill the aclbuffer
- if(!m_AclFrameQue.empty() && m_pACLBuffer)
+ else
{
- ACLFrame& frame = m_AclFrameQue.front();
-
- INFO_LOG(WII_IPC_WIIMOTE, "Sending ACL frame.");
- UACLHeader* pHeader = (UACLHeader*)Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address);
- pHeader->ConnectionHandle = frame.ConnectionHandle;
+ // 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
+ pHeader->ConnectionHandle = _ConnectionHandle;
pHeader->BCFlag = 0;
pHeader->PBFlag = 2;
- pHeader->Size = frame.size;
-
- // Write the frame to the PayloadBuffer
- memcpy(Memory::GetPointer(m_pACLBuffer->PayloadBuffer[0].m_Address + sizeof(UACLHeader)),
- frame.data, frame.size);
-
- // return reply buffer size
- Memory::Write_U32(sizeof(UACLHeader) + frame.size, m_pACLBuffer->m_Address + 0x4);
-
- delete [] frame.data;
- m_AclFrameQue.pop();
-
- u32 Addr = m_pACLBuffer->m_Address;
- delete m_pACLBuffer;
- m_pACLBuffer = NULL;
+ pHeader->Size = _Size;
+ memcpy((u8*)pHeader + sizeof(UACLHeader), _pData, _Size);
+ m_ACLFrame.m_number++;
- /* Debugging
- std::string Temp;
- for (u32 j = 0; j < frame.size; j++)
+ if (m_ACLFrame.m_number > 16)
{
- char Buffer[128];
- sprintf(Buffer, "%02x ", frame.data[j]);
- Temp.append(Buffer);
+ 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!");
}
- LOGV(WII_IPC_WIIMOTE, 1, " Size: 0x%08x", frame.size);
- LOGV(WII_IPC_WIIMOTE, 1, " Size of UACLHeader: 0x%08x", sizeof(UACLHeader));
- LOGV(WII_IPC_WIIMOTE, 1, " Data: %s", Temp.c_str()); */
-
- return Addr;
}
+}
- if ((g_GlobalHandle != 0) && (g_HCICount > 0))
- {
- SendEventNumberOfCompletedPackets(g_GlobalHandle, g_HCICount*2);
- g_HCICount = 0;
- }
+// AyuanX: this ugly function is only useful when there are
+// multiple L2CAP packets come from WiiMote_Plugin in one cycle
+//
+void CWII_IPC_HLE_Device_usb_oh1_57e_305::PurgeACLFrame()
+{
+ if(m_ACLBuffer.m_address == NULL)
+ return;
- if (m_AclFrameQue.empty())
- {
- for (size_t i = 0; i < m_WiiMotes.size(); i++)
+ INFO_LOG(WII_IPC_WIIMOTE, "Purging ACL Frame: 0x%08x ....", m_ACLBuffer.m_address);
+
+ if(m_ACLFrame.m_number > 0)
{
- if (m_WiiMotes[i].Update())
- break;
+ m_ACLFrame.m_number--;
+ // Fill the buffer
+ u8* _Address = m_ACLFrame.m_data + m_ACLFrame.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);
+ // Send a reply to indicate ACL buffer is sent
+ WII_IPCInterface::EnqReply(m_ACLBuffer.m_address);
+ // Invalidate ACL buffer
+ m_ACLBuffer.m_address = NULL;
+ m_ACLBuffer.m_buffer = NULL;
}
+}
+
+// ===================================================
+/* See IPC_HLE_PERIOD in SystemTimers.cpp for a documentation of this update. */
+// ----------------
+u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
+{
+ // Check if last command needs more work
+ if (m_HCIBuffer.m_address && m_LastCmd)
+ {
+ ExecuteHCICommandMessage(m_CtrlSetup);
+ return true;
}
- if (m_AclFrameQue.empty())
+ // Check if temp ACL frame is not purged
+ if (m_ACLFrame.m_number > 0)
{
- CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update();
+ PurgeACLFrame();
+ if (m_ACLFrame.m_number == 0)
+ WII_IPCInterface::EnqReply(m_CtrlSetup.m_Address);
+ return true;
}
// --------------------------------------------------------------------
/* We wait for ScanEnable to be sent from the game through HCI_CMD_WRITE_SCAN_ENABLE
- before we initiate the connection. To avoid doing this for GC games we also
- want m_LocalName from CommandWriteLocalName() to be "Wii".
+ before we initiate the connection.
FiRES: TODO find a good solution to do this
- JP: Solution to what? When to run SendEventRequestConnection()?
- */
- // -------------------------
-
- /* I disabled this and disable m_ScanEnable instead to avoid running SendEventRequestConnection()
- again. */
- //static bool test = true;
/* Why do we need this? 0 worked with the emulated wiimote in all games I tried. Do we have to
wait for wiiuse_init() and wiiuse_find() for a real Wiimote here? I'm testing
this new method of not waiting at all if there are no real Wiimotes. Please let me know
if it doesn't work. */
- static int counter = (Core::GetRealWiimote() ? 1000 : 0);
- if (!strcasecmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
+ // AyuanX: I don't know the Real Wiimote behavior, so I'll leave it here untouched
+ //
+ // Initiate ACL connection
+ static int counter = (Core::GetRealWiimote() ? 1000 : 0);
+ if (m_HCIBuffer.m_address && (m_ScanEnable & 0x2))
{
counter--;
if (counter < 0)
- {
- //test = false;
for (size_t i=0; i < m_WiiMotes.size(); i++)
- {
if (m_WiiMotes[i].EventPagingChanged(2))
{
Host_SetWiiMoteConnectionState(1);
+ // Create ACL connection
SendEventRequestConnection(m_WiiMotes[i]);
+ return true;
}
- }
+ }
+
+ // AyuanX: Actually we don't need to link channels so early
+ // We can wait until HCI command: CommandReadRemoteFeatures is finished
+ // Because at this moment, CPU is busy handling HCI commands
+ // and have no time to respond ACL requests shortly
+ // But ... whatever, either way works
+ //
+ // Link channels when connected
+ if (m_ACLBuffer.m_address)
+ {
+ for (size_t i = 0; i < m_WiiMotes.size(); i++)
+ {
+ if (m_WiiMotes[i].LinkChannel())
+ return true;
+ }
+ }
+
+ // 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
+ //
+ static u32 FreqDividerSync = 0;
+ if (m_HCIBuffer.m_address && !WII_IPCInterface::GetAddress() && m_WiiMotes[0].IsLinked())
+ {
+ FreqDividerSync++;
+ if ((m_PacketCount >0) || (FreqDividerSync > 15)) // Feel free to tweak it
+ {
+ FreqDividerSync = 0;
+ SendEventNumberOfCompletedPackets(m_WiiMotes[0].GetConnectionHandle(), m_PacketCount);
+ m_PacketCount = 0;
+ return true;
+ }
+ }
+
+ // AyuanX: If we let this Wiimote_Update function running freely
+ // it will exaust all the HLE time slots and block further CPU commands
+ // so we have to make sure CPU and other things get the privilege to bypass this
+ // Besides, decreasing its reporting frequency also brings us great FPS boost
+ // Now I am making it running at 1/100 frequency of IPC which is already fast enough for human input
+ //
+ static u32 FreqDividerMote = 0;
+ if (m_ACLBuffer.m_address && !WII_IPCInterface::GetAddress() && !m_LastCmd && m_WiiMotes[0].IsLinked())
+ {
+ FreqDividerMote++;
+ if(FreqDividerMote > 100) // Feel free to tweak it
+ {
+ FreqDividerMote = 0;
+ CPluginManager::GetInstance().GetWiimote(0)->Wiimote_Update();
+ return true;
}
}
- return 0;
+ return false;
}
// Events
// -----------------
-// This is messages send from the Wiimote to the game, for example RequestConnection()
+// Thess messages are sent from the Wiimote to the game, for example RequestConnection()
// or ConnectionComplete().
//
-
+// 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)
{
- m_EventQueue.push(_event);
+ if (m_HCIBuffer.m_address != NULL)
+ {
+ INFO_LOG(WII_IPC_WIIMOTE, "Sending HCI Packet to Address: 0x%08x ....", m_HCIBuffer.m_address);
+
+ memcpy(Memory::GetPointer(m_HCIBuffer.m_buffer), _event.m_buffer, _event.m_size);
+
+ // Calculate buffer size
+ Memory::Write_U32((u32)_event.m_size, m_HCIBuffer.m_address + 0x4);
+
+ // Send a reply to indicate HCI buffer is filled
+ WII_IPCInterface::EnqReply(m_HCIBuffer.m_address);
+
+ // Invalidate HCI buffer
+ m_HCIBuffer.m_address = NULL;
+ m_HCIBuffer.m_buffer = NULL;
+
+ return;
+ }
+ 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!");
+ }
}
+
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventCommandStatus(u16 _Opcode)
-{
- SQueuedEvent Event(sizeof(SHCIEventStatus), 0);
+{
+ // If we haven't sent this event or other events before, we will send it
+ // If we have, then skip it
+ if (m_LastCmd == NULL)
+ {
+ // Let's make a mark to show further events are scheduled
+ // besides this should also guarantee we won't send this event twice
+ // I think 65535 is big enough, so it won't trouble other events who also make use of g_LastCmd
+ m_LastCmd = 0xFFFF;
- SHCIEventStatus* pHCIEvent = (SHCIEventStatus*)Event.m_buffer;
- pHCIEvent->EventType = 0x0F;
- pHCIEvent->PayloadLength = sizeof(SHCIEventStatus) - 2;
- pHCIEvent->Status = 0x0;
- pHCIEvent->PacketIndicator = 0x01;
- pHCIEvent->Opcode = _Opcode;
+ SQueuedEvent Event(sizeof(SHCIEventStatus), 0);
- AddEventToQueue(Event);
+ SHCIEventStatus* pHCIEvent = (SHCIEventStatus*)Event.m_buffer;
+ pHCIEvent->EventType = 0x0F;
+ pHCIEvent->PayloadLength = sizeof(SHCIEventStatus) - 2;
+ pHCIEvent->Status = 0x0;
+ pHCIEvent->PacketIndicator = 0x01;
+ pHCIEvent->Opcode = _Opcode;
- INFO_LOG(WII_IPC_WIIMOTE, "Event: Command Status");
- INFO_LOG(WII_IPC_WIIMOTE, " Opcode: 0x%04x", pHCIEvent->Opcode);
+ INFO_LOG(WII_IPC_WIIMOTE, "Event: Command Status");
+ INFO_LOG(WII_IPC_WIIMOTE, " Opcode: 0x%04x", pHCIEvent->Opcode);
- return true;
+ AddEventToQueue(Event);
+
+ return true;
+ }
+ else
+ {
+ // If the mark matches, clear it
+ // if not, keep it untouched
+ if (m_LastCmd==0xFFFF)
+ m_LastCmd = NULL;
+
+ return false;
+ }
}
@@ -605,7 +677,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HL
pEventRequestConnection->uclass[0] = _rWiiMote.GetClass()[0];
pEventRequestConnection->uclass[1] = _rWiiMote.GetClass()[1];
pEventRequestConnection->uclass[2] = _rWiiMote.GetClass()[2];
- pEventRequestConnection->LinkType = 0x01;
+ pEventRequestConnection->LinkType = 0x01; // ACL
AddEventToQueue(Event);
@@ -619,6 +691,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HL
};
#endif
+ INFO_LOG(WII_IPC_WIIMOTE, "<<<<<<< Request ACL Connection >>>>>>>");
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventRequestConnection");
INFO_LOG(WII_IPC_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x",
pEventRequestConnection->bdaddr.b[0], pEventRequestConnection->bdaddr.b[1], pEventRequestConnection->bdaddr.b[2],
@@ -708,13 +781,8 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventConnectionComplete(bdaddr_t _
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(_bd);
if (pWiimote)
- {
pWiimote->EventConnectionAccepted();
- }
-
- g_GlobalHandle = pConnectionComplete->Connection_Handle;
-
#if MAX_LOGLEVEL >= DEBUG_LEVEL
static char s_szLinkType[][128] =
{
@@ -893,12 +961,12 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventNumberOfCompletedPackets(u16
pNumberOfCompletedPackets->Connection_Handle = _connectionHandle;
pNumberOfCompletedPackets->Number_Of_Completed_Packets = _count;
- AddEventToQueue(Event);
-
// Log
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventNumberOfCompletedPackets");
- INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle);
- INFO_LOG(WII_IPC_WIIMOTE, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pNumberOfCompletedPackets->Connection_Handle);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Number_Of_Completed_Packets: %i", pNumberOfCompletedPackets->Number_Of_Completed_Packets);
+
+ AddEventToQueue(Event);
return true;
}
@@ -921,12 +989,12 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventAuthenticationCompleted(u16 _
pEventAuthenticationCompleted->Status = 0;
pEventAuthenticationCompleted->Connection_Handle = _connectionHandle;
- AddEventToQueue(Event);
-
// Log
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventAuthenticationCompleted");
INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pEventAuthenticationCompleted->Connection_Handle);
+ AddEventToQueue(Event);
+
return true;
}
@@ -950,12 +1018,12 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventModeChange(u16 _connectionHan
pModeChange->CurrentMode = _mode;
pModeChange->Value = _value;
- AddEventToQueue(Event);
-
// Log
INFO_LOG(WII_IPC_WIIMOTE, "Event: SendEventModeChange");
- INFO_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pModeChange->Connection_Handle);
- INFO_LOG(WII_IPC_WIIMOTE, " missing other paramter :)");
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Connection_Handle: 0x%04x", pModeChange->Connection_Handle);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Current Mode: 0x%02x", pModeChange->CurrentMode = _mode);
+
+ AddEventToQueue(Event);
return true;
}
@@ -1003,9 +1071,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom
u16 ocf = HCI_OCF(pMsg->Opcode);
u16 ogf = HCI_OGF(pMsg->Opcode);
- INFO_LOG(WII_IPC_WIIMOTE, "******************************");
- INFO_LOG(WII_IPC_WIIMOTE, "ExecuteHCICommandMessage(0x%04x)(ocf: 0x%02x, ogf: 0x%02x)",
- pMsg->Opcode, ocf, ogf);
+
+ // Only show info if this is a new HCI command
+ // or else we are continuing to execute last command
+ if(m_LastCmd == NULL)
+ {
+ INFO_LOG(WII_IPC_WIIMOTE, "**************************************************");
+ INFO_LOG(WII_IPC_WIIMOTE, "ExecuteHCICommandMessage(0x%04x)(ocf: 0x%02x, ogf: 0x%02x)", pMsg->Opcode, ocf, ogf);
+ }
switch(pMsg->Opcode)
{
@@ -1073,7 +1146,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom
break;
case HCI_CMD_INQUIRY:
- CommandInquiry(pInput);
+ CommandInquiry(pInput);
break;
case HCI_CMD_WRITE_INQUIRY_SCAN_TYPE:
@@ -1154,14 +1227,13 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom
//
default:
{
- u16 _ocf = HCI_OCF(pMsg->Opcode);
- u16 _ogf = HCI_OGF(pMsg->Opcode);
-
- if (_ogf == 0x3f)
+ // send fake okay msg...
+ SendEventCommandComplete(pMsg->Opcode, NULL, 0);
+
+ if (ogf == 0x3f)
{
PanicAlert("Vendor specific HCI command");
- ERROR_LOG(WII_IPC_WIIMOTE, "Command: vendor specific: 0x%04X (ocf: 0x%x)", pMsg->Opcode, _ocf);
-
+ ERROR_LOG(WII_IPC_WIIMOTE, "Command: vendor specific: 0x%04X (ocf: 0x%x)", pMsg->Opcode, ocf);
for (int i=0; i<pMsg->len; i++)
{
ERROR_LOG(WII_IPC_WIIMOTE, " 0x02%x", pInput[i]);
@@ -1169,14 +1241,17 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::ExecuteHCICommandMessage(const SHCICom
}
else
{
- _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USB_IOCTL_CTRLMSG: 0x%04X (ocf: 0x%x ogf 0x%x)", pMsg->Opcode, _ocf, _ogf);
+ _dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USB_IOCTL_CTRLMSG: 0x%04X (ocf: 0x%x ogf 0x%x)", pMsg->Opcode, ocf, ogf);
}
-
- // send fake all is okay msg...
- SendEventCommandComplete(pMsg->Opcode, NULL, 0);
}
break;
}
+
+ if (m_LastCmd == NULL)
+ {
+ // HCI command finished, send a reply to command
+ WII_IPCInterface::EnqReply(_rHCICommandMessage.m_Address);
+ }
}
@@ -1201,10 +1276,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadBufferSize(u8* _Input)
// reply
hci_read_buffer_size_rp Reply;
Reply.status = 0x00;
- Reply.max_acl_size = 339;
- Reply.num_acl_pkts = 10;
+ Reply.max_acl_size = 0x0FFF; //339;
+ Reply.num_acl_pkts = 0xFF; //10;
Reply.max_sco_size = 64;
Reply.num_sco_pkts = 0;
+ // AyuanX: Are these parameters fixed or adjustable ???
INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_READ_BUFFER_SIZE:");
DEBUG_LOG(WII_IPC_WIIMOTE, "return:");
@@ -1297,6 +1373,20 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input)
PanicAlert("CommandReadStoredLinkKey");
}
+ // generate link key
+ // Let us have some fun :P
+ if(m_LastCmd<m_WiiMotes.size())
+ {
+ SendEventLinkKeyNotification(m_WiiMotes[m_LastCmd]);
+ m_LastCmd++;
+ return;
+ }
+ else
+ {
+ SendEventCommandComplete(HCI_CMD_READ_STORED_LINK_KEY, &Reply, sizeof(hci_read_stored_link_key_rp));
+ m_LastCmd = NULL;
+ }
+
// logging
INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_READ_STORED_LINK_KEY:");
DEBUG_LOG(WII_IPC_WIIMOTE, "input:");
@@ -1307,14 +1397,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadStoredLinkKey(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, "return:");
DEBUG_LOG(WII_IPC_WIIMOTE, " max_num_keys: %i", Reply.max_num_keys);
DEBUG_LOG(WII_IPC_WIIMOTE, " num_keys_read: %i", Reply.num_keys_read);
-
- // generate link key
- for (size_t i=0; i<m_WiiMotes.size(); i++)
- {
- SendEventLinkKeyNotification(m_WiiMotes[i]);
- }
-
- SendEventCommandComplete(HCI_CMD_READ_STORED_LINK_KEY, &Reply, sizeof(hci_read_stored_link_key_rp));
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteUnitClass(u8* _Input)
@@ -1386,6 +1468,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandHostBufferSize(u8* _Input)
Reply.status = 0x00;
INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_HOST_BUFFER_SIZE:");
+
DEBUG_LOG(WII_IPC_WIIMOTE, "write:");
DEBUG_LOG(WII_IPC_WIIMOTE, " max_acl_size: %i", pHostBufferSize->max_acl_size);
DEBUG_LOG(WII_IPC_WIIMOTE, " max_sco_size: %i", pHostBufferSize->max_sco_size);
@@ -1523,11 +1606,23 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSetEventFilter(u8* _Input)
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input)
{
- // command parameters
- hci_inquiry_cp* pInquiry = (hci_inquiry_cp*)_Input;
- u8 lap[HCI_LAP_SIZE];
+ if (SendEventCommandStatus(HCI_CMD_INQUIRY))
+ return;
+
+ if (m_LastCmd == NULL)
+ {
+ SendEventInquiryResponse();
+ // Now let's set up a mark
+ m_LastCmd = HCI_CMD_INQUIRY;
+ }
+ else
+ {
+ SendEventInquiryComplete();
+ // Clean up
+ m_LastCmd = NULL;
+ }
- memcpy(lap, pInquiry->lap, HCI_LAP_SIZE);
+ hci_inquiry_cp* pInquiry = (hci_inquiry_cp*)_Input;
INFO_LOG(WII_IPC_WIIMOTE, "Command: HCI_CMD_INQUIRY:");
DEBUG_LOG(WII_IPC_WIIMOTE, "write:");
@@ -1535,11 +1630,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiry(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " LAP[1]: 0x%02x", pInquiry->lap[1]);
DEBUG_LOG(WII_IPC_WIIMOTE, " LAP[2]: 0x%02x", pInquiry->lap[2]);
DEBUG_LOG(WII_IPC_WIIMOTE, " inquiry_length: %i (N x 1.28) sec", pInquiry->inquiry_length);
- DEBUG_LOG(WII_IPC_WIIMOTE, " num_responses: %i (N x 1.28) sec", pInquiry->num_responses);
-
- SendEventCommandStatus(HCI_CMD_INQUIRY);
- SendEventInquiryResponse();
- SendEventInquiryComplete();
+ DEBUG_LOG(WII_IPC_WIIMOTE, " num_responses: %i (N x 1.28) sec", pInquiry->num_responses);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryScanType(u8* _Input)
@@ -1606,6 +1697,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandInquiryCancel(u8* _Input)
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_REMOTE_NAME_REQ))
+ return;
+
// command parameters
hci_remote_name_req_cp* pRemoteNameReq = (hci_remote_name_req_cp*)_Input;
@@ -1618,12 +1712,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandRemoteNameReq(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " page_scan_mode: %i", pRemoteNameReq->page_scan_mode);
DEBUG_LOG(WII_IPC_WIIMOTE, " clock_offset: %i", pRemoteNameReq->clock_offset);
- SendEventCommandStatus(HCI_CMD_REMOTE_NAME_REQ);
SendEventRemoteNameReq(pRemoteNameReq->bdaddr);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_CREATE_CON))
+ return;
+
// command parameters
hci_create_con_cp* pCreateCon = (hci_create_con_cp*)_Input;
@@ -1639,15 +1735,32 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandCreateCon(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " clock_offset: %i", pCreateCon->clock_offset);
DEBUG_LOG(WII_IPC_WIIMOTE, " accept_role_switch: %i", pCreateCon->accept_role_switch);
- SendEventCommandStatus(HCI_CMD_CREATE_CON);
SendEventConnectionComplete(pCreateCon->bdaddr);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_ACCEPT_CON))
+ return;
+
// command parameters
hci_accept_con_cp* pAcceptCon = (hci_accept_con_cp*)_Input;
+ // this connection wants to be the master
+ if ((m_LastCmd == NULL)&&(pAcceptCon->role == 0))
+ {
+ SendEventRoleChange(pAcceptCon->bdaddr, true);
+ // Now let us set up a mark
+ m_LastCmd = HCI_CMD_ACCEPT_CON;
+ return;
+ }
+ else
+ {
+ SendEventConnectionComplete(pAcceptCon->bdaddr);
+ // Clean up
+ m_LastCmd = NULL;
+ }
+
#if MAX_LOGLEVEL >= DEBUG_LEVEL
static char s_szRole[][128] =
{
@@ -1662,20 +1775,13 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAcceptCon(u8* _Input)
pAcceptCon->bdaddr.b[0], pAcceptCon->bdaddr.b[1], pAcceptCon->bdaddr.b[2],
pAcceptCon->bdaddr.b[3], pAcceptCon->bdaddr.b[4], pAcceptCon->bdaddr.b[5]);
DEBUG_LOG(WII_IPC_WIIMOTE, " role: %s", s_szRole[pAcceptCon->role]);
-
- SendEventCommandStatus(HCI_CMD_ACCEPT_CON);
-
- // this connection wants to be the master
- if (pAcceptCon->role == 0)
- {
- SendEventRoleChange(pAcceptCon->bdaddr, true);
- }
-
- SendEventConnectionComplete(pAcceptCon->bdaddr);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadClockOffset(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_READ_CLOCK_OFFSET))
+ return;
+
// command parameters
hci_read_clock_offset_cp* pReadClockOffset = (hci_read_clock_offset_cp*)_Input;
@@ -1683,16 +1789,17 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadClockOffset(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, "Input:");
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%02x", pReadClockOffset->con_handle);
- SendEventCommandStatus(HCI_CMD_READ_CLOCK_OFFSET);
SendEventReadClockOffsetComplete(pReadClockOffset->con_handle);
-
// CWII_IPC_HLE_WiiMote* pWiiMote = AccessWiiMote(pReadClockOffset->con_handle);
// SendEventRequestLinkKey(pWiiMote->GetBD());
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteVerInfo(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_READ_REMOTE_VER_INFO))
+ return;
+
// command parameters
hci_read_remote_ver_info_cp* pReadRemoteVerInfo = (hci_read_remote_ver_info_cp*)_Input;
@@ -1700,12 +1807,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteVerInfo(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, "Input:");
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%02x", pReadRemoteVerInfo->con_handle);
- SendEventCommandStatus(HCI_CMD_READ_REMOTE_VER_INFO);
SendEventReadRemoteVerInfo(pReadRemoteVerInfo->con_handle);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteFeatures(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_READ_REMOTE_FEATURES))
+ return;
+
// command parameters
hci_read_remote_features_cp* pReadRemoteFeatures = (hci_read_remote_features_cp*)_Input;
@@ -1713,12 +1822,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandReadRemoteFeatures(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, "Input:");
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pReadRemoteFeatures->con_handle);
- SendEventCommandStatus(HCI_CMD_READ_REMOTE_FEATURES);
SendEventReadRemoteFeatures(pReadRemoteFeatures->con_handle);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_WRITE_LINK_POLICY_SETTINGS))
+ return;
+
// command parameters
hci_write_link_policy_settings_cp* pLinkPolicy = (hci_write_link_policy_settings_cp*)_Input;
@@ -1727,8 +1838,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pLinkPolicy->con_handle);
DEBUG_LOG(WII_IPC_WIIMOTE, " Policy: 0x%04x", pLinkPolicy->settings);
- SendEventCommandStatus(HCI_CMD_WRITE_LINK_POLICY_SETTINGS);
-
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pLinkPolicy->con_handle);
if (pWiimote)
{
@@ -1738,6 +1847,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteLinkPolicy(u8* _Input)
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAuthenticationRequested(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_AUTH_REQ))
+ return;
+
// command parameters
hci_auth_req_cp* pAuthReq = (hci_auth_req_cp*)_Input;
@@ -1745,12 +1857,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandAuthenticationRequested(u8* _In
DEBUG_LOG(WII_IPC_WIIMOTE, "Input:");
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pAuthReq->con_handle);
- SendEventCommandStatus(HCI_CMD_AUTH_REQ);
SendEventAuthenticationCompleted(pAuthReq->con_handle);
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSniffMode(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_SNIFF_MODE))
+ return;
+
// command parameters
hci_sniff_mode_cp* pSniffMode = (hci_sniff_mode_cp*)_Input;
@@ -1762,12 +1876,14 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandSniffMode(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " attempt: 0x%04x", pSniffMode->attempt);
DEBUG_LOG(WII_IPC_WIIMOTE, " timeout: 0x%04x", pSniffMode->timeout);
- SendEventCommandStatus(HCI_CMD_SNIFF_MODE);
SendEventModeChange(pSniffMode->con_handle, 0x02, pSniffMode->max_interval); // 0x02 - sniff mode
}
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
{
+ if(SendEventCommandStatus(HCI_CMD_DISCONNECT))
+ return;
+
// command parameters
hci_discon_cp* pDiscon = (hci_discon_cp*)_Input;
@@ -1776,14 +1892,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandDisconnect(u8* _Input)
DEBUG_LOG(WII_IPC_WIIMOTE, " ConnectionHandle: 0x%04x", pDiscon->con_handle);
DEBUG_LOG(WII_IPC_WIIMOTE, " Reason: 0x%02x", pDiscon->reason);
- SendEventCommandStatus(HCI_CMD_DISCONNECT);
SendEventDisconnect(pDiscon->con_handle, pDiscon->reason);
+// AyuanX : Disconnecting WiiMote is a bad idea because we don't support reconnect yet
+// so let's don't do it
+/*
CWII_IPC_HLE_WiiMote* pWiimote = AccessWiiMote(pDiscon->con_handle);
if (pWiimote)
- {
pWiimote->EventDisconnect();
- }
+*/
static bool OneShotMessage = true;
if (OneShotMessage)
@@ -1977,3 +2094,4 @@ bool CWII_IPC_HLE_Device_usb_oh0::IOCtlV(u32 _CommandAddress)
Memory::Write_U32(0, _CommandAddress + 0x4);
return 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 e98ec47e9e..1787f0f890 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
@@ -18,11 +18,11 @@
#ifndef _WII_IPC_HLE_DEVICE_USB_H_
#define _WII_IPC_HLE_DEVICE_USB_H_
-#include "WII_IPC_HLE_Device.h"
#include "hci.h"
#include <vector>
#include <queue>
-
+#include "WII_IPC_HLE.h"
+#include "WII_IPC_HLE_Device.h"
#include "WII_IPC_HLE_WiiMote.h"
@@ -38,13 +38,6 @@ union UACLHeader
u32 Hex;
};
-struct ACLFrame
-{
- u16 ConnectionHandle;
- u8* data;
- u32 size;
-};
-
struct SQueuedEvent
{
u8 m_buffer[1024];
@@ -58,7 +51,7 @@ struct SQueuedEvent
if (m_size > 1024)
{
// i know this code sux...
- PanicAlert("SQueuedEvent: allocate a to big buffer!!");
+ PanicAlert("SQueuedEvent: allocate too big buffer!!");
}
}
};
@@ -79,7 +72,8 @@ public:
virtual u32 Update();
- void SendACLFrame(u16 _ConnectionHandle, u8* _pData, u32 _Size);
+ void SendACLPacket(u16 _ConnectionHandle, u8* _pData, u32 _Size);
+ void PurgeACLFrame();
//hack for wiimote plugin
@@ -89,6 +83,8 @@ public:
CWII_IPC_HLE_WiiMote* AccessWiiMote(const bdaddr_t& _rAddr);
CWII_IPC_HLE_WiiMote* AccessWiiMote(u16 _ConnectionHandle);
+ void DoState(PointerWrap &p);
+
private:
enum
@@ -106,7 +102,7 @@ private:
enum
{
HCI_EVENT_ENDPOINT = 0x81,
- ACL_DATA_ENDPOINT_READ = 0x02,
+ ACL_DATA_BLK_OUT = 0x02,
ACL_DATA_ENDPOINT = 0x82,
};
@@ -121,6 +117,39 @@ private:
u32 m_PayLoadAddr;
u32 m_PayLoadSize;
+ u32 m_Address;
+ };
+
+ struct ACLFrame
+ {
+ u32 m_number;
+ u8 m_data[1024];
+
+ ACLFrame(int num)
+ : m_number(num)
+ {
+ }
+ };
+
+ struct CtrlBuffer
+ {
+ u32 m_address;
+ u32 m_buffer;
+
+ CtrlBuffer(u32 _Address)
+ : m_address(_Address)
+ {
+ if(_Address == NULL)
+ {
+ m_buffer = NULL;
+ }
+ else
+ {
+ u32 _BufferVector = Memory::Read_U32(_Address + 0x18);
+ u32 _InBufferNum = Memory::Read_U32(_Address + 0x10);
+ m_buffer = Memory::Read_U32(_BufferVector + _InBufferNum * 8);
+ }
+ }
};
bdaddr_t m_ControllerBD;
@@ -138,13 +167,14 @@ private:
u16 m_HostNumSCOPackets;
typedef std::queue<SQueuedEvent> CEventQueue;
- typedef std::queue<ACLFrame> CACLFrameQueue;
-
- CEventQueue m_EventQueue;
- CACLFrameQueue m_AclFrameQue;
- SIOCtlVBuffer* m_pACLBuffer;
- SIOCtlVBuffer* m_pHCIBuffer;
+ // STATE_TO_SAVE
+ SHCICommandMessage m_CtrlSetup;
+ CtrlBuffer m_HCIBuffer;
+ CtrlBuffer m_ACLBuffer;
+ ACLFrame m_ACLFrame;
+ u32 m_LastCmd;
+ int m_PacketCount;
// Events
void AddEventToQueue(const SQueuedEvent& _event);
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 8cb55a5175..cfc119c5dc 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
@@ -33,6 +33,7 @@ static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb;
CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305* _pHost, int _Number)
: m_Connected(false)
+ , m_Linked(false)
, m_HIDControlChannel_Connected(false)
, m_HIDControlChannel_ConnectedWait(false)
, m_HIDControlChannel_Config(false)
@@ -47,7 +48,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
{
s_Usb = _pHost;
- INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %i constructed", _Number);
+ INFO_LOG(WII_IPC_WIIMOTE, "Wiimote #%i constructed", _Number);
m_BD.b[0] = 0x11;
m_BD.b[1] = 0x02;
@@ -89,25 +90,24 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
//
//
-
-bool CWII_IPC_HLE_WiiMote::Update()
+bool CWII_IPC_HLE_WiiMote::LinkChannel()
{
- if (m_Connected == false)
+ if ((m_Connected == false) || (m_Linked == true))
return false;
- // try to connect HIDP_CONTROL_CHANNEL
+ // try to connect HID_CONTROL_CHANNEL
if (!m_HIDControlChannel_Connected)
{
if (m_HIDControlChannel_ConnectedWait)
return false;
m_HIDControlChannel_ConnectedWait = true;
- SendConnectionRequest(0x0040, HIDP_CONTROL_CHANNEL);
-
+ // The CID is fixed, other CID will be rejected
+ SendConnectionRequest(0x0040, HID_CONTROL_CHANNEL);
return true;
}
- // try to config HIDP_CONTROL_CHANNEL
+ // try to config HID_CONTROL_CHANNEL
if (!m_HIDControlChannel_Config)
{
if (m_HIDControlChannel_ConfigWait)
@@ -127,6 +127,7 @@ bool CWII_IPC_HLE_WiiMote::Update()
return false;
m_HIDInterruptChannel_ConnectedWait = true;
+ // The CID is fixed, other CID will be rejected
SendConnectionRequest(0x0041, HID_INTERRUPT_CHANNEL);
return true;
}
@@ -144,11 +145,75 @@ bool CWII_IPC_HLE_WiiMote::Update()
return true;
}
+ m_Linked = true;
UpdateStatus();
return false;
}
+// ===================================================
+/* Send a status report to the status bar. */
+// ----------------
+void CWII_IPC_HLE_WiiMote::ShowStatus(const void* _pData)
+{
+ // Check if it's enabled
+ SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter;
+ bool LedsOn = StartUp.bWiiLeds;
+ bool SpeakersOn = StartUp.bWiiSpeakers;
+
+ const u8* data = (const u8*)_pData;
+
+ // Get the last four bits with LED info
+ if (LedsOn)
+ {
+ if (data[1] == 0x11)
+ {
+ int led_bits = (data[2] >> 4);
+ Host_UpdateLeds(led_bits);
+ }
+ }
+
+ int speaker_bits = 0;
+
+ if (SpeakersOn)
+ {
+ u8 Bits = 0;
+ switch (data[1])
+ {
+ case 0x14: // Enable and disable speakers
+ if (data[2] == 0x02) // Off
+ Bits = 0;
+ else if (data[2] == 0x06) // On
+ Bits = 1;
+ Host_UpdateSpeakerStatus(0, Bits);
+ break;
+
+ case 0x19: // Mute and unmute
+ // Get the value
+ if (data[2] == 0x02) // Unmute
+ Bits = 1;
+ else if (data[2] == 0x06) // Mute
+ Bits = 0;
+ Host_UpdateSpeakerStatus(1, Bits);
+ break;
+ // Write to speaker registry, or write sound
+ case 0x16:
+ case 0x18:
+ // Turn on the activity light
+ Host_UpdateSpeakerStatus(2, 1);
+ break;
+ }
+ }
+}
+
+// Turn off the activity icon again
+void CWII_IPC_HLE_WiiMote::UpdateStatus()
+{
+ // Check if it's enabled
+ if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiSpeakers)
+ return;
+ Host_UpdateStatus();
+}
//
//
@@ -165,11 +230,13 @@ bool CWII_IPC_HLE_WiiMote::Update()
void CWII_IPC_HLE_WiiMote::EventConnectionAccepted()
{
m_Connected = true;
+ m_Linked = false;
}
void CWII_IPC_HLE_WiiMote::EventDisconnect()
{
m_Connected = false;
+ m_Linked = false;
}
bool CWII_IPC_HLE_WiiMote::EventPagingChanged(u8 _pageMode)
@@ -210,22 +277,20 @@ void CWII_IPC_HLE_WiiMote::EventCommandWriteLinkPolicy()
//
-
// ===================================================
-/* This function send ACL frams from the Wii to Wiimote_ControlChannel() in the Wiimote.
- It's called from SendToDevice() in WII_IPC_HLE_Device_usb.cpp. */
-// ----------------
-void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size)
+// This function receives L2CAP commands from the CPU
+// It's called from SendToDevice() in WII_IPC_HLE_Device_usb.cpp.
+// ---------------------------------------------------
+void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
{
- // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, _pData, _Size, "SendACLFrame: ");
+ // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, _pData, _Size, "SendACLPacket: ");
// parse the command
SL2CAP_Header* pHeader = (SL2CAP_Header*)_pData;
u8* pData = _pData + sizeof(SL2CAP_Header);
u32 DataSize = _Size - sizeof(SL2CAP_Header);
-
- INFO_LOG(WII_IPC_WIIMOTE, "L2Cap-SendFrame: Channel 0x%04x, Len 0x%x, DataSize 0x%x",
- pHeader->CID, pHeader->Length, DataSize);
+ INFO_LOG(WII_IPC_WIIMOTE, "++++++++++++++++++++++++++++++++++++++");
+ INFO_LOG(WII_IPC_WIIMOTE, "Execute L2CAP Command: Cid 0x%04x, Len 0x%x, DataSize 0x%x", pHeader->CID, pHeader->Length, DataSize);
if(pHeader->Length != DataSize)
{
@@ -241,8 +306,9 @@ void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size)
default:
{
- _dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->CID), "SendACLFrame to unknown channel %i", pHeader->CID);
+ _dbg_assert_msg_(WII_IPC_WIIMOTE, DoesChannelExist(pHeader->CID), "L2CAP: SendACLPacket to unknown channel %i", pHeader->CID);
CChannelMap::iterator itr= m_Channel.find(pHeader->CID);
+
Common::PluginWiimote* mote = CPluginManager::GetInstance().GetWiimote(0);
if (itr != m_Channel.end())
{
@@ -253,13 +319,15 @@ void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size)
HandleSDP(pHeader->CID, pData, DataSize);
break;
- case HIDP_CONTROL_CHANNEL:
+ case HID_CONTROL_CHANNEL:
mote->Wiimote_ControlChannel(rChannel.DCID, pData, DataSize);
+ // Call Wiimote Plugin
break;
case HID_INTERRUPT_CHANNEL:
ShowStatus(pData);
mote->Wiimote_InterruptChannel(rChannel.DCID, pData, DataSize);
+ // Call Wiimote Plugin
break;
default:
@@ -272,72 +340,6 @@ void CWII_IPC_HLE_WiiMote::SendACLFrame(u8* _pData, u32 _Size)
break;
}
}
-
-
-// ===================================================
-/* Send a status report to the status bar. */
-// ----------------
-void CWII_IPC_HLE_WiiMote::ShowStatus(const void* _pData)
-{
- // Check if it's enabled
- SCoreStartupParameter& StartUp = SConfig::GetInstance().m_LocalCoreStartupParameter;
- bool LedsOn = StartUp.bWiiLeds;
- bool SpeakersOn = StartUp.bWiiSpeakers;
-
- const u8* data = (const u8*)_pData;
-
- // Get the last four bits with LED info
- if (LedsOn)
- {
- if (data[1] == 0x11)
- {
- int led_bits = (data[2] >> 4);
- Host_UpdateLeds(led_bits);
- }
- }
-
- int speaker_bits = 0;
-
- if (SpeakersOn)
- {
- u8 Bits = 0;
- switch (data[1])
- {
- case 0x14: // Enable and disable speakers
- if (data[2] == 0x02) // Off
- Bits = 0;
- else if (data[2] == 0x06) // On
- Bits = 1;
- Host_UpdateSpeakerStatus(0, Bits);
- break;
-
- case 0x19: // Mute and unmute
- // Get the value
- if (data[2] == 0x02) // Unmute
- Bits = 1;
- else if (data[2] == 0x06) // Mute
- Bits = 0;
- Host_UpdateSpeakerStatus(1, Bits);
- break;
- // Write to speaker registry, or write sound
- case 0x16:
- case 0x18:
- // Turn on the activity light
- Host_UpdateSpeakerStatus(2, 1);
- break;
- }
- }
-}
-
-// Turn off the activity icon again
-void CWII_IPC_HLE_WiiMote::UpdateStatus()
-{
- // Check if it's enabled
- if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bWiiSpeakers)
- return;
- Host_UpdateStatus();
-}
-
// ================
void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size)
@@ -350,34 +352,34 @@ void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size)
switch(pCommand->code)
{
- case L2CAP_CONN_REQ:
- CommandConnectionReq(pCommand->ident, _pData, pCommand->len);
+ case L2CAP_COMMAND_REJ:
+ ERROR_LOG(WII_IPC_WIIMOTE, "SignalChannel - L2CAP_COMMAND_REJ (something went wrong)."
+ "Try to replace your SYSCONF file with a new copy."
+ ,pCommand->code);
+ PanicAlert(
+ "SignalChannel - L2CAP_COMMAND_REJ (something went wrong)."
+ "Try to replace your SYSCONF file with a new copy."
+ ,pCommand->code);
break;
- case L2CAP_CONF_REQ:
- CommandCofigurationReq(pCommand->ident, _pData, pCommand->len);
+ case L2CAP_CONN_REQ:
+ ReceiveConnectionReq(pCommand->ident, _pData, pCommand->len);
break;
case L2CAP_CONN_RSP:
- CommandConnectionResponse(pCommand->ident, _pData, pCommand->len);
+ ReceiveConnectionResponse(pCommand->ident, _pData, pCommand->len);
break;
- case L2CAP_DISCONN_REQ:
- CommandDisconnectionReq(pCommand->ident, _pData, pCommand->len);
+ case L2CAP_CONF_REQ:
+ ReceiveConfigurationReq(pCommand->ident, _pData, pCommand->len);
break;
case L2CAP_CONF_RSP:
- CommandConfigurationResponse(pCommand->ident, _pData, pCommand->len);
+ ReceiveConfigurationResponse(pCommand->ident, _pData, pCommand->len);
break;
- case L2CAP_COMMAND_REJ:
- ERROR_LOG(WII_IPC_WIIMOTE, "SignalChannel - L2CAP_COMMAND_REJ (something went wrong). Try to replace your"
- "SYSCONF file with a new copy."
- ,pCommand->code);
- PanicAlert(
- "SignalChannel - L2CAP_COMMAND_REJ (something went wrong). Try to replace your"
- "SYSCONF file with a new copy."
- ,pCommand->code);
+ case L2CAP_DISCONN_REQ:
+ ReceiveDisconnectionReq(pCommand->ident, _pData, pCommand->len);
break;
default:
@@ -390,21 +392,18 @@ void CWII_IPC_HLE_WiiMote::SignalChannel(u8* _pData, u32 _Size)
}
}
-
//
//
//
//
-// --- Send Commands To Device
+// --- Receive Commands from CPU
//
//
//
//
//
-
-
-void CWII_IPC_HLE_WiiMote::CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size)
+void CWII_IPC_HLE_WiiMote::ReceiveConnectionReq(u8 _Ident, u8* _pData, u32 _Size)
{
SL2CAP_CommandConnectionReq* pCommandConnectionReq = (SL2CAP_CommandConnectionReq*)_pData;
@@ -414,7 +413,7 @@ void CWII_IPC_HLE_WiiMote::CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size
rChannel.SCID = pCommandConnectionReq->scid;
rChannel.DCID = pCommandConnectionReq->scid;
- INFO_LOG(WII_IPC_WIIMOTE, " CommandConnectionReq");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] ReceiveConnectionRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
DEBUG_LOG(WII_IPC_WIIMOTE, " PSM: 0x%04x", rChannel.PSM);
DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rChannel.SCID);
@@ -427,31 +426,58 @@ void CWII_IPC_HLE_WiiMote::CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size
Rsp.result = 0x00;
Rsp.status = 0x00;
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendConnectionResponse");
SendCommandToACL(_Ident, L2CAP_CONN_RSP, sizeof(SL2CAP_ConnectionResponse), (u8*)&Rsp);
+}
- // update state machine
- if (rChannel.PSM == HIDP_CONTROL_CHANNEL)
+void CWII_IPC_HLE_WiiMote::ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32 _Size)
+{
+ l2cap_conn_rsp* rsp = (l2cap_conn_rsp*)_pData;
+
+ _dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_conn_rsp));
+
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] ReceiveConnectionResponse");
+ DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rsp->dcid);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rsp->scid);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Status: 0x%04x", rsp->status);
+
+ _dbg_assert_(WII_IPC_WIIMOTE, rsp->result == 0);
+ _dbg_assert_(WII_IPC_WIIMOTE, rsp->status == 0);
+ _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid));
+
+ SChannel& rChannel = m_Channel[rsp->scid];
+ rChannel.DCID = rsp->dcid;
+
+ //
+ // AyuanX: I'm commenting this out because CPU thinks he is faster than WiiMote
+ // and basically CPU will take the initiative to config channel
+ // in any case we don't want to race against CPU, or we are doomed
+ // so we wait for CPU to request first
+ //
+ /*
+ if (rChannel.PSM == HID_CONTROL_CHANNEL)
m_HIDControlChannel_Connected = true;
if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
m_HIDInterruptChannel_Connected = true;
+ */
}
-void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Size)
+void CWII_IPC_HLE_WiiMote::ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size)
{
- INFO_LOG(WII_IPC_WIIMOTE, "*******************************************************");
u32 Offset = 0;
SL2CAP_CommandConfigurationReq* pCommandConfigReq = (SL2CAP_CommandConfigurationReq*)_pData;
_dbg_assert_(WII_IPC_WIIMOTE, pCommandConfigReq->flags == 0x00); // 1 means that the options are send in multi-packets
-
_dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(pCommandConfigReq->dcid));
+
SChannel& rChannel = m_Channel[pCommandConfigReq->dcid];
- INFO_LOG(WII_IPC_WIIMOTE, " CommandCofigurationReq");
- INFO_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
- INFO_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", pCommandConfigReq->dcid);
- INFO_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", pCommandConfigReq->flags);
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] ReceiveConfigurationRequest");
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", pCommandConfigReq->dcid);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", pCommandConfigReq->flags);
Offset += sizeof(SL2CAP_CommandConfigurationReq);
@@ -478,7 +504,11 @@ void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Si
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == 2);
SL2CAP_OptionsMTU* pMTU = (SL2CAP_OptionsMTU*)&_pData[Offset];
rChannel.MTU = pMTU->MTU;
- INFO_LOG(WII_IPC_WIIMOTE, " Config MTU: 0x%04x", pMTU->MTU);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Config MTU: 0x%04x", pMTU->MTU);
+ // AyuanX: My experiment shows that the MTU is always set to 640 bytes
+ // This means that we only need temp_frame_size of 640B instead 1024B
+ // Actually I've never seen a frame bigger than 64B
+ // But... who cares of several KB mem today? Never mind
}
break;
@@ -487,7 +517,7 @@ void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Si
_dbg_assert_(WII_IPC_WIIMOTE, pOptions->length == 2);
SL2CAP_OptionsFlushTimeOut* pFlushTimeOut = (SL2CAP_OptionsFlushTimeOut*)&_pData[Offset];
rChannel.FlushTimeOut = pFlushTimeOut->TimeOut;
- INFO_LOG(WII_IPC_WIIMOTE, " Config FlushTimeOut: 0x%04x", pFlushTimeOut->TimeOut);
+ DEBUG_LOG(WII_IPC_WIIMOTE, " Config FlushTimeOut: 0x%04x", pFlushTimeOut->TimeOut);
}
break;
@@ -503,44 +533,25 @@ void CWII_IPC_HLE_WiiMote::CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Si
RespLen += OptionSize;
}
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendConfigurationResponse");
SendCommandToACL(_Ident, L2CAP_CONF_RSP, RespLen, TempBuffer);
- INFO_LOG(WII_IPC_WIIMOTE, "*******************************************************");
-}
-
-void CWII_IPC_HLE_WiiMote::CommandConnectionResponse(u8 _Ident, u8* _pData, u32 _Size)
-{
- l2cap_conn_rsp* rsp = (l2cap_conn_rsp*)_pData;
-
- _dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_conn_rsp));
-
- INFO_LOG(WII_IPC_WIIMOTE, " CommandConnectionResponse");
- DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", rsp->dcid);
- DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rsp->scid);
- DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result);
- DEBUG_LOG(WII_IPC_WIIMOTE, " Status: 0x%04x", rsp->status);
-
- _dbg_assert_(WII_IPC_WIIMOTE, rsp->result == 0);
- _dbg_assert_(WII_IPC_WIIMOTE, rsp->status == 0);
-
- _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(rsp->scid));
- SChannel& rChannel = m_Channel[rsp->scid];
- rChannel.DCID = rsp->dcid;
// update state machine
- if (rChannel.PSM == HIDP_CONTROL_CHANNEL)
+ if (rChannel.PSM == HID_CONTROL_CHANNEL)
m_HIDControlChannel_Connected = true;
if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
m_HIDInterruptChannel_Connected = true;
+
}
-void CWII_IPC_HLE_WiiMote::CommandConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size)
+void CWII_IPC_HLE_WiiMote::ReceiveConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size)
{
l2cap_conf_rsp* rsp = (l2cap_conf_rsp*)_pData;
_dbg_assert_(WII_IPC_WIIMOTE, _Size == sizeof(l2cap_conf_rsp));
- INFO_LOG(WII_IPC_WIIMOTE, " CommandConfigurationResponse");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] ReceiveConfigurationResponse");
DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", rsp->scid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", rsp->flags);
DEBUG_LOG(WII_IPC_WIIMOTE, " Result: 0x%04x", rsp->result);
@@ -549,21 +560,22 @@ void CWII_IPC_HLE_WiiMote::CommandConfigurationResponse(u8 _Ident, u8* _pData, u
// update state machine
SChannel& rChannel = m_Channel[rsp->scid];
- if (rChannel.PSM == HIDP_CONTROL_CHANNEL)
+
+ if (rChannel.PSM == HID_CONTROL_CHANNEL)
m_HIDControlChannel_Config = true;
if (rChannel.PSM == HID_INTERRUPT_CHANNEL)
m_HIDInterruptChannel_Config = true;
+
}
-void CWII_IPC_HLE_WiiMote::CommandDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size)
+void CWII_IPC_HLE_WiiMote::ReceiveDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size)
{
SL2CAP_CommandDisconnectionReq* pCommandDisconnectionReq = (SL2CAP_CommandDisconnectionReq*)_pData;
- // create the channel
_dbg_assert_(WII_IPC_WIIMOTE, m_Channel.find(pCommandDisconnectionReq->scid) != m_Channel.end());
- INFO_LOG(WII_IPC_WIIMOTE, " CommandDisconnectionReq");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] ReceiveDisconnectionReq");
DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
DEBUG_LOG(WII_IPC_WIIMOTE, " SCID: 0x%04x", pCommandDisconnectionReq->dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " DCID: 0x%04x", pCommandDisconnectionReq->scid);
@@ -573,23 +585,22 @@ void CWII_IPC_HLE_WiiMote::CommandDisconnectionReq(u8 _Ident, u8* _pData, u32 _S
Rsp.scid = pCommandDisconnectionReq->scid;
Rsp.dcid = pCommandDisconnectionReq->dcid;
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendDisconnectionResponse");
SendCommandToACL(_Ident, L2CAP_DISCONN_RSP, sizeof(SL2CAP_CommandDisconnectionResponse), (u8*)&Rsp);
}
-
//
//
//
//
-// --- Send Commands To Device
+// --- Send Commands To CPU
//
//
//
//
//
-
-
+// We assume WiiMote is always connected
void CWII_IPC_HLE_WiiMote::SendConnectionRequest(u16 scid, u16 psm)
{
// create the channel
@@ -601,13 +612,14 @@ void CWII_IPC_HLE_WiiMote::SendConnectionRequest(u16 scid, u16 psm)
cr.psm = psm;
cr.scid = scid;
- INFO_LOG(WII_IPC_WIIMOTE, " SendConnectionRequest()");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendConnectionRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Psm: 0x%04x", cr.psm);
DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid);
SendCommandToACL(L2CAP_CONN_REQ, L2CAP_CONN_REQ, sizeof(l2cap_conn_req), (u8*)&cr);
}
+// We don't initiatively disconnet Wiimote though ...
void CWII_IPC_HLE_WiiMote::SendDisconnectRequest(u16 scid)
{
// create the channel
@@ -617,7 +629,7 @@ void CWII_IPC_HLE_WiiMote::SendDisconnectRequest(u16 scid)
cr.dcid = rChannel.DCID;
cr.scid = rChannel.SCID;
- INFO_LOG(WII_IPC_WIIMOTE, " SendDisconnectionRequest()");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendDisconnectionRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr.dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Scid: 0x%04x", cr.scid);
@@ -659,13 +671,10 @@ void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16* MTU, u16* Flu
*(u16*)&Buffer[Offset] = *FlushTimeOut; Offset += 2;
}
- INFO_LOG(WII_IPC_WIIMOTE, " SendConfigurationRequest()");
+ INFO_LOG(WII_IPC_WIIMOTE, "[ACL] SendConfigurationRequest");
DEBUG_LOG(WII_IPC_WIIMOTE, " Dcid: 0x%04x", cr->dcid);
DEBUG_LOG(WII_IPC_WIIMOTE, " Flags: 0x%04x", cr->flags);
- // hack:
- static u8 ident = 99;
- ident++;
SendCommandToACL(L2CAP_CONF_REQ, L2CAP_CONF_REQ, Offset, Buffer);
}
@@ -681,7 +690,6 @@ void CWII_IPC_HLE_WiiMote::SendConfigurationRequest(u16 scid, u16* MTU, u16* Flu
//
//
-
#define SDP_UINT8 0x08
#define SDP_UINT16 0x09
#define SDP_UINT32 0x0A
@@ -718,7 +726,7 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceSearchResponse(u16 cid, u16 Transaction
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header));
- m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
+ m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
}
u32 ParseCont(u8* pCont)
@@ -746,10 +754,12 @@ int ParseAttribList(u8* pAttribIDList, u16& _startID, u16& _endID)
u32 attribOffset = 0;
CBigEndianBuffer attribList(pAttribIDList);
- u8 sequence = attribList.Read8(attribOffset); attribOffset++; _dbg_assert_(WII_IPC_WIIMOTE, sequence == SDP_SEQ8);
+ u8 sequence = attribList.Read8(attribOffset); attribOffset++;
u8 seqSize = attribList.Read8(attribOffset); attribOffset++;
u8 typeID = attribList.Read8(attribOffset); attribOffset++;
+ _dbg_assert_(WII_IPC_WIIMOTE, sequence == SDP_SEQ8);
+
if (typeID == SDP_UINT32)
{
_startID = attribList.Read16(attribOffset); attribOffset += 2;
@@ -759,7 +769,7 @@ int ParseAttribList(u8* pAttribIDList, u16& _startID, u16& _endID)
{
_startID = attribList.Read16(attribOffset); attribOffset += 2;
_endID = _startID;
- WARN_LOG(WII_IPC_WIIMOTE, "Read just a single attrib - not tested");
+ DEBUG_LOG(WII_IPC_WIIMOTE, "Read just a single attrib - not tested");
PanicAlert("Read just a single attrib - not tested");
}
@@ -799,9 +809,9 @@ void CWII_IPC_HLE_WiiMote::SDPSendServiceAttributeResponse(u16 cid, u16 Transact
memcpy(buffer.GetPointer(Offset), pPacket, packetSize); Offset += packetSize;
pHeader->Length = (u16)(Offset - sizeof(SL2CAP_Header));
- m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
+ m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
-// Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "test response: ");
+ // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "test response: ");
}
void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size)
@@ -812,7 +822,7 @@ void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size)
switch(buffer.Read8(0))
{
- // SDP_ServiceSearchRequest
+ // SDP_ServiceSearchRequest
case 0x02:
{
WARN_LOG(WII_IPC_WIIMOTE, "!!! SDP_ServiceSearchRequest !!!");
@@ -829,7 +839,7 @@ void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size)
}
break;
- // SDP_ServiceAttributeRequest
+ // SDP_ServiceAttributeRequest
case 0x04:
{
WARN_LOG(WII_IPC_WIIMOTE, "!!! SDP_ServiceAttributeRequest !!!");
@@ -867,8 +877,6 @@ void CWII_IPC_HLE_WiiMote::HandleSDP(u16 cid, u8* _pData, u32 _Size)
//
//
-
-
void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLength, u8* _pCommandData)
{
u8 DataFrame[1024];
@@ -885,22 +893,22 @@ void CWII_IPC_HLE_WiiMote::SendCommandToACL(u8 _Ident, u8 _Code, u8 _CommandLeng
memcpy(&DataFrame[Offset], _pCommandData, _CommandLength);
- INFO_LOG(WII_IPC_WIIMOTE, " SendCommandToACL (answer)");
+ DEBUG_LOG(WII_IPC_WIIMOTE, " SendCommandToACL (to CPU)");
DEBUG_LOG(WII_IPC_WIIMOTE, " Ident: 0x%02x", _Ident);
DEBUG_LOG(WII_IPC_WIIMOTE, " Code: 0x%02x", _Code);
// send ....
- m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
+ m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, pHeader->Length + sizeof(SL2CAP_Header));
- // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "m_pHost->SendACLFrame: ");
+ // Debugger::PrintDataBuffer(LogTypes::WIIMOTE, DataFrame, pHeader->Length + sizeof(SL2CAP_Header), "m_pHost->SendACLPacket: ");
}
// ===================================================
-/* On a second boot the _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid)) makes a report. However
- the game eventually starts and the Wiimote connects, but it takes at least ten seconds. */
-// ----------------
-void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size)
+// On a second boot the _dbg_assert_(WII_IPC_WIIMOTE, DoesChannelExist(scid)) makes a report.
+// However the game eventually starts and the Wiimote connects, but it takes at least ten seconds.
+// ---------------------------------------------------
+void CWII_IPC_HLE_WiiMote::ReceiveL2capData(u16 scid, const void* _pData, u32 _Size)
{
// Allocate DataFrame
u8 DataFrame[1024];
@@ -921,11 +929,11 @@ void CWII_IPC_HLE_WiiMote::SendL2capData(u16 scid, const void* _pData, u32 _Size
// Update Offset to the final size of the report
Offset += _Size;
- // Send the report
- m_pHost->SendACLFrame(GetConnectionHandle(), DataFrame, Offset);
-
// Update the status bar
Host_SetWiiMoteConnectionState(2);
+
+ // Send the report
+ m_pHost->SendACLPacket(GetConnectionHandle(), DataFrame, Offset);
}
@@ -942,7 +950,7 @@ namespace Core
DEBUG_LOG(WII_IPC_WIIMOTE, " Data: %s", ArrayToString(pData, _Size, 0, 50).c_str());
DEBUG_LOG(WII_IPC_WIIMOTE, " Channel: %u", _channelID);
- s_Usb->m_WiiMotes[0].SendL2capData(_channelID, _pData, _Size);
+ s_Usb->m_WiiMotes[0].ReceiveL2capData(_channelID, _pData, _Size);
DEBUG_LOG(WII_IPC_WIIMOTE, "=========================================================");
}
}
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 fbfdddfe4a..84bbbfc1c8 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
@@ -26,7 +26,7 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305;
enum
{
SDP_CHANNEL = 0x01,
- HIDP_CONTROL_CHANNEL = 0x11,
+ HID_CONTROL_CHANNEL = 0x11,
HID_INTERRUPT_CHANNEL= 0x13,
// L2CAP command codes
@@ -192,9 +192,13 @@ public:
// ugly Host handling....
// we really have to clean all this code
- bool Update();
+ bool LinkChannel();
bool IsConnected() const { return m_Connected; }
-
+ bool IsLinked() const { return m_Linked; }
+ void ShowStatus(const void* _pData); // Show status
+ void UpdateStatus(); // Update status
+ void ExecuteL2capCmd(u8* _pData, u32 _Size); // From CPU
+ void ReceiveL2capData(u16 scid, const void* _pData, u32 _Size); // From wiimote
void EventConnectionAccepted();
void EventDisconnect();
@@ -202,33 +206,20 @@ public:
void EventCommandWriteLinkPolicy();
const bdaddr_t& GetBD() const { return m_BD; }
-
const uint8_t* GetClass() const { return uclass; }
-
u16 GetConnectionHandle() const { return m_ControllerConnectionHandle; }
-
const u8* GetFeatures() const { return features; }
-
const char* GetName() const { return m_Name.c_str(); }
-
u8 GetLMPVersion() const { return lmp_version; }
-
u16 GetLMPSubVersion() const { return lmp_subversion; }
-
u8 GetManufactorID() const { return 0xF; } // Broadcom Corporation
-
- void SendACLFrame(u8* _pData, u32 _Size); // To wiimote
- void ShowStatus(const void* _pData); // Show status
- void UpdateStatus(); // Update status
-
- void SendL2capData(u16 scid, const void* _pData, u32 _Size); // From wiimote
-
const u8* GetLinkKey() const { return m_LinkKey; }
private:
// state machine
bool m_Connected;
+ bool m_Linked;
bool m_HIDControlChannel_Connected;
bool m_HIDControlChannel_ConnectedWait;
bool m_HIDControlChannel_Config;
@@ -238,25 +229,15 @@ private:
bool m_HIDInterruptChannel_Config;
bool m_HIDInterruptChannel_ConfigWait;
-
-
// STATE_TO_SAVE
bdaddr_t m_BD;
-
u16 m_ControllerConnectionHandle;
-
uint8_t uclass[HCI_CLASS_SIZE];
-
u8 features[HCI_FEATURES_SIZE];
-
u8 lmp_version;
-
u16 lmp_subversion;
-
u8 m_LinkKey[16];
-
std::string m_Name;
-
CWII_IPC_HLE_Device_usb_oh1_57e_305* m_pHost;
struct SChannel
@@ -285,13 +266,11 @@ private:
void SendConfigurationRequest(u16 _SCID, u16* _pMTU = NULL, u16* _pFlushTimeOut = NULL);
void SendDisconnectRequest(u16 _SCID);
- void CommandConnectionReq(u8 _Ident, u8* _pData, u32 _Size);
- void CommandCofigurationReq(u8 _Ident, u8* _pData, u32 _Size);
- void CommandConnectionResponse(u8 _Ident, u8* _pData, u32 _Size);
- void CommandDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size);
- void CommandConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size);
-
-
+ void ReceiveConnectionReq(u8 _Ident, u8* _pData, u32 _Size);
+ void ReceiveConnectionResponse(u8 _Ident, u8* _pData, u32 _Size);
+ void ReceiveDisconnectionReq(u8 _Ident, u8* _pData, u32 _Size);
+ void ReceiveConfigurationReq(u8 _Ident, u8* _pData, u32 _Size);
+ void ReceiveConfigurationResponse(u8 _Ident, u8* _pData, u32 _Size);
// some new ugly stuff
//