diff options
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Src/HW/HW.cpp | 11 | ||||
| -rw-r--r-- | Source/Core/Core/Src/HW/SystemTimers.cpp | 13 | ||||
| -rw-r--r-- | Source/Core/Core/Src/HW/WII_IPC.cpp | 158 | ||||
| -rw-r--r-- | Source/Core/Core/Src/HW/WII_IPC.h | 17 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 254 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.h | 9 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h | 12 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.cpp | 670 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_usb.h | 66 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp | 362 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.h | 47 |
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 // |
