Created
December 6, 2019 09:48
-
-
Save argonism/b345f14cbdb0b21fc0aecb4d79a87323 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 to_down(uint8_t* data, uint8_t* diff, hid_device* dev, int globalCount) | |
{ | |
data[0] -= *diff; | |
printf("down\n"); | |
printf("diff: %x\n", *diff); | |
printf("data: %x\n", data[0]); | |
SendSubcommand(dev, 0x30, data, 1, &globalCount); | |
} | |
void to_up(uint8_t* data, uint8_t* diff, hid_device* dev, int globalCount) | |
{ | |
data[0] += *diff; | |
printf("up\n"); | |
printf("diff: %x\n", *diff); | |
printf("data: %x\n", data[0]); | |
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]; | |
// hid_set_nonblocking(dev, 1); | |
data[0] = 0x00; | |
// 0x03番のサブコマンドに、0x01を送信します。 | |
// ランプはビットフラグで、4桁。ランプの一番上から10進数で 1, 2, 4, 8 と対応しています。 | |
// double time; | |
// data[0] = 0x10; | |
bool down = false; | |
bool secound = false; | |
// uint8_t i = 0x00; | |
// ボタンの入力を受け付けるぞ! | |
uint8_t diff = 0x01; | |
SendSubcommand(handler[0], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[1], 0x30, data, 1, &globalCount); | |
while (true) | |
{ | |
if (std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() <= 100) | |
{ | |
end = std::chrono::system_clock::now(); | |
continue; | |
} | |
if (data[0] == 0x08 && down == false) { | |
down = true; | |
diff = 0x00; | |
data[0] = 0x08; | |
// SendSubcommand(handler[0], 0x30, data, 1, &globalCount); | |
// SendSubcommand(handler[1], 0x30, data, 1, &globalCount); | |
if (secound) { | |
secound = false; | |
uint8_t temp[0x01]; | |
temp[0] = 0x00; | |
// SendSubcommand(handler[0], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[1], 0x30, temp, 1, &globalCount); | |
// to_down(data, &diff, handler[0], globalCount); | |
} else { | |
secound = true; | |
uint8_t temp[0x01]; | |
temp[0] = 0x00; | |
// SendSubcommand(handler[1], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[0], 0x30, temp, 1, &globalCount); | |
// to_down(data, &diff, handler[1], globalCount); | |
} | |
continue; | |
} | |
else if (data[0] == 0x01 && down) { | |
down = false; | |
data[0] = 0x01; | |
diff = 0x01; | |
} | |
hid_device* dev = (secound) ? handler[1] : handler[0]; | |
if (down) { | |
to_down(data, &diff, dev, globalCount); | |
if (diff != 1) | |
diff = data[0] / 2; | |
} else { | |
to_up(data, &diff, dev, globalCount); | |
diff = data[0]; | |
} | |
// printf("awawa!: %x\n", diff); | |
start = std::chrono::system_clock::now(); | |
} | |
} |
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; | |
}; | |
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]; | |
// hid_set_nonblocking(dev, 1); | |
data[0] = 0x00; | |
// 0x03番のサブコマンドに、0x01を送信します。 | |
// ランプはビットフラグで、4桁。ランプの一番上から10進数で 1, 2, 4, 8 と対応しています。 | |
// double time; | |
// data[0] = 0x10; | |
bool down = false; | |
// uint8_t i = 0x00; | |
// ボタンの入力を受け付けるぞ! | |
uint8_t diff = 0x01; | |
SendSubcommand(handler[0], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[1], 0x30, data, 1, &globalCount); | |
while (true) | |
{ | |
if (std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count() <= 100) | |
{ | |
end = std::chrono::system_clock::now(); | |
continue; | |
} | |
if (data[0] == 0x0F) | |
{ | |
down = true; | |
} | |
else if (data[0] == 0x00) | |
{ | |
down = false; | |
} | |
if (down) | |
{ | |
data[0] = (data[0] - diff); | |
if (data[0] != 0x00) | |
diff = diff / 2; | |
} | |
else | |
{ | |
data[0] += diff; | |
if (data[0] != 0x0F) | |
diff = diff * 2; | |
} | |
printf(" %s \n", (down ? "true" : "false")); | |
printf("diff: %x\n", diff); | |
printf("data: %x\n", data[0]); | |
SendSubcommand(handler[0], 0x30, data, 1, &globalCount); | |
SendSubcommand(handler[1], 0x30, data, 1, &globalCount); | |
start = std::chrono::system_clock::now(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment