-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
111 lines (90 loc) · 3.23 KB
/
main.cpp
File metadata and controls
111 lines (90 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include <thread>
#include <chrono>
#include <cstring>
#include <map>
#include <string>
#include <sstream>
#include <tuple>
extern "C" {
#include "hid/hidapi.h"
}
extern "C" {
extern unsigned char lightbar_json[];
extern unsigned int lightbar_json_len;
}
constexpr unsigned short DS4_VID = 0x054C;
constexpr unsigned short DS4_PID = 0x05C4;
void set_lightbar(hid_device* dev, uint8_t r, uint8_t g, uint8_t b) {
if (!dev) return;
unsigned char report[32];
std::memset(report, 0, sizeof(report));
report[0] = 0x05;
report[1] = 0xFF;
report[6] = r;
report[7] = g;
report[8] = b;
hid_write(dev, report, sizeof(report));
}
std::map<std::string, std::tuple<uint8_t,uint8_t,uint8_t>> parse_lightbar_json() {
std::map<std::string, std::tuple<uint8_t,uint8_t,uint8_t>> colors;
std::string s(reinterpret_cast<char*>(lightbar_json), lightbar_json_len);
size_t pos = 0;
while((pos = s.find("\"gamepad", pos)) != std::string::npos) {
size_t key_start = pos;
size_t key_end = s.find("\"", key_start+1);
std::string key = s.substr(key_start+1, key_end-key_start-1);
size_t val_start = s.find("\"#", key_end);
if(val_start == std::string::npos) break;
val_start += 2; // skip "#"
std::string hex = s.substr(val_start,6);
unsigned int r,g,b;
std::stringstream ss;
ss << std::hex << hex.substr(0,2); ss >> r;
ss.clear(); ss.str(""); ss << std::hex << hex.substr(2,2); ss >> g;
ss.clear(); ss.str(""); ss << std::hex << hex.substr(4,2); ss >> b;
colors[key] = std::make_tuple((uint8_t)r,(uint8_t)g,(uint8_t)b);
pos = val_start;
}
return colors;
}
int main() {
std::cout << "PS controller lightbar software (JSON)\n";
if(hid_init()!=0){
std::cerr << "hid_init failed\n";
return 1;
}
auto lightbar_colors = parse_lightbar_json();
int controller_count = 0;
hid_device* controller = nullptr;
while(true){
if(!controller){
controller = hid_open(DS4_VID, DS4_PID, nullptr);
if(controller){
controller_count++;
std::string gamepad_key = "gamepad" + std::to_string(controller_count);
std::cout << "Controller connected, Assigned as " << gamepad_key << "\n";
if(lightbar_colors.count(gamepad_key)){
auto [r,g,b] = lightbar_colors[gamepad_key];
set_lightbar(controller,r,g,b);
std::cout << "Set lightbar color: R=" << (int)r
<< " G=" << (int)g << " B=" << (int)b << "\n";
} else {
std::cout << "No color defined for " << gamepad_key << ", using default\n";
set_lightbar(controller,255,0,255);
}
}
} else {
unsigned char buf[1];
int r = hid_read_timeout(controller, buf, sizeof(buf),10);
if(r<0){
std::cout << "Controller disconnected\n";
hid_close(controller);
controller=nullptr;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
hid_exit();
return 0;
}