Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BuildMacOSUniversalBinary.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ def build(config):
"-DCMAKE_PREFIX_PATH="+prefix_path,
"-DCMAKE_SYSTEM_PROCESSOR="+arch,
"-DCMAKE_IGNORE_PATH="+ignore_path,
"-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0.0",
"-DMACOS_CODE_SIGNING_IDENTITY="
+ config["codesign_identity"],
'-DMACOS_CODE_SIGNING="ON"',
Expand Down
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
option(ENABLE_VTUNE "Enable Intel VTune integration for JIT code." OFF)

if(NOT ANDROID)
option(ENABLE_HWDB "Enables the udev hardware database" ON)
option(ENABLE_EVDEV "Enables the evdev controller backend" ON)
endif()
endif()
Expand Down Expand Up @@ -571,6 +572,16 @@ if(OPROFILING)
endif()
endif()

if(ENABLE_HWDB)
find_package(LIBUDEV REQUIRED)
if(LIBUDEV_FOUND)
message(STATUS "libudev found, enabling hardware database")
add_definitions(-DHAVE_LIBUDEV=1)
else()
message(FATAL_ERROR "Couldn't find libudev. Can't build hardware database.\nDisable ENABLE_HWDB if you wish to build without hardware database support")
endif()
endif()

if(ENABLE_EVDEV)
find_package(LIBUDEV REQUIRED)
find_package(LIBEVDEV REQUIRED)
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/AchievementManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1318,7 +1318,7 @@ u32 AchievementManager::MemoryPeeker(u32 address, u8* buffer, u32 num_bytes, rc_
if (instance.m_dll_found)
{
std::lock_guard lg{instance.m_memory_lock};
if (u64(address) + num_bytes >= instance.m_cloned_memory.size())
if (u64(address) + num_bytes > instance.m_cloned_memory.size())
{
ERROR_LOG_FMT(ACHIEVEMENTS,
"Attempt to read past memory size: size {} address {} write length {}",
Expand Down
8 changes: 6 additions & 2 deletions Source/Core/Core/AchievementManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ class AchievementManager

#include <string>

#include "Common/CommonTypes.h"

namespace ActionReplay
{
struct ARCode;
Expand All @@ -333,12 +335,14 @@ class AchievementManager

constexpr bool IsHardcoreModeActive() { return false; }

constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id)
constexpr bool CheckApprovedGeckoCode(const Gecko::GeckoCode& code, const std::string& game_id,
u16 revision)
{
return true;
};

constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id)
constexpr bool CheckApprovedARCode(const ActionReplay::ARCode& code, const std::string& game_id,
u16 revision)
{
return true;
};
Expand Down
2 changes: 0 additions & 2 deletions Source/Core/Core/Boot/Boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,6 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
const u32 ipl_hash = Common::ComputeCRC32(data.data(), data.size());
bool known_ipl = false;
bool pal_ipl = false;
bool triforce_ipl = false;
switch (ipl_hash)
{
case NTSC_v1_0:
Expand All @@ -442,7 +441,6 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
break;
case Triforce:
known_ipl = true;
triforce_ipl = true;
default:
PanicAlertFmtT("The IPL file is not a known good dump. (CRC32: {0:x})", ipl_hash);
break;
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/Core/IOS/Network/IP/Top.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ static std::optional<DefaultInterface> GetSystemDefaultInterface()
};

auto get_addr = [](const sockaddr* addr) {
return reinterpret_cast<const sockaddr_in*>(addr)->sin_addr.s_addr;
return reinterpret_cast<const sockaddr_in*>(addr)->sin_addr;
};

const auto default_interface_address = get_default_address();
Expand All @@ -430,12 +430,12 @@ static std::optional<DefaultInterface> GetSystemDefaultInterface()
for (const ifaddrs* iface = iflist; iface; iface = iface->ifa_next)
{
if (iface->ifa_addr && iface->ifa_addr->sa_family == AF_INET &&
get_addr(iface->ifa_addr) == default_interface_address->s_addr)
get_addr(iface->ifa_addr).s_addr == default_interface_address->s_addr)
{
// this isnt fully correct, but this will make calls to get the routing table at least return
// the gateway
if (routing_table.empty())
routing_table = {{0, 0, 0, get_addr(iface->ifa_dstaddr)}};
routing_table = {{0, {}, {}, get_addr(iface->ifa_dstaddr)}};

return DefaultInterface{get_addr(iface->ifa_addr), get_addr(iface->ifa_netmask),
get_addr(iface->ifa_broadaddr), routing_table};
Expand Down
75 changes: 53 additions & 22 deletions Source/Core/Core/IOS/USB/Bluetooth/BTReal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "Core/Core.h"
#include "Core/HW/Memmap.h"
#include "Core/IOS/Device.h"
#include "Core/IOS/USB/Host.h"
#include "Core/System.h"
#include "VideoCommon/OnScreenDisplay.h"

Expand All @@ -38,27 +39,17 @@ constexpr u8 REQUEST_TYPE = static_cast<u8>(LIBUSB_ENDPOINT_OUT) |
static_cast<u8>(LIBUSB_REQUEST_TYPE_CLASS) |
static_cast<u8>(LIBUSB_RECIPIENT_INTERFACE);

static bool IsWantedDevice(const libusb_device_descriptor& descriptor)
{
const int vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
const int pid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID);
if (vid == -1 || pid == -1)
return true;
return descriptor.idVendor == vid && descriptor.idProduct == pid;
}

static bool IsBluetoothDevice(const libusb_interface_descriptor& descriptor)
static bool IsBluetoothDevice(const libusb_device_descriptor& descriptor)
{
constexpr u8 SUBCLASS = 0x01;
constexpr u8 PROTOCOL_BLUETOOTH = 0x01;
if (Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID) != -1 &&
Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID) != -1)
{
return true;
}
return descriptor.bInterfaceClass == LIBUSB_CLASS_WIRELESS &&
descriptor.bInterfaceSubClass == SUBCLASS &&
descriptor.bInterfaceProtocol == PROTOCOL_BLUETOOTH;
// Some devices misreport their class, so we avoid relying solely on descriptor checks and allow
// users to specify their own VID/PID.
return BluetoothRealDevice::IsConfiguredBluetoothDevice(descriptor.idVendor,
descriptor.idProduct) ||
(descriptor.bDeviceClass == LIBUSB_CLASS_WIRELESS &&
descriptor.bDeviceSubClass == SUBCLASS &&
descriptor.bDeviceProtocol == PROTOCOL_BLUETOOTH);
}

BluetoothRealDevice::BluetoothRealDevice(EmulationKernel& ios, const std::string& device_name)
Expand All @@ -82,6 +73,13 @@ BluetoothRealDevice::~BluetoothRealDevice()
SaveLinkKeys();
}

