mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
BTEmu: Fix home menu inquiry assigning multiple wii remotes to wrong slots.
This commit is contained in:
@ -394,7 +394,7 @@ void BluetoothEmu::ACLPool::WriteToEndpoint(const USB::V0BulkMessage& endpoint)
|
|||||||
m_ios.EnqueueIPCReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size);
|
m_ios.EnqueueIPCReply(endpoint.ios_request, sizeof(hci_acldata_hdr_t) + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BluetoothEmu::SendEventInquiryComplete()
|
bool BluetoothEmu::SendEventInquiryComplete(u8 num_responses)
|
||||||
{
|
{
|
||||||
SQueuedEvent event(sizeof(SHCIEventInquiryComplete), 0);
|
SQueuedEvent event(sizeof(SHCIEventInquiryComplete), 0);
|
||||||
|
|
||||||
@ -402,6 +402,7 @@ bool BluetoothEmu::SendEventInquiryComplete()
|
|||||||
inquiry_complete->EventType = HCI_EVENT_INQUIRY_COMPL;
|
inquiry_complete->EventType = HCI_EVENT_INQUIRY_COMPL;
|
||||||
inquiry_complete->PayloadLength = sizeof(SHCIEventInquiryComplete) - 2;
|
inquiry_complete->PayloadLength = sizeof(SHCIEventInquiryComplete) - 2;
|
||||||
inquiry_complete->EventStatus = 0x00;
|
inquiry_complete->EventStatus = 0x00;
|
||||||
|
inquiry_complete->num_responses = num_responses;
|
||||||
|
|
||||||
AddEventToQueue(event);
|
AddEventToQueue(event);
|
||||||
|
|
||||||
@ -412,48 +413,54 @@ bool BluetoothEmu::SendEventInquiryComplete()
|
|||||||
|
|
||||||
bool BluetoothEmu::SendEventInquiryResponse()
|
bool BluetoothEmu::SendEventInquiryResponse()
|
||||||
{
|
{
|
||||||
static_assert(sizeof(SHCIEventInquiryResult) - 2 + (MAX_BBMOTES * sizeof(hci_inquiry_response)) <
|
// We only respond with the first discoverable remote.
|
||||||
256);
|
// The Wii instructs users to press 1+2 in the desired play order.
|
||||||
|
// Responding with all remotes at once can place them in undesirable slots.
|
||||||
|
// Additional scans will connect each remote in the proper order.
|
||||||
|
constexpr u8 num_responses = 1;
|
||||||
|
|
||||||
SQueuedEvent event(static_cast<u32>(sizeof(SHCIEventInquiryResult) +
|
static_assert(
|
||||||
m_wiimotes.size() * sizeof(hci_inquiry_response)),
|
sizeof(SHCIEventInquiryResult) - 2 + (num_responses * sizeof(hci_inquiry_response)) < 256);
|
||||||
0);
|
|
||||||
|
|
||||||
SHCIEventInquiryResult* inquiry_result = (SHCIEventInquiryResult*)event.buffer;
|
const auto iter = std::find_if(m_wiimotes.begin(), m_wiimotes.end(),
|
||||||
|
std::mem_fn(&WiimoteDevice::IsInquiryScanEnabled));
|
||||||
inquiry_result->EventType = HCI_EVENT_INQUIRY_RESULT;
|
if (iter == m_wiimotes.end())
|
||||||
inquiry_result->num_responses = 0;
|
|
||||||
|
|
||||||
for (size_t i = 0; i != m_wiimotes.size(); ++i)
|
|
||||||
{
|
{
|
||||||
if (!m_wiimotes[i]->IsInquiryScanEnabled())
|
// No remotes are discoverable.
|
||||||
continue;
|
SendEventInquiryComplete(0);
|
||||||
|
return false;
|
||||||
++inquiry_result->num_responses;
|
|
||||||
|
|
||||||
u8* buffer = event.buffer + sizeof(SHCIEventInquiryResult) + i * sizeof(hci_inquiry_response);
|
|
||||||
hci_inquiry_response* response = (hci_inquiry_response*)buffer;
|
|
||||||
|
|
||||||
response->bdaddr = m_wiimotes[i]->GetBD();
|
|
||||||
std::copy_n(m_wiimotes[i]->GetClass().begin(), HCI_CLASS_SIZE, response->uclass);
|
|
||||||
|
|
||||||
response->page_scan_rep_mode = 1;
|
|
||||||
response->page_scan_period_mode = 0;
|
|
||||||
response->page_scan_mode = 0;
|
|
||||||
response->clock_offset = 0x3818;
|
|
||||||
|
|
||||||
DEBUG_LOG(IOS_WIIMOTE, "Event: Send Fake Inquiry of one controller");
|
|
||||||
DEBUG_LOG(IOS_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", response->bdaddr[0],
|
|
||||||
response->bdaddr[1], response->bdaddr[2], response->bdaddr[3], response->bdaddr[4],
|
|
||||||
response->bdaddr[5]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& wiimote = *iter;
|
||||||
|
|
||||||
|
SQueuedEvent event(
|
||||||
|
u32(sizeof(SHCIEventInquiryResult) + num_responses * sizeof(hci_inquiry_response)), 0);
|
||||||
|
|
||||||
|
const auto inquiry_result = reinterpret_cast<SHCIEventInquiryResult*>(event.buffer);
|
||||||
|
inquiry_result->EventType = HCI_EVENT_INQUIRY_RESULT;
|
||||||
|
inquiry_result->num_responses = num_responses;
|
||||||
|
|
||||||
|
u8* const buffer = event.buffer + sizeof(SHCIEventInquiryResult);
|
||||||
|
const auto response = reinterpret_cast<hci_inquiry_response*>(buffer);
|
||||||
|
|
||||||
|
response->bdaddr = wiimote->GetBD();
|
||||||
|
response->page_scan_rep_mode = 1;
|
||||||
|
response->page_scan_period_mode = 0;
|
||||||
|
response->page_scan_mode = 0;
|
||||||
|
std::copy_n(wiimote->GetClass().begin(), HCI_CLASS_SIZE, response->uclass);
|
||||||
|
response->clock_offset = 0x3818;
|
||||||
|
|
||||||
|
DEBUG_LOG(IOS_WIIMOTE, "Event: Send Fake Inquiry of one controller");
|
||||||
|
DEBUG_LOG(IOS_WIIMOTE, " bd: %02x:%02x:%02x:%02x:%02x:%02x", response->bdaddr[0],
|
||||||
|
response->bdaddr[1], response->bdaddr[2], response->bdaddr[3], response->bdaddr[4],
|
||||||
|
response->bdaddr[5]);
|
||||||
|
|
||||||
inquiry_result->PayloadLength =
|
inquiry_result->PayloadLength =
|
||||||
u8(sizeof(SHCIEventInquiryResult) - 2 +
|
u8(sizeof(SHCIEventInquiryResult) - 2 +
|
||||||
(inquiry_result->num_responses * sizeof(hci_inquiry_response)));
|
(inquiry_result->num_responses * sizeof(hci_inquiry_response)));
|
||||||
|
|
||||||
AddEventToQueue(event);
|
AddEventToQueue(event);
|
||||||
|
SendEventInquiryComplete(num_responses);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1109,7 +1116,6 @@ void BluetoothEmu::CommandInquiry(const u8* input)
|
|||||||
|
|
||||||
SendEventCommandStatus(HCI_CMD_INQUIRY);
|
SendEventCommandStatus(HCI_CMD_INQUIRY);
|
||||||
SendEventInquiryResponse();
|
SendEventInquiryResponse();
|
||||||
SendEventInquiryComplete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BluetoothEmu::CommandInquiryCancel(const u8* input)
|
void BluetoothEmu::CommandInquiryCancel(const u8* input)
|
||||||
|
@ -118,7 +118,7 @@ private:
|
|||||||
bool SendEventCommandStatus(u16 opcode);
|
bool SendEventCommandStatus(u16 opcode);
|
||||||
void SendEventCommandComplete(u16 opcode, const void* data, u32 data_size);
|
void SendEventCommandComplete(u16 opcode, const void* data, u32 data_size);
|
||||||
bool SendEventInquiryResponse();
|
bool SendEventInquiryResponse();
|
||||||
bool SendEventInquiryComplete();
|
bool SendEventInquiryComplete(u8 num_responses);
|
||||||
bool SendEventRemoteNameReq(const bdaddr_t& bd);
|
bool SendEventRemoteNameReq(const bdaddr_t& bd);
|
||||||
bool SendEventRequestConnection(const WiimoteDevice& wiimote);
|
bool SendEventRequestConnection(const WiimoteDevice& wiimote);
|
||||||
bool SendEventConnectionComplete(const bdaddr_t& bd, u8 status);
|
bool SendEventConnectionComplete(const bdaddr_t& bd, u8 status);
|
||||||
|
@ -72,7 +72,7 @@ WiimoteDevice::WiimoteDevice(Device::BluetoothEmu* host, int number, bdaddr_t bd
|
|||||||
|
|
||||||
// UGLY: This prevents an OSD message in SetSource -> Activate.
|
// UGLY: This prevents an OSD message in SetSource -> Activate.
|
||||||
if (hid_source)
|
if (hid_source)
|
||||||
m_baseband_state = BasebandState::RequestConnection;
|
SetBasebandState(BasebandState::RequestConnection);
|
||||||
|
|
||||||
SetSource(hid_source);
|
SetSource(hid_source);
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ void WiimoteDevice::DoState(PointerWrap& p)
|
|||||||
p.Do(m_link_key);
|
p.Do(m_link_key);
|
||||||
p.Do(m_name);
|
p.Do(m_name);
|
||||||
p.Do(m_channels);
|
p.Do(m_channels);
|
||||||
p.Do(m_last_connect_request_counter);
|
p.Do(m_connection_request_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 WiimoteDevice::GetNumber() const
|
u32 WiimoteDevice::GetNumber() const
|
||||||
@ -133,6 +133,9 @@ bool WiimoteDevice::IsPageScanEnabled() const
|
|||||||
|
|
||||||
void WiimoteDevice::SetBasebandState(BasebandState new_state)
|
void WiimoteDevice::SetBasebandState(BasebandState new_state)
|
||||||
{
|
{
|
||||||
|
// Prevent button press from immediately causing connection attempts.
|
||||||
|
m_connection_request_counter = ::Wiimote::UPDATE_FREQ;
|
||||||
|
|
||||||
const bool was_connected = IsConnected();
|
const bool was_connected = IsConnected();
|
||||||
|
|
||||||
m_baseband_state = new_state;
|
m_baseband_state = new_state;
|
||||||
@ -230,11 +233,7 @@ void WiimoteDevice::Activate(bool connect)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
{
|
|
||||||
// Prevent button press from immediately causing a connection attempt.
|
|
||||||
m_last_connect_request_counter = ::Wiimote::UPDATE_FREQ;
|
|
||||||
Core::DisplayMessage(fmt::format(message, GetNumber() + 1), CONNECTION_MESSAGE_TIME);
|
Core::DisplayMessage(fmt::format(message, GetNumber() + 1), CONNECTION_MESSAGE_TIME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WiimoteDevice::EventConnectionRequest()
|
bool WiimoteDevice::EventConnectionRequest()
|
||||||
@ -344,14 +343,14 @@ void WiimoteDevice::Update()
|
|||||||
|
|
||||||
void WiimoteDevice::UpdateInput()
|
void WiimoteDevice::UpdateInput()
|
||||||
{
|
{
|
||||||
if (m_last_connect_request_counter)
|
if (m_connection_request_counter)
|
||||||
--m_last_connect_request_counter;
|
--m_connection_request_counter;
|
||||||
|
|
||||||
if (!IsSourceValid())
|
if (!IsSourceValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Allow button press to trigger activation once per second.
|
// Allow button press to trigger activation after a second of no connection activity.
|
||||||
if (!m_last_connect_request_counter && m_baseband_state == BasebandState::Inactive)
|
if (!m_connection_request_counter && m_baseband_state == BasebandState::Inactive)
|
||||||
{
|
{
|
||||||
if (Wiimote::NetPlay_GetButtonPress(GetNumber(), m_hid_source->IsButtonPressed()))
|
if (Wiimote::NetPlay_GetButtonPress(GetNumber(), m_hid_source->IsButtonPressed()))
|
||||||
Activate(true);
|
Activate(true);
|
||||||
|
@ -130,7 +130,7 @@ private:
|
|||||||
LinkKeyType m_link_key;
|
LinkKeyType m_link_key;
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
ChannelMap m_channels;
|
ChannelMap m_channels;
|
||||||
u8 m_last_connect_request_counter = 0;
|
u8 m_connection_request_counter = 0;
|
||||||
|
|
||||||
void SetBasebandState(BasebandState);
|
void SetBasebandState(BasebandState);
|
||||||
|
|
||||||
|
@ -2652,6 +2652,7 @@ struct SHCIEventInquiryComplete
|
|||||||
u8 EventType;
|
u8 EventType;
|
||||||
u8 PayloadLength;
|
u8 PayloadLength;
|
||||||
u8 EventStatus;
|
u8 EventStatus;
|
||||||
|
u8 num_responses;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SHCIEventReadClockOffsetComplete
|
struct SHCIEventReadClockOffsetComplete
|
||||||
|
Reference in New Issue
Block a user