Created
December 6, 2019 11:24
-
-
Save argonism/baf72f44d2bd4459957486511d391ce4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define JOYCON_L_PRODUCT_ID 8198 | |
#define JOYCON_R_PRODUCT_ID 8199 | |
#define MAX_JOYSTICKS_NUM 16 | |
#include <hidapi.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <iostream> | |
#include <chrono> | |
#include <array> | |
void SendSubcommand(hid_device *dev, uint8_t command, uint8_t data[], int len, int* globalCount) { | |
uint8_t buf[0x40]; memset(buf, 0x0, size_t(0x40)); | |
buf[0] = 1; // 0x10 for rumble only | |
buf[1] = *globalCount; // Increment by 1 for each packet sent. It loops in 0x0 - 0xF range. | |
if (*globalCount == 0xf0) { | |
*globalCount = 0x00; | |
} else { | |
*globalCount++; | |
} | |
buf[10] = command; | |
memcpy(buf + 11, data, len); | |
hid_write(dev, buf, 0x40); | |
} | |
std::array<hid_device*, MAX_JOYSTICKS_NUM> RefreshConnectedState() | |
{ | |
hid_init(); | |
std::array<hid_device*, MAX_JOYSTICKS_NUM> handler; | |
// hidハンドラーの取得 | |
hid_device_info *device = hid_enumerate(0, 0); | |
const char *path; | |
int i = 0; | |
while (device) | |
{ | |
path = device->path; | |
if ( device->product_id == JOYCON_L_PRODUCT_ID || device->product_id == JOYCON_R_PRODUCT_ID) | |
{ | |
printf("\nproduct_id: %ls\n", device->product_string); | |
printf("\npath: %s\n", device->path); | |
printf("%hu, %hu, %ls\n", device->vendor_id, device->product_id, device->serial_number); | |
// hid_device *dev = hid_open_ref(device->dev_ref); | |
hid_device *dev = hid_open_path(device->path); | |
if (dev) | |
{ | |
hid_set_nonblocking(dev, 1); | |
printf("open devise: %ls\n", device->product_string); | |
hid_set_nonblocking(dev, 1); | |
handler[i] = dev; | |
printf("set hid_device: %ls\n", device->product_string); | |
} | |
else | |
{ | |
printf("fail to hid open\n"); | |
} | |
i++; | |
} | |
device = device->next; | |
} | |
hid_free_enumeration(device); | |
return handler; | |
}; | |
void light_up(hid_device* dev, uint8_t* data, int globalCount, bool increase) { | |
if (increase) { | |
if (data[0] == 0x08) { | |
data[0] = 0x01; | |
} else { | |
data[0] *= 2; | |
} | |
} else { | |
if (data[0] == 0x01) { | |
data[0] = 0x08; | |
} else { | |
data[0] /= 2; | |
} | |
} | |
SendSubcommand(dev, 0x30, data, 1, &globalCount); | |
} | |
int main() | |
{ | |
int globalCount = 0; | |
std::array<hid_device*, MAX_JOYSTICKS_NUM> handler = RefreshConnectedState(); | |
std::chrono::system_clock::time_point start, end; | |
start = std::chrono::system_clock::now(); | |
end = std::chrono::system_clock::now(); | |
uint8_t data[0x01]; | |
uint8_t rep_id[0x01]; | |
data[0] = 0x01; | |
printf("aaa"); | |
// 0x03番のサブコマンドに、0x01を送信します。 | |
// ランプはビットフラグで、4桁。ランプの一番上から10進数で 1, 2, 4, 8 と対応しています。 | |
rep_id[0] = 0x3F; | |
for (int i=0; i <= 1; i++) { | |
hid_set_nonblocking(handler[i], 0); | |
SendSubcommand(handler[i], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[i], 0x03, rep_id, 1, &globalCount); | |
} | |
// read input report | |
uint8_t buff[0x40]; memset(buff, 0x40, size_t(0x40)); | |
// 読み込むサイズを指定。 | |
size_t size = 49; | |
while (true) | |
{ | |
// if (std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() <= 100) | |
// { | |
// end = std::chrono::system_clock::now(); | |
// continue; | |
// } | |
// input report を受けとる。 | |
// for (int i=0; i <= 2; i++) { | |
// } | |
int ret = hid_read(handler[0], buff, size); | |
// input report の id が 0x3F のものに絞る。 | |
if (*buff != 0x3F) | |
{ | |
continue; | |
} | |
// input report の id を表示。 | |
printf("\ninput report id: %d\n", *buff); | |
// ボタンのビットビットフィールドを表示。 | |
printf("button byte 1: %d\n", buff[1]); | |
printf("button byte 2: %d\n", buff[1]); | |
if (buff[3] == 0x02) | |
{ | |
printf("in a buff[1"); | |
light_up(handler[1], data, globalCount, true); | |
} | |
else if (buff[3] == 0x06) | |
{ | |
light_up(handler[1], data, globalCount, false); | |
} | |
// start = std::chrono::system_clock::now(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment