IOS HLE: Deduplicate request code in OH1
This commit is contained in:
parent
d4de87a973
commit
f9e806fd71
|
@ -50,24 +50,23 @@ void RestoreBTInfoSection(SysConf* sysconf)
|
||||||
File::Delete(filename);
|
File::Delete(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const SIOCtlVBuffer& cmd_buffer)
|
CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlMessage::CtrlMessage(const IOSIOCtlVRequest& ioctlv)
|
||||||
|
: ios_request(ioctlv)
|
||||||
{
|
{
|
||||||
request_type = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address);
|
request_type = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||||
request = Memory::Read_U8(cmd_buffer.InBuffer[1].m_Address);
|
request = Memory::Read_U8(ioctlv.in_vectors[1].address);
|
||||||
value = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[2].m_Address));
|
value = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[2].address));
|
||||||
index = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[3].m_Address));
|
index = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[3].address));
|
||||||
length = Common::swap16(Memory::Read_U16(cmd_buffer.InBuffer[4].m_Address));
|
length = Common::swap16(Memory::Read_U16(ioctlv.in_vectors[4].address));
|
||||||
payload_addr = cmd_buffer.PayloadBuffer[0].m_Address;
|
payload_addr = ioctlv.io_vectors[0].address;
|
||||||
address = cmd_buffer.m_Address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const SIOCtlVBuffer& cmd_buffer,
|
CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::CtrlBuffer(const IOSIOCtlVRequest& ioctlv)
|
||||||
const u32 command_address)
|
: ios_request(ioctlv)
|
||||||
{
|
{
|
||||||
m_endpoint = Memory::Read_U8(cmd_buffer.InBuffer[0].m_Address);
|
m_endpoint = Memory::Read_U8(ioctlv.in_vectors[0].address);
|
||||||
m_length = Memory::Read_U16(cmd_buffer.InBuffer[1].m_Address);
|
m_length = Memory::Read_U16(ioctlv.in_vectors[1].address);
|
||||||
m_payload_addr = cmd_buffer.PayloadBuffer[0].m_Address;
|
m_payload_addr = ioctlv.io_vectors[0].address;
|
||||||
m_cmd_address = command_address;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* src,
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8* src,
|
||||||
|
@ -77,8 +76,3 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::FillBuffer(const u8*
|
||||||
m_length);
|
m_length);
|
||||||
Memory::CopyToEmu(m_payload_addr, src, size);
|
Memory::CopyToEmu(m_payload_addr, src, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_base::CtrlBuffer::SetRetVal(const u32 retval) const
|
|
||||||
{
|
|
||||||
Memory::Write_U32(retval, m_cmd_address + 4);
|
|
||||||
}
|
|
||||||
|
|
|
@ -24,11 +24,6 @@ public:
|
||||||
: IWII_IPC_HLE_Device(device_id, device_name)
|
: IWII_IPC_HLE_Device(device_id, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_base() override = default;
|
|
||||||
|
|
||||||
virtual IPCCommandResult Open(u32 command_address, u32 mode) override = 0;
|
|
||||||
|
|
||||||
virtual void DoState(PointerWrap& p) override = 0;
|
|
||||||
|
|
||||||
virtual void UpdateSyncButtonState(bool is_held) {}
|
virtual void UpdateSyncButtonState(bool is_held) {}
|
||||||
virtual void TriggerSyncButtonPressedEvent() {}
|
virtual void TriggerSyncButtonPressedEvent() {}
|
||||||
|
@ -56,31 +51,23 @@ protected:
|
||||||
|
|
||||||
struct CtrlMessage
|
struct CtrlMessage
|
||||||
{
|
{
|
||||||
CtrlMessage() = default;
|
CtrlMessage(const IOSIOCtlVRequest& ioctlv);
|
||||||
CtrlMessage(const SIOCtlVBuffer& cmd_buffer);
|
IOSIOCtlVRequest ios_request;
|
||||||
|
|
||||||
u8 request_type = 0;
|
u8 request_type = 0;
|
||||||
u8 request = 0;
|
u8 request = 0;
|
||||||
u16 value = 0;
|
u16 value = 0;
|
||||||
u16 index = 0;
|
u16 index = 0;
|
||||||
u16 length = 0;
|
u16 length = 0;
|
||||||
u32 payload_addr = 0;
|
u32 payload_addr = 0;
|
||||||
u32 address = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CtrlBuffer
|
struct CtrlBuffer
|
||||||
{
|
{
|
||||||
public:
|
CtrlBuffer(const IOSIOCtlVRequest& ioctlv);
|
||||||
CtrlBuffer() = default;
|
IOSIOCtlVRequest ios_request;
|
||||||
CtrlBuffer(const SIOCtlVBuffer& cmd_buffer, u32 command_address);
|
|
||||||
|
|
||||||
void FillBuffer(const u8* src, size_t size) const;
|
void FillBuffer(const u8* src, size_t size) const;
|
||||||
void SetRetVal(const u32 retval) const;
|
|
||||||
bool IsValid() const { return m_cmd_address != 0; }
|
|
||||||
void Invalidate() { m_cmd_address = m_payload_addr = 0; }
|
|
||||||
u8 m_endpoint = 0;
|
u8 m_endpoint = 0;
|
||||||
u16 m_length = 0;
|
u16 m_length = 0;
|
||||||
u32 m_payload_addr = 0;
|
u32 m_payload_addr = 0;
|
||||||
u32 m_cmd_address = 0;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,8 +95,6 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::CWII_IPC_HLE_Device_usb_oh1_57e_305_emu
|
||||||
m_ControllerBD.b[4] = 0x00;
|
m_ControllerBD.b[4] = 0x00;
|
||||||
m_ControllerBD.b[5] = 0xFF;
|
m_ControllerBD.b[5] = 0xFF;
|
||||||
|
|
||||||
memset(m_PacketCount, 0, sizeof(m_PacketCount));
|
|
||||||
|
|
||||||
Host_SetWiiMoteConnectionState(0);
|
Host_SetWiiMoteConnectionState(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,6 +104,18 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::~CWII_IPC_HLE_Device_usb_oh1_57e_305_em
|
||||||
SetUsbPointer(nullptr);
|
SetUsbPointer(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void DoStateForMessage(PointerWrap& p, std::unique_ptr<T>& message)
|
||||||
|
{
|
||||||
|
u32 request_address = (message != nullptr) ? message->ios_request.address : 0;
|
||||||
|
p.Do(request_address);
|
||||||
|
if (request_address != 0)
|
||||||
|
{
|
||||||
|
IOSIOCtlVRequest request{request_address};
|
||||||
|
message = std::make_unique<T>(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p)
|
||||||
{
|
{
|
||||||
bool passthrough_bluetooth = false;
|
bool passthrough_bluetooth = false;
|
||||||
|
@ -119,10 +129,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::DoState(PointerWrap& p)
|
||||||
|
|
||||||
p.Do(m_is_active);
|
p.Do(m_is_active);
|
||||||
p.Do(m_ControllerBD);
|
p.Do(m_ControllerBD);
|
||||||
p.Do(m_CtrlSetup);
|
DoStateForMessage(p, m_CtrlSetup);
|
||||||
p.Do(m_ACLSetup);
|
DoStateForMessage(p, m_HCIEndpoint);
|
||||||
p.DoPOD(m_HCIEndpoint);
|
DoStateForMessage(p, m_ACLEndpoint);
|
||||||
p.DoPOD(m_ACLEndpoint);
|
|
||||||
p.Do(m_last_ticks);
|
p.Do(m_last_ticks);
|
||||||
p.DoArray(m_PacketCount);
|
p.DoArray(m_PacketCount);
|
||||||
p.Do(m_ScanEnable);
|
p.Do(m_ScanEnable);
|
||||||
|
@ -138,75 +147,41 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::RemoteDisconnect(u16 _connectionHa
|
||||||
return SendEventDisconnect(_connectionHandle, 0x13);
|
return SendEventDisconnect(_connectionHandle, 0x13);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Open(u32 _CommandAddress, u32 _Mode)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close()
|
||||||
{
|
{
|
||||||
|
// Clean up state
|
||||||
m_ScanEnable = 0;
|
m_ScanEnable = 0;
|
||||||
|
|
||||||
m_last_ticks = 0;
|
m_last_ticks = 0;
|
||||||
memset(m_PacketCount, 0, sizeof(m_PacketCount));
|
memset(m_PacketCount, 0, sizeof(m_PacketCount));
|
||||||
|
m_HCIEndpoint.reset();
|
||||||
m_HCIEndpoint.m_cmd_address = 0;
|
m_ACLEndpoint.reset();
|
||||||
m_ACLEndpoint.m_cmd_address = 0;
|
|
||||||
|
|
||||||
m_is_active = true;
|
|
||||||
return GetDefaultReply();
|
|
||||||
}
|
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Close(u32 _CommandAddress, bool _bForce)
|
|
||||||
{
|
|
||||||
m_ScanEnable = 0;
|
|
||||||
|
|
||||||
m_last_ticks = 0;
|
|
||||||
memset(m_PacketCount, 0, sizeof(m_PacketCount));
|
|
||||||
|
|
||||||
m_HCIEndpoint.m_cmd_address = 0;
|
|
||||||
m_ACLEndpoint.m_cmd_address = 0;
|
|
||||||
|
|
||||||
m_is_active = false;
|
m_is_active = false;
|
||||||
return GetDefaultReply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAddress)
|
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(const IOSIOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
bool _SendReply = false;
|
bool send_reply = true;
|
||||||
|
switch (request.request)
|
||||||
SIOCtlVBuffer CommandBuffer(_CommandAddress);
|
|
||||||
|
|
||||||
switch (CommandBuffer.Parameter)
|
|
||||||
{
|
{
|
||||||
case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack
|
case USBV0_IOCTL_CTRLMSG: // HCI command is received from the stack
|
||||||
{
|
{
|
||||||
// This is the HCI datapath from CPU to Wii Remote, the USB stuff is little endian..
|
m_CtrlSetup = std::make_unique<CtrlMessage>(request);
|
||||||
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");
|
|
||||||
|
|
||||||
// Replies are generated inside
|
// Replies are generated inside
|
||||||
ExecuteHCICommandMessage(m_CtrlSetup);
|
ExecuteHCICommandMessage(*m_CtrlSetup);
|
||||||
|
m_CtrlSetup.reset();
|
||||||
|
send_reply = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case USBV0_IOCTL_BLKMSG:
|
case USBV0_IOCTL_BLKMSG:
|
||||||
{
|
{
|
||||||
const CtrlBuffer ctrl(CommandBuffer, _CommandAddress);
|
const CtrlBuffer ctrl{request};
|
||||||
switch (ctrl.m_endpoint)
|
switch (ctrl.m_endpoint)
|
||||||
{
|
{
|
||||||
case ACL_DATA_OUT: // ACL data is received from the stack
|
case ACL_DATA_OUT: // ACL data is received from the stack
|
||||||
{
|
{
|
||||||
// This is the ACL datapath from CPU to Wii Remote
|
// This is the ACL datapath from CPU to Wii Remote
|
||||||
// Here we only need to record the command address in case we need to delay the reply
|
|
||||||
m_ACLSetup = CommandBuffer.m_Address;
|
|
||||||
|
|
||||||
const auto* acl_header =
|
const auto* acl_header =
|
||||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(ctrl.m_payload_addr));
|
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(ctrl.m_payload_addr));
|
||||||
|
|
||||||
|
@ -216,65 +191,43 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::IOCtlV(u32 _CommandAdd
|
||||||
SendToDevice(HCI_CON_HANDLE(acl_header->con_handle),
|
SendToDevice(HCI_CON_HANDLE(acl_header->con_handle),
|
||||||
Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)),
|
Memory::GetPointer(ctrl.m_payload_addr + sizeof(hci_acldata_hdr_t)),
|
||||||
acl_header->length);
|
acl_header->length);
|
||||||
|
break;
|
||||||
_SendReply = true;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case ACL_DATA_IN: // We are given an ACL buffer to fill
|
case ACL_DATA_IN: // We are given an ACL buffer to fill
|
||||||
{
|
{
|
||||||
CtrlBuffer temp(CommandBuffer, _CommandAddress);
|
m_ACLEndpoint = std::make_unique<CtrlBuffer>(request);
|
||||||
m_ACLEndpoint = temp;
|
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", request.address);
|
||||||
|
send_reply = false;
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL_DATA_IN: 0x%08x ", _CommandAddress);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
|
||||||
_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint);
|
_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_BLKMSG: %x", ctrl.m_endpoint);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case USBV0_IOCTL_INTRMSG:
|
case USBV0_IOCTL_INTRMSG:
|
||||||
{
|
{
|
||||||
const CtrlBuffer ctrl(CommandBuffer, _CommandAddress);
|
const CtrlBuffer ctrl{request};
|
||||||
if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
if (ctrl.m_endpoint == HCI_EVENT) // We are given a HCI buffer to fill
|
||||||
{
|
{
|
||||||
CtrlBuffer temp(CommandBuffer, _CommandAddress);
|
m_HCIEndpoint = std::make_unique<CtrlBuffer>(request);
|
||||||
m_HCIEndpoint = temp;
|
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", request.address);
|
||||||
|
send_reply = false;
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI_EVENT: 0x%08x ", _CommandAddress);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint);
|
_dbg_assert_msg_(WII_IPC_WIIMOTE, 0, "Unknown USBV0_IOCTL_INTRMSG: %x", ctrl.m_endpoint);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
request.DumpUnknown(GetDeviceName(), LogTypes::WII_IPC_WIIMOTE);
|
||||||
_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());
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " Parameter: 0x%x", CommandBuffer.Parameter);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " BufferVector: 0x%08x", CommandBuffer.BufferVector);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address);
|
|
||||||
INFO_LOG(WII_IPC_WIIMOTE, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// write return value
|
request.SetReturnValue(IPC_SUCCESS);
|
||||||
Memory::Write_U32(0, _CommandAddress + 4);
|
return send_reply ? GetDefaultReply() : GetNoReply();
|
||||||
return _SendReply ? GetDefaultReply() : GetNoReply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Here we handle the USBV0_IOCTL_BLKMSG Ioctlv
|
// Here we handle the USBV0_IOCTL_BLKMSG Ioctlv
|
||||||
|
@ -302,22 +255,22 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendACLPacket(u16 connection_handl
|
||||||
{
|
{
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", connection_handle);
|
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet from %x ready to send to stack...", connection_handle);
|
||||||
|
|
||||||
if (m_ACLEndpoint.IsValid() && !m_HCIEndpoint.IsValid() && m_EventQueue.empty())
|
if (m_ACLEndpoint && !m_HCIEndpoint && m_EventQueue.empty())
|
||||||
{
|
{
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x",
|
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL endpoint valid, sending packet to %08x",
|
||||||
m_ACLEndpoint.m_cmd_address);
|
m_ACLEndpoint->ios_request.address);
|
||||||
|
|
||||||
hci_acldata_hdr_t* header =
|
hci_acldata_hdr_t* header =
|
||||||
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(m_ACLEndpoint.m_payload_addr));
|
reinterpret_cast<hci_acldata_hdr_t*>(Memory::GetPointer(m_ACLEndpoint->m_payload_addr));
|
||||||
header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
header->con_handle = HCI_MK_CON_HANDLE(connection_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
||||||
header->length = size;
|
header->length = size;
|
||||||
|
|
||||||
// Write the packet to the buffer
|
// Write the packet to the buffer
|
||||||
memcpy(reinterpret_cast<u8*>(header) + sizeof(hci_acldata_hdr_t), data, header->length);
|
memcpy(reinterpret_cast<u8*>(header) + sizeof(hci_acldata_hdr_t), data, header->length);
|
||||||
|
|
||||||
m_ACLEndpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size);
|
m_ACLEndpoint->ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size);
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(m_ACLEndpoint->ios_request);
|
||||||
m_ACLEndpoint.Invalidate();
|
m_ACLEndpoint.reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -336,17 +289,17 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...",
|
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x completed...",
|
||||||
((hci_event_hdr_t*)_event.m_buffer)->event);
|
((hci_event_hdr_t*)_event.m_buffer)->event);
|
||||||
|
|
||||||
if (m_HCIEndpoint.IsValid())
|
if (m_HCIEndpoint)
|
||||||
{
|
{
|
||||||
if (m_EventQueue.empty()) // fast path :)
|
if (m_EventQueue.empty()) // fast path :)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x",
|
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI endpoint valid, sending packet to %08x",
|
||||||
m_HCIEndpoint.m_cmd_address);
|
m_HCIEndpoint->ios_request.address);
|
||||||
m_HCIEndpoint.FillBuffer(_event.m_buffer, _event.m_size);
|
m_HCIEndpoint->FillBuffer(_event.m_buffer, _event.m_size);
|
||||||
m_HCIEndpoint.SetRetVal(_event.m_size);
|
m_HCIEndpoint->ios_request.SetReturnValue(_event.m_size);
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request);
|
||||||
m_HCIEndpoint.Invalidate();
|
m_HCIEndpoint.reset();
|
||||||
}
|
}
|
||||||
else // push new one, pop oldest
|
else // push new one, pop oldest
|
||||||
{
|
{
|
||||||
|
@ -357,12 +310,12 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x "
|
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x "
|
||||||
"being written from queue (%zu) to %08x...",
|
"being written from queue (%zu) to %08x...",
|
||||||
((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1,
|
((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1,
|
||||||
m_HCIEndpoint.m_cmd_address);
|
m_HCIEndpoint->ios_request.address);
|
||||||
m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
|
m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size);
|
||||||
m_HCIEndpoint.SetRetVal(event.m_size);
|
m_HCIEndpoint->ios_request.SetReturnValue(event.m_size);
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request);
|
||||||
m_HCIEndpoint.Invalidate();
|
m_HCIEndpoint.reset();
|
||||||
m_EventQueue.pop_front();
|
m_EventQueue.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -377,24 +330,27 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::AddEventToQueue(const SQueuedEvent
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update()
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update()
|
||||||
{
|
{
|
||||||
// check HCI queue
|
// check HCI queue
|
||||||
if (!m_EventQueue.empty() && m_HCIEndpoint.IsValid())
|
if (!m_EventQueue.empty() && m_HCIEndpoint)
|
||||||
{
|
{
|
||||||
// an endpoint has become available, and we have a stored response.
|
// an endpoint has become available, and we have a stored response.
|
||||||
const SQueuedEvent& event = m_EventQueue.front();
|
const SQueuedEvent& event = m_EventQueue.front();
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x being written from queue (%zu) to %08x...",
|
DEBUG_LOG(WII_IPC_WIIMOTE, "HCI event %x being written from queue (%zu) to %08x...",
|
||||||
((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1,
|
((hci_event_hdr_t*)event.m_buffer)->event, m_EventQueue.size() - 1,
|
||||||
m_HCIEndpoint.m_cmd_address);
|
m_HCIEndpoint->ios_request.address);
|
||||||
m_HCIEndpoint.FillBuffer(event.m_buffer, event.m_size);
|
m_HCIEndpoint->FillBuffer(event.m_buffer, event.m_size);
|
||||||
m_HCIEndpoint.SetRetVal(event.m_size);
|
m_HCIEndpoint->ios_request.SetReturnValue(event.m_size);
|
||||||
// Send a reply to indicate HCI buffer is filled
|
// Send a reply to indicate HCI buffer is filled
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(m_HCIEndpoint->ios_request);
|
||||||
m_HCIEndpoint.Invalidate();
|
m_HCIEndpoint.reset();
|
||||||
m_EventQueue.pop_front();
|
m_EventQueue.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check ACL queue
|
// check ACL queue
|
||||||
if (!m_acl_pool.IsEmpty() && m_ACLEndpoint.IsValid() && m_EventQueue.empty())
|
if (!m_acl_pool.IsEmpty() && m_ACLEndpoint && m_EventQueue.empty())
|
||||||
m_acl_pool.WriteToEndpoint(m_ACLEndpoint);
|
{
|
||||||
|
m_acl_pool.WriteToEndpoint(*m_ACLEndpoint);
|
||||||
|
m_ACLEndpoint.reset();
|
||||||
|
}
|
||||||
|
|
||||||
// We wait for ScanEnable to be sent from the Bluetooth stack through HCI_CMD_WRITE_SCAN_ENABLE
|
// We wait for ScanEnable to be sent from the Bluetooth stack through HCI_CMD_WRITE_SCAN_ENABLE
|
||||||
// before we initiate the connection.
|
// before we initiate the connection.
|
||||||
|
@ -402,7 +358,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update()
|
||||||
// FiRES: TODO find a better way to do this
|
// FiRES: TODO find a better way to do this
|
||||||
|
|
||||||
// Create ACL connection
|
// Create ACL connection
|
||||||
if (m_HCIEndpoint.IsValid() && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE))
|
if (m_HCIEndpoint && (m_ScanEnable & HCI_PAGE_SCAN_ENABLE))
|
||||||
{
|
{
|
||||||
for (auto& wiimote : m_WiiMotes)
|
for (auto& wiimote : m_WiiMotes)
|
||||||
{
|
{
|
||||||
|
@ -415,7 +371,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link channels when connected
|
// Link channels when connected
|
||||||
if (m_ACLEndpoint.IsValid())
|
if (m_ACLEndpoint)
|
||||||
{
|
{
|
||||||
for (auto& wiimote : m_WiiMotes)
|
for (auto& wiimote : m_WiiMotes)
|
||||||
{
|
{
|
||||||
|
@ -469,7 +425,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe
|
||||||
|
|
||||||
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from "
|
DEBUG_LOG(WII_IPC_WIIMOTE, "ACL packet being written from "
|
||||||
"queue to %08x",
|
"queue to %08x",
|
||||||
endpoint.m_cmd_address);
|
endpoint.ios_request.address);
|
||||||
|
|
||||||
hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr);
|
hci_acldata_hdr_t* pHeader = (hci_acldata_hdr_t*)Memory::GetPointer(endpoint.m_payload_addr);
|
||||||
pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
pHeader->con_handle = HCI_MK_CON_HANDLE(conn_handle, HCI_PACKET_START, HCI_POINT2POINT);
|
||||||
|
@ -478,12 +434,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ACLPool::WriteToEndpoint(CtrlBuffe
|
||||||
// Write the packet to the buffer
|
// Write the packet to the buffer
|
||||||
std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t));
|
std::copy(data, data + size, (u8*)pHeader + sizeof(hci_acldata_hdr_t));
|
||||||
|
|
||||||
endpoint.SetRetVal(sizeof(hci_acldata_hdr_t) + size);
|
endpoint.ios_request.SetReturnValue(sizeof(hci_acldata_hdr_t) + size);
|
||||||
|
|
||||||
m_queue.pop_front();
|
m_queue.pop_front();
|
||||||
|
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(endpoint.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(endpoint.ios_request);
|
||||||
endpoint.Invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete()
|
bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventInquiryComplete()
|
||||||
|
@ -1023,10 +978,10 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::SendEventConPacketTypeChange(u16 _
|
||||||
// Command dispatcher
|
// Command dispatcher
|
||||||
// This is called from the USBV0_IOCTL_CTRLMSG Ioctlv
|
// This is called from the USBV0_IOCTL_CTRLMSG Ioctlv
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage(
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage(
|
||||||
const SHCICommandMessage& _rHCICommandMessage)
|
const CtrlMessage& ctrl_message)
|
||||||
{
|
{
|
||||||
u8* pInput = Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr + 3);
|
u8* pInput = Memory::GetPointer(ctrl_message.payload_addr + 3);
|
||||||
SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(_rHCICommandMessage.m_PayLoadAddr);
|
SCommandMessage* pMsg = (SCommandMessage*)Memory::GetPointer(ctrl_message.payload_addr);
|
||||||
|
|
||||||
u16 ocf = HCI_OCF(pMsg->Opcode);
|
u16 ocf = HCI_OCF(pMsg->Opcode);
|
||||||
u16 ogf = HCI_OGF(pMsg->Opcode);
|
u16 ogf = HCI_OGF(pMsg->Opcode);
|
||||||
|
@ -1110,11 +1065,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage(
|
||||||
|
|
||||||
// vendor specific...
|
// vendor specific...
|
||||||
case 0xFC4C:
|
case 0xFC4C:
|
||||||
CommandVendorSpecific_FC4C(pInput, _rHCICommandMessage.m_PayLoadSize - 3);
|
CommandVendorSpecific_FC4C(pInput, ctrl_message.length - 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFC4F:
|
case 0xFC4F:
|
||||||
CommandVendorSpecific_FC4F(pInput, _rHCICommandMessage.m_PayLoadSize - 3);
|
CommandVendorSpecific_FC4F(pInput, ctrl_message.length - 3);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCI_CMD_INQUIRY_CANCEL:
|
case HCI_CMD_INQUIRY_CANCEL:
|
||||||
|
@ -1203,7 +1158,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_emu::ExecuteHCICommandMessage(
|
||||||
}
|
}
|
||||||
|
|
||||||
// HCI command is finished, send a reply to command
|
// HCI command is finished, send a reply to command
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(_rHCICommandMessage.m_Address);
|
WII_IPC_HLE_Interface::EnqueueReply(ctrl_message.ios_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -43,10 +44,8 @@ public:
|
||||||
|
|
||||||
virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_emu();
|
virtual ~CWII_IPC_HLE_Device_usb_oh1_57e_305_emu();
|
||||||
|
|
||||||
IPCCommandResult Open(u32 _CommandAddress, u32 _Mode) override;
|
void Close() override;
|
||||||
IPCCommandResult Close(u32 _CommandAddress, bool _bForce) override;
|
IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override;
|
||||||
|
|
||||||
IPCCommandResult IOCtlV(u32 _CommandAddress) override;
|
|
||||||
|
|
||||||
void Update() override;
|
void Update() override;
|
||||||
|
|
||||||
|
@ -62,31 +61,16 @@ public:
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SHCICommandMessage
|
|
||||||
{
|
|
||||||
u8 bRequestType;
|
|
||||||
u8 bRequest;
|
|
||||||
u16 wValue;
|
|
||||||
u16 wIndex;
|
|
||||||
u16 wLength;
|
|
||||||
|
|
||||||
u32 m_PayLoadAddr;
|
|
||||||
u32 m_PayLoadSize;
|
|
||||||
u32 m_Address;
|
|
||||||
};
|
|
||||||
|
|
||||||
bdaddr_t m_ControllerBD;
|
bdaddr_t m_ControllerBD;
|
||||||
|
|
||||||
// this is used to trigger connecting via ACL
|
// this is used to trigger connecting via ACL
|
||||||
u8 m_ScanEnable = 0;
|
u8 m_ScanEnable = 0;
|
||||||
|
|
||||||
SHCICommandMessage m_CtrlSetup;
|
std::unique_ptr<CtrlMessage> m_CtrlSetup;
|
||||||
CtrlBuffer m_HCIEndpoint;
|
std::unique_ptr<CtrlBuffer> m_HCIEndpoint;
|
||||||
|
std::unique_ptr<CtrlBuffer> m_ACLEndpoint;
|
||||||
std::deque<SQueuedEvent> m_EventQueue;
|
std::deque<SQueuedEvent> m_EventQueue;
|
||||||
|
|
||||||
u32 m_ACLSetup;
|
|
||||||
CtrlBuffer m_ACLEndpoint;
|
|
||||||
|
|
||||||
class ACLPool
|
class ACLPool
|
||||||
{
|
{
|
||||||
struct Packet
|
struct Packet
|
||||||
|
@ -109,7 +93,7 @@ private:
|
||||||
void DoState(PointerWrap& p) { p.Do(m_queue); }
|
void DoState(PointerWrap& p) { p.Do(m_queue); }
|
||||||
} m_acl_pool;
|
} m_acl_pool;
|
||||||
|
|
||||||
u32 m_PacketCount[MAX_BBMOTES];
|
u32 m_PacketCount[MAX_BBMOTES] = {};
|
||||||
u64 m_last_ticks = 0;
|
u64 m_last_ticks = 0;
|
||||||
|
|
||||||
// Send ACL data to a device (wiimote)
|
// Send ACL data to a device (wiimote)
|
||||||
|
@ -138,7 +122,7 @@ private:
|
||||||
bool SendEventLinkKeyNotification(const u8 num_to_send);
|
bool SendEventLinkKeyNotification(const u8 num_to_send);
|
||||||
|
|
||||||
// Execute HCI Message
|
// Execute HCI Message
|
||||||
void ExecuteHCICommandMessage(const SHCICommandMessage& _rCtrlMessage);
|
void ExecuteHCICommandMessage(const CtrlMessage& ctrl_message);
|
||||||
|
|
||||||
// OGF 0x01 - Link control commands and return parameters
|
// OGF 0x01 - Link control commands and return parameters
|
||||||
void CommandWriteInquiryMode(const u8* input);
|
void CommandWriteInquiryMode(const u8* input);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/MsgHandler.h"
|
#include "Common/MsgHandler.h"
|
||||||
#include "Common/Network.h"
|
#include "Common/Network.h"
|
||||||
|
@ -89,7 +90,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305_real::~CWII_IPC_HLE_Device_usb_oh1_57e_305_r
|
||||||
SaveLinkKeys();
|
SaveLinkKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_address, u32 mode)
|
IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(const IOSOpenRequest& request)
|
||||||
{
|
{
|
||||||
libusb_device** list;
|
libusb_device** list;
|
||||||
const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list);
|
const ssize_t cnt = libusb_get_device_list(m_libusb_context, &list);
|
||||||
|
@ -136,18 +137,18 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Open(u32 command_addr
|
||||||
PanicAlertT("Bluetooth passthrough mode is enabled, "
|
PanicAlertT("Bluetooth passthrough mode is enabled, "
|
||||||
"but no usable Bluetooth USB device was found. Aborting.");
|
"but no usable Bluetooth USB device was found. Aborting.");
|
||||||
Core::QueueHostJob(Core::Stop);
|
Core::QueueHostJob(Core::Stop);
|
||||||
return GetNoReply();
|
return IPC_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartTransferThread();
|
StartTransferThread();
|
||||||
|
|
||||||
m_is_active = true;
|
m_is_active = true;
|
||||||
return GetDefaultReply();
|
return IPC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_address, bool force)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close()
|
||||||
{
|
{
|
||||||
if (!force)
|
if (m_handle)
|
||||||
{
|
{
|
||||||
libusb_release_interface(m_handle, 0);
|
libusb_release_interface(m_handle, 0);
|
||||||
StopTransferThread();
|
StopTransferThread();
|
||||||
|
@ -156,10 +157,9 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::Close(u32 command_add
|
||||||
}
|
}
|
||||||
|
|
||||||
m_is_active = false;
|
m_is_active = false;
|
||||||
return GetDefaultReply();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_address)
|
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(const IOSIOCtlVRequest& request)
|
||||||
{
|
{
|
||||||
if (!m_is_wii_bt_module && s_need_reset_keys.TestAndClear())
|
if (!m_is_wii_bt_module && s_need_reset_keys.TestAndClear())
|
||||||
{
|
{
|
||||||
|
@ -170,14 +170,13 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
|
||||||
WaitForHCICommandComplete(HCI_CMD_WRITE_STORED_LINK_KEY);
|
WaitForHCICommandComplete(HCI_CMD_WRITE_STORED_LINK_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SIOCtlVBuffer cmd_buffer(command_address);
|
switch (request.request)
|
||||||
switch (cmd_buffer.Parameter)
|
|
||||||
{
|
{
|
||||||
// HCI commands to the Bluetooth adapter
|
// HCI commands to the Bluetooth adapter
|
||||||
case USBV0_IOCTL_CTRLMSG:
|
case USBV0_IOCTL_CTRLMSG:
|
||||||
{
|
{
|
||||||
auto cmd = std::make_unique<CtrlMessage>(cmd_buffer);
|
auto cmd = std::make_unique<CtrlMessage>(request);
|
||||||
const u16 opcode = *reinterpret_cast<u16*>(Memory::GetPointer(cmd->payload_addr));
|
const u16 opcode = Common::swap16(Memory::Read_U16(cmd->payload_addr));
|
||||||
if (opcode == HCI_CMD_READ_BUFFER_SIZE)
|
if (opcode == HCI_CMD_READ_BUFFER_SIZE)
|
||||||
{
|
{
|
||||||
m_fake_read_buffer_size_reply.Set();
|
m_fake_read_buffer_size_reply.Set();
|
||||||
|
@ -220,25 +219,24 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
|
||||||
case USBV0_IOCTL_BLKMSG:
|
case USBV0_IOCTL_BLKMSG:
|
||||||
case USBV0_IOCTL_INTRMSG:
|
case USBV0_IOCTL_INTRMSG:
|
||||||
{
|
{
|
||||||
auto buffer = std::make_unique<CtrlBuffer>(cmd_buffer, command_address);
|
auto buffer = std::make_unique<CtrlBuffer>(request);
|
||||||
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear())
|
if (request.request == USBV0_IOCTL_INTRMSG && m_fake_read_buffer_size_reply.TestAndClear())
|
||||||
{
|
{
|
||||||
FakeReadBufferSizeReply(*buffer);
|
FakeReadBufferSizeReply(*buffer);
|
||||||
return GetNoReply();
|
return GetNoReply();
|
||||||
}
|
}
|
||||||
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear())
|
if (request.request == USBV0_IOCTL_INTRMSG && m_fake_vendor_command_reply.TestAndClear())
|
||||||
{
|
{
|
||||||
FakeVendorCommandReply(*buffer);
|
FakeVendorCommandReply(*buffer);
|
||||||
return GetNoReply();
|
return GetNoReply();
|
||||||
}
|
}
|
||||||
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG &&
|
if (request.request == USBV0_IOCTL_INTRMSG && m_sync_button_state == SyncButtonState::Pressed)
|
||||||
m_sync_button_state == SyncButtonState::Pressed)
|
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Scanning for Wii Remotes", 2000);
|
Core::DisplayMessage("Scanning for Wii Remotes", 2000);
|
||||||
FakeSyncButtonPressedEvent(*buffer);
|
FakeSyncButtonPressedEvent(*buffer);
|
||||||
return GetNoReply();
|
return GetNoReply();
|
||||||
}
|
}
|
||||||
if (cmd_buffer.Parameter == USBV0_IOCTL_INTRMSG &&
|
if (request.request == USBV0_IOCTL_INTRMSG &&
|
||||||
m_sync_button_state == SyncButtonState::LongPressed)
|
m_sync_button_state == SyncButtonState::LongPressed)
|
||||||
{
|
{
|
||||||
Core::DisplayMessage("Reset saved Wii Remote pairings", 2000);
|
Core::DisplayMessage("Reset saved Wii Remote pairings", 2000);
|
||||||
|
@ -253,8 +251,8 @@ IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_real::IOCtlV(u32 command_ad
|
||||||
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
transfer->flags |= LIBUSB_TRANSFER_FREE_TRANSFER;
|
||||||
transfer->length = buffer->m_length;
|
transfer->length = buffer->m_length;
|
||||||
transfer->timeout = TIMEOUT;
|
transfer->timeout = TIMEOUT;
|
||||||
transfer->type = cmd_buffer.Parameter == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK :
|
transfer->type = request.request == USBV0_IOCTL_BLKMSG ? LIBUSB_TRANSFER_TYPE_BULK :
|
||||||
LIBUSB_TRANSFER_TYPE_INTERRUPT;
|
LIBUSB_TRANSFER_TYPE_INTERRUPT;
|
||||||
transfer->user_data = buffer.release();
|
transfer->user_data = buffer.release();
|
||||||
libusb_submit_transfer(transfer);
|
libusb_submit_transfer(transfer);
|
||||||
break;
|
break;
|
||||||
|
@ -387,7 +385,7 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305_real::SendHCIStoreLinkKeyCommand()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const CtrlBuffer& ctrl)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(CtrlBuffer& ctrl)
|
||||||
{
|
{
|
||||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||||
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
||||||
|
@ -395,8 +393,8 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl
|
||||||
hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2;
|
hci_event->PayloadLength = sizeof(SHCIEventCommand) - 2;
|
||||||
hci_event->PacketIndicator = 0x01;
|
hci_event->PacketIndicator = 0x01;
|
||||||
hci_event->Opcode = m_fake_vendor_command_reply_opcode;
|
hci_event->Opcode = m_fake_vendor_command_reply_opcode;
|
||||||
ctrl.SetRetVal(sizeof(SHCIEventCommand));
|
ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand));
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
// Due to how the widcomm stack which Nintendo uses is coded, we must never
|
||||||
|
@ -404,7 +402,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeVendorCommandReply(const Ctrl
|
||||||
// - it will cause a u8 underflow and royally screw things up.
|
// - it will cause a u8 underflow and royally screw things up.
|
||||||
// Therefore, the reply to this command has to be faked to avoid random, weird issues
|
// Therefore, the reply to this command has to be faked to avoid random, weird issues
|
||||||
// (including Wiimote disconnects and "event mismatch" warning messages).
|
// (including Wiimote disconnects and "event mismatch" warning messages).
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const CtrlBuffer& ctrl)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(CtrlBuffer& ctrl)
|
||||||
{
|
{
|
||||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||||
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
auto* hci_event = reinterpret_cast<SHCIEventCommand*>(packet);
|
||||||
|
@ -421,11 +419,11 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeReadBufferSizeReply(const Ctr
|
||||||
reply.num_sco_pkts = SCO_PKT_NUM;
|
reply.num_sco_pkts = SCO_PKT_NUM;
|
||||||
|
|
||||||
memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp));
|
memcpy(packet + sizeof(SHCIEventCommand), &reply, sizeof(hci_read_buffer_size_rp));
|
||||||
ctrl.SetRetVal(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp));
|
ctrl.ios_request.SetReturnValue(sizeof(SHCIEventCommand) + sizeof(hci_read_buffer_size_rp));
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuffer& ctrl,
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(CtrlBuffer& ctrl,
|
||||||
const u8* payload, const u8 size)
|
const u8* payload, const u8 size)
|
||||||
{
|
{
|
||||||
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
u8* packet = Memory::GetPointer(ctrl.m_payload_addr);
|
||||||
|
@ -433,15 +431,15 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonEvent(const CtrlBuf
|
||||||
hci_event->event = HCI_EVENT_VENDOR;
|
hci_event->event = HCI_EVENT_VENDOR;
|
||||||
hci_event->length = size;
|
hci_event->length = size;
|
||||||
memcpy(packet + sizeof(hci_event_hdr_t), payload, size);
|
memcpy(packet + sizeof(hci_event_hdr_t), payload, size);
|
||||||
ctrl.SetRetVal(sizeof(hci_event_hdr_t) + size);
|
ctrl.ios_request.SetReturnValue(sizeof(hci_event_hdr_t) + size);
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(ctrl.m_cmd_address);
|
WII_IPC_HLE_Interface::EnqueueReply(ctrl.ios_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the red sync button is pressed, a HCI event is generated:
|
// When the red sync button is pressed, a HCI event is generated:
|
||||||
// > HCI Event: Vendor (0xff) plen 1
|
// > HCI Event: Vendor (0xff) plen 1
|
||||||
// 08
|
// 08
|
||||||
// This causes the emulated software to perform a BT inquiry and connect to found Wiimotes.
|
// This causes the emulated software to perform a BT inquiry and connect to found Wiimotes.
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(CtrlBuffer& ctrl)
|
||||||
{
|
{
|
||||||
NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet");
|
NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button pressed' (0x08) event packet");
|
||||||
const u8 payload[1] = {0x08};
|
const u8 payload[1] = {0x08};
|
||||||
|
@ -450,7 +448,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonPressedEvent(const
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent.
|
// When the red sync button is held for 10 seconds, a HCI event with payload 09 is sent.
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::FakeSyncButtonHeldEvent(CtrlBuffer& ctrl)
|
||||||
{
|
{
|
||||||
NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button held' (0x09) event packet");
|
NOTICE_LOG(WII_IPC_WIIMOTE, "Faking 'sync button held' (0x09) event packet");
|
||||||
const u8 payload[1] = {0x09};
|
const u8 payload[1] = {0x09};
|
||||||
|
@ -580,7 +578,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::CommandCallback(libusb_transfer*
|
||||||
s_showed_failed_transfer.Clear();
|
s_showed_failed_transfer.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(cmd->address, 0, CoreTiming::FromThread::NON_CPU);
|
WII_IPC_HLE_Interface::EnqueueReply(cmd->ios_request, 0, CoreTiming::FromThread::NON_CPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer* tr)
|
||||||
|
@ -624,6 +622,6 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305_real::TransferCallback(libusb_transfer*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctrl->SetRetVal(tr->actual_length);
|
ctrl->ios_request.SetReturnValue(tr->actual_length);
|
||||||
WII_IPC_HLE_Interface::EnqueueReply(ctrl->m_cmd_address, 0, CoreTiming::FromThread::NON_CPU);
|
WII_IPC_HLE_Interface::EnqueueReply(ctrl->ios_request, 0, CoreTiming::FromThread::NON_CPU);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,9 @@ public:
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305_real(u32 device_id, const std::string& device_name);
|
CWII_IPC_HLE_Device_usb_oh1_57e_305_real(u32 device_id, const std::string& device_name);
|
||||||
~CWII_IPC_HLE_Device_usb_oh1_57e_305_real() override;
|
~CWII_IPC_HLE_Device_usb_oh1_57e_305_real() override;
|
||||||
|
|
||||||
IPCCommandResult Open(u32 command_address, u32 mode) override;
|
IOSReturnCode Open(const IOSOpenRequest& request) override;
|
||||||
IPCCommandResult Close(u32 command_address, bool force) override;
|
void Close() override;
|
||||||
IPCCommandResult IOCtlV(u32 command_address) override;
|
IPCCommandResult IOCtlV(const IOSIOCtlVRequest& request) override;
|
||||||
|
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
void UpdateSyncButtonState(bool is_held) override;
|
void UpdateSyncButtonState(bool is_held) override;
|
||||||
|
@ -80,11 +80,11 @@ private:
|
||||||
void SendHCIResetCommand();
|
void SendHCIResetCommand();
|
||||||
void SendHCIDeleteLinkKeyCommand();
|
void SendHCIDeleteLinkKeyCommand();
|
||||||
bool SendHCIStoreLinkKeyCommand();
|
bool SendHCIStoreLinkKeyCommand();
|
||||||
void FakeVendorCommandReply(const CtrlBuffer& ctrl);
|
void FakeVendorCommandReply(CtrlBuffer& ctrl);
|
||||||
void FakeReadBufferSizeReply(const CtrlBuffer& ctrl);
|
void FakeReadBufferSizeReply(CtrlBuffer& ctrl);
|
||||||
void FakeSyncButtonEvent(const CtrlBuffer& ctrl, const u8* payload, u8 size);
|
void FakeSyncButtonEvent(CtrlBuffer& ctrl, const u8* payload, u8 size);
|
||||||
void FakeSyncButtonPressedEvent(const CtrlBuffer& ctrl);
|
void FakeSyncButtonPressedEvent(CtrlBuffer& ctrl);
|
||||||
void FakeSyncButtonHeldEvent(const CtrlBuffer& ctrl);
|
void FakeSyncButtonHeldEvent(CtrlBuffer& ctrl);
|
||||||
|
|
||||||
void LoadLinkKeys();
|
void LoadLinkKeys();
|
||||||
void SaveLinkKeys();
|
void SaveLinkKeys();
|
||||||
|
|
|
@ -12,11 +12,11 @@ namespace Core
|
||||||
void DisplayMessage(const std::string& message, int time_in_ms);
|
void DisplayMessage(const std::string& message, int time_in_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPCCommandResult CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(u32 command_address, u32 mode)
|
IOSReturnCode CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::Open(const IOSOpenRequest& request)
|
||||||
{
|
{
|
||||||
PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb."
|
PanicAlertT("Bluetooth passthrough mode is enabled, but Dolphin was built without libusb."
|
||||||
" Passthrough mode cannot be used.");
|
" Passthrough mode cannot be used.");
|
||||||
return GetNoReply();
|
return IPC_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::DoState(PointerWrap& p)
|
void CWII_IPC_HLE_Device_usb_oh1_57e_305_stub::DoState(PointerWrap& p)
|
||||||
|
|
|
@ -16,11 +16,10 @@ class CWII_IPC_HLE_Device_usb_oh1_57e_305_stub final
|
||||||
: public CWII_IPC_HLE_Device_usb_oh1_57e_305_base
|
: public CWII_IPC_HLE_Device_usb_oh1_57e_305_base
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(u32 device_id, const std::string& device_name)
|
CWII_IPC_HLE_Device_usb_oh1_57e_305_stub(const u32 device_id, const std::string& device_name)
|
||||||
: CWII_IPC_HLE_Device_usb_oh1_57e_305_base(device_id, device_name)
|
: CWII_IPC_HLE_Device_usb_oh1_57e_305_base(device_id, device_name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
~CWII_IPC_HLE_Device_usb_oh1_57e_305_stub() override {}
|
IOSReturnCode Open(const IOSOpenRequest& request) override;
|
||||||
IPCCommandResult Open(u32 command_address, u32 mode) override;
|
|
||||||
void DoState(PointerWrap& p) override;
|
void DoState(PointerWrap& p) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,7 +71,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
|
||||||
static std::thread g_save_thread;
|
static std::thread g_save_thread;
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
static const u32 STATE_VERSION = 68; // Last changed in PR 4638
|
static const u32 STATE_VERSION = 69; // Last changed in PR 4661
|
||||||
|
|
||||||
// Maps savestate versions to Dolphin versions.
|
// Maps savestate versions to Dolphin versions.
|
||||||
// Versions after 42 don't need to be added to this list,
|
// Versions after 42 don't need to be added to this list,
|
||||||
|
|
Loading…
Reference in New Issue