Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Pseudo-Third-Party Controller Support #51

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
82 changes: 81 additions & 1 deletion jctool/jctool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <functional>
#include <memory>
#include <string>
#include <cstring>
// #define NOMINMAX
#include <Windows.h>

Expand All @@ -20,6 +21,7 @@ using namespace CppWinFormJoy;
#pragma comment(lib, "SetupAPI")

bool enable_traffic_dump = false;
bool enable_hid_listings = false;

hid_device *handle;
hid_device *handle_l;
Expand Down Expand Up @@ -1402,7 +1404,7 @@ int get_raw_ir_image(u8 show_status) {
u8 buf[49];
u8 buf_reply[0x170];
u8 *buf_image = new u8[19 * 4096]; // 8bpp greyscale image.
uint16_t bad_signal = 0;
uint16_t bad_signal = 0;
int error_reading = 0;
float noise_level = 0.0f;
int avg_intensity_percent = 0.0f;
Expand Down Expand Up @@ -2912,8 +2914,48 @@ int test_chamber() {
return 0;
}

void output_hid_device_info_list() {
// Enumerate and output the HID devices on the system
hid_device_info* devs, * cur_dev;
devs = hid_enumerate(0x0, 0x0);
cur_dev = devs;
std::wstring dev_info_list;
while (cur_dev) {
std::wstringstream dev_info;
if (cur_dev->product_string || cur_dev->manufacturer_string || cur_dev->serial_number) {
wchar_t* product_string = cur_dev->product_string ? cur_dev->product_string : L"Unknown Product" ;
wchar_t* manufacturer_string = cur_dev->manufacturer_string ? cur_dev->manufacturer_string : L"Unknown Manufacturer" ;
wchar_t* serial_number = cur_dev->serial_number ? cur_dev->serial_number : L"Unknown Serial Number";

dev_info << std::setfill(L'0') << std::hex;
dev_info << L"HID Device: 0x" << std::setw(4) << cur_dev->product_id << L" \"" << product_string << L'"' << L'\n';
dev_info << L"\tvendor = 0x" << std::setw(4) << cur_dev->vendor_id << L" \"" << manufacturer_string << L'"' << L'\n';
dev_info << L"\trelease = " << std::dec << cur_dev->release_number << L'\n';
dev_info << L"\tserial = " << serial_number << std::hex << L'\n';
dev_info << L"\tusage = 0x" << std::setw(4) << cur_dev->usage << L" page: 0x" << cur_dev->usage_page << L'\n';
dev_info << L"\n" << cur_dev->path;

std::wstring dev_info_str = dev_info.str();
System::String^ dev_info_str_handle = System::String(dev_info_str.c_str(), 0, dev_info_str.length()).ToString();

if (MessageBox::Show(dev_info_str_handle,
L"CTCaer's Joy-Con Toolkit - HID Device Info Report",
MessageBoxButtons::OKCancel, MessageBoxIcon::Information) == System::Windows::Forms::DialogResult::Cancel) {
break;
}
}
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);
}

int device_connection(){
if (check_connection_ok) {
if (enable_hid_listings) {
output_hid_device_info_list();
enable_hid_listings = false;
}

handle_ok = 0;
// Joy-Con (L)
if (handle = hid_open(0x57e, 0x2006, nullptr)) {
Expand All @@ -2932,6 +2974,39 @@ int device_connection(){
}
// Nothing found
else {
// Check for third-party controllers
hid_device_info* devs = hid_enumerate(0x0, 0x0);
hid_device_info* cur_dev = devs;
while (cur_dev) {
std::wstring product_string = cur_dev->product_string ? cur_dev->product_string : L"Unknown Product";
std::wstring manufacturer_string = cur_dev->manufacturer_string ? cur_dev->manufacturer_string : L"Unknown Manufacturer";
std::wstring serial_number = cur_dev->serial_number ? cur_dev->serial_number : L"Unknown Serial Number";

if (product_string == L"Wireless Gamepad" && manufacturer_string == L"Nintendo" && cur_dev->usage == 0x0005) {
//if (true) {
std::wstring third_party_warning = L"A potential third-party device has been detected:\n\n\t"
+ product_string + L" : " + manufacturer_string + L"\n\n"
+ L"Editing could be potentially unstable. Would you like to use this device anyways?";
if (MessageBox::Show(System::String(third_party_warning.c_str(), 0, third_party_warning.length()).ToString(),
L"CTCaer's Joy-Con Toolkit - Third-Party Device Detected",
MessageBoxButtons::YesNo, MessageBoxIcon::Warning) == System::Windows::Forms::DialogResult::Yes)
{
if (handle = hid_open(cur_dev->product_id, cur_dev->vendor_id, cur_dev->serial_number)) {
// Maybe do some more tests here just to double check
hid_free_enumeration(devs);
handle_ok = 3;
return handle_ok;
}
else {
MessageBox::Show(L"Could not obtain the device.\nIt's usage has been aborted.",
L"CTCaer's Joy-Con Toolkit - Third-Party Device Connection Failed",
MessageBoxButtons::OK, MessageBoxIcon::Stop);
}
}
}
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);
return 0;
}
}
Expand Down Expand Up @@ -2965,6 +3040,11 @@ int Main(array<String^>^ args) {
}
*/
check_connection_ok = true;
if (args->Length > 0) {
if (args[0] == "-l") {
enable_hid_listings = true; // List all connected HID device information for first connection check
}
}
while (!device_connection()) {
if (MessageBox::Show(
L"The device is not paired or the device was disconnected!\n\n" +
Expand Down