-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeymappings.h
More file actions
225 lines (206 loc) · 9.64 KB
/
keymappings.h
File metadata and controls
225 lines (206 loc) · 9.64 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
/*
Mapping table layout (per profile):
profiles_normal[NUM_PROFILES*2][NUM_KEYS]
profiles_media [NUM_PROFILES*2][NUM_KEYS]
┌───────────────────────────┬───────────────────────────┐
│ Short press mappings │ Long press mappings │
│ (rows 0–7 = profiles) │ (rows 8–15 = profiles) │
└───────────────────────────┴───────────────────────────┘
Example (profile 1 shown):
profiles_normal[0][keyX] → short press normal key
profiles_media [0][keyX] → short press media key
profiles_normal[8][keyX] → long press normal key
profiles_media [8][keyX] → long press media key
Lookup logic:
1. On short press → check normal[profile], fallback to media[profile].
2. On long press → check normal[profile+NUM_PROFILES],
if empty then check media[profile+NUM_PROFILES].
*/
#define NUM_PROFILES 8 // 8 profiles, enough for now, Bill Gates - "640K ought to be enough for anybody"
#define NUM_KEYS 8 // 8 buttons in each profile, with the single controller you will have only 4 buttons
// We maintain two separate lookup tables for key profiles:
//
// 1. normal_profiles:
// - Stores standard keyboard keys (letters, numbers, symbols, arrows, etc.).
// - These are represented as char values (e.g. 'a', '-', '1') or special
// constants like KEY_RETURN, KEY_UP_ARROW, etc.
// - Use this table when you want the keypad to behave like a regular keyboard.
//
// 2. media_profiles:
// - Stores media control keys (e.g. volume up/down, play/pause, next/prev track).
// - These are defined in the BLE Keyboard library as `const uint8_t*`
// (HID usage codes for the consumer control report).
// - Because media keys are defined differently than normal keys, they require
// their own table with a matching pointer type.
//
// Table layout (for both normal_profiles and media_profiles):
// - The first NUM_PROFILES rows are for short press mappings.
// - The next NUM_PROFILES rows (offset by +NUM_PROFILES) are for long press mappings.
// Example: normal_profiles[active_profile][key] → short press mapping
// normal_profiles[active_profile+NUM_PROFILES][key] → long press mapping
//
// Lookup order when a button is pressed:
// - First, the program checks the active entry in normal_profiles (short or long depending on press).
// - If the entry is valid (not empty / not 0), it sends the normal key.
// - If the normal_profiles entry is empty (0), the program falls back to
// the corresponding entry in media_profiles and sends that instead.
//
// This way, each button can either send a normal key or, if unused in the normal table,
// act as a media key — and both short and long press actions can be mapped independently
char profiles_normal[NUM_PROFILES*2][NUM_KEYS] = {
// Profil 1 short press
{ '=', '-', 'r','c', KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW }, // Original RCntrl P.1 + arrow buttons for the second controller
// Profil 2 short press
{ 0, 0, 0, 0, KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW }, // Original RCntrl P.2 + arrow buttons for the second controller
// Profil 3 short press
{ 0, 0, 0, 0, KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW }, // Media profile with Volume/Play/Pause/Stop/Prev/Next + longpress for PLAY/PAUSE/STOP + arrow buttons for the second controller
// Profil 4 short press
{ KEY_F6, KEY_F7, KEY_RETURN, KEY_ESC, KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW }, // DMD2
// Profil 5 short press
{ KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8 }, // generic profile with Function keys that can be mapped inside application
// Profil 6 short press
{ '+', '-', 'D', 'C', KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW }, // Navigation
// Profil 7 short press
{ KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8 }, //SpeedoX MyRide
// Profil 8 short press
{ KEY_UP_ARROW, KEY_LEFT_ARROW, KEY_RIGHT_ARROW, KEY_DOWN_ARROW, KEY_F6, KEY_F7, KEY_RETURN, KEY_ESC }, // Inverted DMD2
// Profil 1 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 2 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 3 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 4 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 5 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 6 long press
{ 0, 0, 'D', 0, 0, 0, 0, 0 }, // send D as a longpressa button
// Profil 7 long press
{ KEY_F9, KEY_F10, KEY_F11, 0, KEY_F12, 0, 0, 0 },
// Profil 8 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
};
const uint8_t* profiles_media[NUM_PROFILES*2][NUM_KEYS] = {
// Profil 1 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 2 short press
{ KEY_MEDIA_PREVIOUS_TRACK, KEY_MEDIA_NEXT_TRACK, KEY_MEDIA_VOLUME_DOWN, KEY_MEDIA_VOLUME_UP, 0, 0, 0, 0 },
// Profil 3 short press
{ KEY_MEDIA_NEXT_TRACK, KEY_MEDIA_PREVIOUS_TRACK, KEY_MEDIA_VOLUME_UP, KEY_MEDIA_VOLUME_DOWN, 0, 0, 0, 0 },
// Profil 4 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 5 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 6 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 7 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 8 short press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// If there is a mapping for long press, instead of sending repeating key, single key with new mapping is sent
// Profil 1 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 2 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 3 long press
// if you use long press keys, make sure that you configure those keys as non-instant by modifying "key_actions" table
// if you leave keys as instant keys, they will first send normal key and than long press key
// Example for profile2:
// first two buttons are non-instant, meaning key will be sent when you release the button (no repeat of course)
// button 1: * short press - > KEY_MEDIA_NEXT_TRACK button 2: * short press - > KEY_MEDIA_PREVIOUS_TRACK
// * long press - > KEY_MEDIA_PLAY_PAUSE * long press - > KEY_MEDIA_STOP
{ KEY_MEDIA_PLAY_PAUSE, KEY_MEDIA_STOP, 0, 0, 0, 0, 0, 0 },
// Profil 4 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 5 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 6 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 7 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 },
// Profil 8 long press
{ 0, 0, 0, 0, 0, 0, 0, 0 }
};
// Status mapping table for keys in each profile
#define RELEASE 0 // fire on key release
#define INSTANT 1 // fire immediately on press
#define DIRECT 2 // bypass normal handling, send keypress
int key_actions[NUM_PROFILES][NUM_KEYS] = {
{INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT}, // profile 1
{INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT}, // profile 2
{RELEASE, RELEASE, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT}, // profile 3
{DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT}, // profile 4
{INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT}, // profile 5
{INSTANT, INSTANT, RELEASE, INSTANT, INSTANT, INSTANT, INSTANT, INSTANT}, // profile 6
{DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT}, // profile 7
{DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT, DIRECT} // profile 8
};
// We want to have separate BT device info for each profile just in case some application require specific name like DMD2
struct BTDeviceInfo {
const char* name;
const char* manufacturer;
int batteryLevel;
};
BTDeviceInfo bt_device_profiles[8] = {
{ "RCntrl V2 P.1", "S.R.I. Omadon", 55 }, // Profil 1
{ "RCntrl V2 P.2", "S.R.I. Omadon", 55 }, // Profil 2
{ "RCntrl V2 P.3", "S.R.I. Omadon", 55 }, // Profil 3
{ "BarButtons", "S.R.I. Omadon", 55 }, // Profil 4
{ "RCntrl V2 P.5", "S.R.I. Omadon", 55 }, // Profil 5
{ "RCntrl V2 P.6", "S.R.I. Omadon", 55 }, // Profil 6
{ "RCntrl V2 P.7", "S.R.I. Omadon", 55 }, // Profil 7
{ "DMD2 CTL 8K", "S.R.I. Omadon", 55 } // Profil 8
};
// We want real names in the debug output
struct MediaKeyName {
const uint8_t* code;
const char* name;
};
MediaKeyName mediaKeyNames[] = {
{ KEY_MEDIA_NEXT_TRACK, "KEY_MEDIA_NEXT_TRACK" },
{ KEY_MEDIA_PREVIOUS_TRACK, "KEY_MEDIA_PREVIOUS_TRACK" },
{ KEY_MEDIA_PLAY_PAUSE, "KEY_MEDIA_PLAY_PAUSE" },
{ KEY_MEDIA_STOP, "KEY_MEDIA_STOP" },
{ KEY_MEDIA_MUTE, "KEY_MEDIA_MUTE" },
{ KEY_MEDIA_VOLUME_UP, "KEY_MEDIA_VOLUME_UP" },
{ KEY_MEDIA_VOLUME_DOWN, "KEY_MEDIA_VOLUME_DOWN" }
};
struct NormalKeyName {
char code;
const char* name;
};
NormalKeyName normalKeyNames[] = {
{ KEY_F1, "KEY_F1" },
{ KEY_F2, "KEY_F2" },
{ KEY_F3, "KEY_F3" },
{ KEY_F4, "KEY_F4" },
{ KEY_F5, "KEY_F5" },
{ KEY_F6, "KEY_F6" },
{ KEY_F7, "KEY_F7" },
{ KEY_F8, "KEY_F8" },
{ KEY_F9, "KEY_F9" },
{ KEY_F10, "KEY_F10" },
{ KEY_F11, "KEY_F11" },
{ KEY_F12, "KEY_F12" },
{ KEY_RETURN, "KEY_RETURN" },
{ KEY_UP_ARROW, "KEY_UP_ARROW" },
{ KEY_DOWN_ARROW, "KEY_DOWN_ARROW" },
{ KEY_LEFT_ARROW, "KEY_LEFT_ARROW" },
{ KEY_RIGHT_ARROW, "KEY_RIGHT_ARROW" },
{ KEY_TAB, "KEY_TAB" },
{ KEY_BACKSPACE, "KEY_BACKSPACE" },
{ KEY_DELETE, "KEY_DELETE" },
{ KEY_ESC, "KEY_ESC" }
};
// We want app status names in the debug output
struct AppStatusName {
const int code;
const char* name;
};
AppStatusName appstatusName[] = {
{ 0, "BT_DISCONNECTED" },
{ 1, "CONFIG_MENU" },
{ 2, "MAIN_MENU" },
{ 3, "KEYMAP_STATUS" }
};