-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpad_translator.h
134 lines (105 loc) · 3.22 KB
/
pad_translator.h
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* author : Shuichi TAKANO
* since : Sat Sep 09 2023 14:39:32
*/
#pragma once
#include <cstdint>
#include <vector>
#include <tuple>
class Serializer;
class Deserializer;
class PadConfig
{
public:
enum class Type : uint8_t
{
NA,
BUTTON,
ANALOG,
HAT,
};
enum class AnalogPos : uint8_t
{
H,
MID,
L,
};
enum class HatPos : uint8_t
{
LEFT,
RIGHT,
UP,
DOWN,
INVALID,
};
struct Unit
{
Type type = Type::BUTTON;
uint8_t number = 0;
AnalogPos analogOn{};
AnalogPos analogOff{};
HatPos hatPos{};
uint8_t index = 0; // 出力ボタン、アナログ番号
uint8_t subIndex = 0; // 同一ボタン出力の中でのサブインデックス
uint8_t inPortOfs = 0; // 入力ポートオフセット
public:
bool testAnalog(uint8_t v) const;
auto makeTie() const
{
return std::tie(type, number, analogOn, analogOff, hatPos, index, subIndex, inPortOfs);
};
friend bool operator<(const Unit &a, const Unit &b)
{
return a.makeTie() < b.makeTie();
}
friend bool operator==(const Unit &a, const Unit &b)
{
return a.makeTie() == b.makeTie();
}
void dump() const;
};
using DeviceID = std::tuple<uint16_t, uint16_t, uint8_t>;
public:
PadConfig() = default;
PadConfig(int vid, int pid, int outPortOfs,
const std::vector<Unit> &buttons, const std::vector<Unit> &analogs);
PadConfig(Deserializer &s);
bool convertButton(int i, const uint32_t *buttons, int nButtons, const int *analogs, int nAnalogs, int hat) const;
int8_t convertAnalog(int i, const uint32_t *buttons, int nButtons, const int *analogs, int nAnalogs, int hat) const;
size_t getButtonCount() const { return buttons_.size(); }
size_t getAnalogCount() const { return analogs_.size(); }
const Unit &getButtonUnit(size_t i) const { return buttons_[i]; }
const Unit &getAnalogUnit(size_t i) const { return analogs_[i]; }
int getVID() const { return vid_; }
int getPID() const { return pid_; }
int getOutPortOfs() const { return outPortOfs_; }
DeviceID getDeviceID() const { return {vid_, pid_, outPortOfs_}; }
void serialize(Serializer &s) const;
void dump() const;
private:
std::vector<Unit> buttons_;
std::vector<Unit> analogs_;
uint16_t vid_ = 0;
uint16_t pid_ = 0;
uint8_t outPortOfs_ = 0; // 出力ポートオフセット
};
int getLevel(PadConfig::AnalogPos p);
bool testHat(int hat, PadConfig::HatPos hatPos);
PadConfig::AnalogPos getAnalogPos(int v);
// デバイスIDと対応する設定を管理
class PadTranslator
{
std::vector<PadConfig> configs_;
PadConfig defaultConfig_;
public:
PadTranslator();
void setDefaultConfig(PadConfig &&cnf) { defaultConfig_ = std::move(cnf); }
void append(PadConfig &&cnf);
const PadConfig *find(int vid, int pid, int portOfs = 0) const;
void serialize(Serializer &s) const;
void deserialize(Deserializer &s);
void reset();
protected:
PadConfig *_find(int vid, int pid, int portOfs = 0);
void sort();
};