bool BluetoothRealDevice::IsConfiguredBluetoothDevice(u16 vid, u16 pid)
{
const int configured_vid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_VID);
const int configured_pid = Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_PID);
return configured_vid == vid && configured_pid == pid;
}

std::optional<IPCReply> BluetoothRealDevice::Open(const OpenRequest& request)
{
if (!m_context.IsValid())
Expand All @@ -101,10 +99,7 @@ std::optional<IPCReply> BluetoothRealDevice::Open(const OpenRequest& request)
return true;
}

const libusb_interface& interface = config_descriptor->interface[INTERFACE];
const libusb_interface_descriptor& descriptor = interface.altsetting[0];
if (IsBluetoothDevice(descriptor) && IsWantedDevice(device_descriptor) &&
OpenDevice(device_descriptor, device))
if (IsBluetoothDevice(device_descriptor) && OpenDevice(device_descriptor, device))
{
unsigned char manufacturer[50] = {}, product[50] = {}, serial_number[50] = {};
const int manufacturer_ret = libusb_get_string_descriptor_ascii(
Expand Down Expand Up @@ -677,6 +672,42 @@ bool BluetoothRealDevice::OpenDevice(const libusb_device_descriptor& device_desc
return true;
}

std::vector<BluetoothRealDevice::BluetoothDeviceInfo> BluetoothRealDevice::ListDevices()
{
std::vector<BluetoothDeviceInfo> device_list;
LibusbUtils::Context context;

if (!context.IsValid())
return {};

int result = context.GetDeviceList([&device_list](libusb_device* device) {
libusb_device_descriptor desc;

auto [config_ret, config] = LibusbUtils::MakeConfigDescriptor(device, 0);
if (config_ret != LIBUSB_SUCCESS)
return true;

if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
return true;

if (IsBluetoothDevice(desc))
{
const std::string device_name =
USBHost::GetDeviceNameFromVIDPID(desc.idVendor, desc.idProduct);
device_list.push_back({desc.idVendor, desc.idProduct, device_name});
}
return true;
});

if (result < 0)
{
ERROR_LOG_FMT(IOS_USB, "Failed to get device list: {}", LibusbUtils::ErrorWrap(result));
return device_list;
}

return device_list;
}

// The callbacks are called from libusb code on a separate thread.
void BluetoothRealDevice::HandleCtrlTransfer(libusb_transfer* tr)
{
Expand Down
11 changes: 11 additions & 0 deletions Source/Core/Core/IOS/USB/Bluetooth/BTReal.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ class BluetoothRealDevice final : public BluetoothBaseDevice
void HandleCtrlTransfer(libusb_transfer* finished_transfer);
void HandleBulkOrIntrTransfer(libusb_transfer* finished_transfer);

static bool IsConfiguredBluetoothDevice(u16 vid, u16 pid);

struct BluetoothDeviceInfo
{
u16 vid;
u16 pid;
std::string name;
};

static std::vector<BluetoothDeviceInfo> ListDevices();

private:
static constexpr u8 INTERFACE = 0x00;
// Arbitrarily chosen value that allows emulated software to send commands often enough
Expand Down
70 changes: 70 additions & 0 deletions Source/Core/Core/IOS/USB/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
#include <string>
#include <utility>

#ifdef __LIBUSB__
#include <libusb.h>
#endif

#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif

#include "Common/ChunkFile.h"
#include "Common/CommonTypes.h"
#include "Common/Logging/Log.h"
Expand Down Expand Up @@ -45,6 +53,68 @@ std::optional<IPCReply> USBHost::Open(const OpenRequest& request)
return IPCReply(IPC_SUCCESS);
}

std::string USBHost::GetDeviceNameFromVIDPID(u16 vid, u16 pid)
{
std::string device_name;
#ifdef __LIBUSB__
LibusbUtils::Context context;

if (!context.IsValid())
return device_name;

context.GetDeviceList([&device_name, vid, pid](libusb_device* device) {
libusb_device_descriptor desc;

if (libusb_get_device_descriptor(device, &desc) != LIBUSB_SUCCESS)
return true;

if (desc.idVendor == vid && desc.idProduct == pid)
{
libusb_device_handle* handle;
if (libusb_open(device, &handle) == LIBUSB_SUCCESS)
{
unsigned char buffer[256];
if (desc.iProduct &&
libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, sizeof(buffer)) > 0)
{
device_name = reinterpret_cast<char*>(buffer);
libusb_close(handle);
}
}
return false;
}
return true;
});

if (!device_name.empty())
return device_name;
#endif
#ifdef HAVE_LIBUDEV
udev* udev = udev_new();
if (!udev)
return device_name;

udev_hwdb* hwdb = udev_hwdb_new(udev);
if (hwdb)
{
const std::string modalias = fmt::format("usb:v{:04X}p{:04X}*", vid, pid);
udev_list_entry* entries = udev_hwdb_get_properties_list_entry(hwdb, modalias.c_str(), 0);

if (entries)
{
udev_list_entry* device_name_entry =
udev_list_entry_get_by_name(entries, "ID_MODEL_FROM_DATABASE");
if (device_name_entry)
{
device_name = udev_list_entry_get_value(device_name_entry);
}
}
udev_hwdb_unref(hwdb);
}
#endif
return device_name;
}

void USBHost::DoState(PointerWrap& p)
{
Device::DoState(p);
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/IOS/USB/Host.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class USBHost : public EmulationDevice
void DoState(PointerWrap& p) override;

void OnDevicesChanged(const USBScanner::DeviceMap& new_devices);
static std::string GetDeviceNameFromVIDPID(u16 vid, u16 pid);

protected:
enum class ChangeEvent
Expand Down
11 changes: 5 additions & 6 deletions Source/Core/DiscIO/DirectoryBlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(const std::stri
}

std::unique_ptr<DirectoryBlobReader> DirectoryBlobReader::Create(
std::unique_ptr<DiscIO::VolumeDisc> volume,
std::unique_ptr<VolumeDisc> volume,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback)
Expand Down Expand Up @@ -414,7 +414,7 @@ DirectoryBlobReader::DirectoryBlobReader(const std::string& game_partition_root,
}

DirectoryBlobReader::DirectoryBlobReader(
std::unique_ptr<DiscIO::VolumeDisc> volume,
std::unique_ptr<VolumeDisc> volume,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback)
Expand Down Expand Up @@ -699,7 +699,7 @@ void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition,
constexpr u32 TMD_OFFSET = 0x2c0;
constexpr u32 H3_OFFSET = 0x4000;

const std::optional<DiscIO::Partition>& wrapped_partition = partition->GetWrappedPartition();
const std::optional<Partition>& wrapped_partition = partition->GetWrappedPartition();
const std::string& partition_root = partition->GetRootDirectory();

u64 ticket_size;
Expand Down Expand Up @@ -797,8 +797,7 @@ void DirectoryBlobReader::SetPartitionHeader(DirectoryBlobPartition* partition,
partition->SetKey(ticket.GetTitleKey());
}

static void GenerateBuilderNodesFromFileSystem(const DiscIO::VolumeDisc& volume,
const DiscIO::Partition& partition,
static void GenerateBuilderNodesFromFileSystem(const VolumeDisc& volume, const Partition& partition,
std::vector<FSTBuilderNode>* nodes,
const FileInfo& parent_info)
{
Expand Down Expand Up @@ -875,7 +874,7 @@ static std::vector<u8> ExtractNodeToVector(std::vector<FSTBuilderNode>* nodes, v
}

DirectoryBlobPartition::DirectoryBlobPartition(
DiscIO::VolumeDisc* volume, const DiscIO::Partition& partition, std::optional<bool> is_wii,
VolumeDisc* volume, const Partition& partition, std::optional<bool> is_wii,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes)>& sys_callback,
const std::function<void(std::vector<FSTBuilderNode>* fst_nodes, FSTBuilderNode* dol_node)>&
fst_callback,
Expand Down
Loading