| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * Copyright (c) 2019-2025, Jacques Gagnon | ||
| 3 | * SPDX-License-Identifier: Apache-2.0 | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <string.h> | ||
| 7 | #include "zephyr/types.h" | ||
| 8 | #include "tools/util.h" | ||
| 9 | #include "adapter/adapter.h" | ||
| 10 | #include "adapter/config.h" | ||
| 11 | #include "adapter/wired/wired.h" | ||
| 12 | #include "tests/cmds.h" | ||
| 13 | #include "bluetooth/mon.h" | ||
| 14 | #include "gc.h" | ||
| 15 | |||
| 16 | enum { | ||
| 17 | GC_A, | ||
| 18 | GC_B, | ||
| 19 | GC_X, | ||
| 20 | GC_Y, | ||
| 21 | GC_START, | ||
| 22 | GC_LD_LEFT = 8, | ||
| 23 | GC_LD_RIGHT, | ||
| 24 | GC_LD_DOWN, | ||
| 25 | GC_LD_UP, | ||
| 26 | GC_Z, | ||
| 27 | GC_R, | ||
| 28 | GC_L, | ||
| 29 | }; | ||
| 30 | |||
| 31 | static DRAM_ATTR const uint8_t gc_axes_idx[ADAPTER_MAX_AXES] = | ||
| 32 | { | ||
| 33 | /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */ | ||
| 34 | 0, 1, 2, 3, 4, 5 | ||
| 35 | }; | ||
| 36 | |||
| 37 | static DRAM_ATTR const struct ctrl_meta gc_axes_meta[ADAPTER_MAX_AXES] = | ||
| 38 | { | ||
| 39 | {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x64, .abs_min = 0x64}, | ||
| 40 | {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x64, .abs_min = 0x64}, | ||
| 41 | {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x5C, .abs_min = 0x5C}, | ||
| 42 | {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x5C, .abs_min = 0x5C}, | ||
| 43 | {.size_min = 0, .size_max = 255, .neutral = 0x20, .abs_max = 0xD0, .abs_min = 0x00}, | ||
| 44 | {.size_min = 0, .size_max = 255, .neutral = 0x20, .abs_max = 0xD0, .abs_min = 0x00}, | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct gc_map { | ||
| 48 | uint16_t buttons; | ||
| 49 | uint8_t axes[6]; | ||
| 50 | } __packed; | ||
| 51 | |||
| 52 | struct gc_kb_map { | ||
| 53 | uint8_t salt; | ||
| 54 | uint8_t bytes[3]; | ||
| 55 | uint8_t key_codes[3]; | ||
| 56 | uint8_t xor; | ||
| 57 | } __packed; | ||
| 58 | |||
| 59 | static const uint32_t gc_mask[4] = {0x773F0FFF, 0x00000000, 0x00000000, BR_COMBO_MASK}; | ||
| 60 | static const uint32_t gc_desc[4] = {0x110000FF, 0x00000000, 0x00000000, 0x00000000}; | ||
| 61 | static DRAM_ATTR const uint32_t gc_btns_mask[32] = { | ||
| 62 | 0, 0, 0, 0, | ||
| 63 | 0, 0, 0, 0, | ||
| 64 | BIT(GC_LD_LEFT), BIT(GC_LD_RIGHT), BIT(GC_LD_DOWN), BIT(GC_LD_UP), | ||
| 65 | 0, 0, 0, 0, | ||
| 66 | BIT(GC_B), BIT(GC_X), BIT(GC_A), BIT(GC_Y), | ||
| 67 | BIT(GC_START), 0, 0, 0, | ||
| 68 | 0, BIT(GC_Z), BIT(GC_L), 0, | ||
| 69 | 0, BIT(GC_Z), BIT(GC_R), 0, | ||
| 70 | }; | ||
| 71 | static DRAM_ATTR const uint32_t gc_btns_mask_alt[32] = { | ||
| 72 | 0, 0, 0, 0, | ||
| 73 | 0, 0, 0, 0, | ||
| 74 | BIT(GC_LD_LEFT), BIT(GC_LD_RIGHT), BIT(GC_LD_DOWN), BIT(GC_LD_UP), | ||
| 75 | 0, 0, 0, 0, | ||
| 76 | BIT(GC_Y), BIT(GC_A), BIT(GC_B), BIT(GC_X), | ||
| 77 | BIT(GC_START), 0, 0, 0, | ||
| 78 | 0, BIT(GC_Z), BIT(GC_L), 0, | ||
| 79 | 0, BIT(GC_Z), BIT(GC_R), 0, | ||
| 80 | }; | ||
| 81 | static DRAM_ATTR const uint32_t *btns_mask[WIRED_MAX_DEV] = { | ||
| 82 | gc_btns_mask, gc_btns_mask, gc_btns_mask, gc_btns_mask, | ||
| 83 | gc_btns_mask, gc_btns_mask, gc_btns_mask, gc_btns_mask, | ||
| 84 | #ifndef CONFIG_BLUERETRO_QEMU | ||
| 85 | gc_btns_mask, gc_btns_mask, gc_btns_mask, gc_btns_mask, | ||
| 86 | #endif | ||
| 87 | }; | ||
| 88 | |||
| 89 | static const uint32_t gc_kb_mask[4] = {0xE6FF0F0F, 0xFFFFFFFF, 0x1FBFFFFF, 0x0003C000 | BR_COMBO_MASK}; | ||
| 90 | static const uint32_t gc_kb_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000}; | ||
| 91 | static const uint8_t gc_kb_scancode[KBM_MAX] = { | ||
| 92 | /* KB_A, KB_D, KB_S, KB_W, MOUSE_X_LEFT, MOUSE_X_RIGHT, MOUSE_Y_DOWN MOUSE_Y_UP */ | ||
| 93 | 0x10, 0x13, 0x22, 0x26, 0x00, 0x00, 0x00, 0x00, | ||
| 94 | /* KB_LEFT, KB_RIGHT, KB_DOWN, KB_UP, MOUSE_WX_LEFT, MOUSE_WX_RIGHT, MOUSE_WY_DOWN, MOUSE_WY_UP */ | ||
| 95 | 0x5C, 0x5F, 0x5D, 0x5E, 0x00, 0x00, 0x00, 0x00, | ||
| 96 | /* KB_Q, KB_R, KB_E, KB_F, KB_ESC, KB_ENTER, KB_LWIN, KB_HASH */ | ||
| 97 | 0x20, 0x21, 0x14, 0x15, 0x4c, 0x61, 0x58, 0x4f, | ||
| 98 | /* MOUSE_RIGHT, KB_Z, KB_LCTRL, MOUSE_MIDDLE, MOUSE_LEFT, KB_X, KB_LSHIFT, KB_SPACE */ | ||
| 99 | 0x00, 0x29, 0x56, 0x00, 0x00, 0x27, 0x54, 0x59, | ||
| 100 | |||
| 101 | /* KB_B, KB_C, KB_G, KB_H, KB_I, KB_J, KB_K, KB_L */ | ||
| 102 | 0x11, 0x12, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, | ||
| 103 | /* KB_M, KB_N, KB_O, KB_P, KB_T, KB_U, KB_V, KB_Y */ | ||
| 104 | 0x1C, 0x1D, 0x1E, 0x1F, 0x23, 0x24, 0x25, 0x28, | ||
| 105 | /* KB_1, KB_2, KB_3, KB_4, KB_5, KB_6, KB_7, KB_8 */ | ||
| 106 | 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, | ||
| 107 | /* KB_9, KB_0, KB_BACKSPACE, KB_TAB, KB_MINUS, KB_EQUAL, KB_LEFTBRACE, KB_RIGHTBRACE */ | ||
| 108 | 0x32, 0x33, 0x50, 0x51, 0x34, 0x35, 0x38, 0x3B, | ||
| 109 | |||
| 110 | /* KB_BACKSLASH, KB_SEMICOLON, KB_APOSTROPHE, KB_GRAVE, KB_COMMA, KB_DOT, KB_SLASH, KB_CAPSLOCK */ | ||
| 111 | 0x3F, 0x39, 0x3A, 0x36, 0x3C, 0x3D, 0x3E, 0x53, | ||
| 112 | /* KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8 */ | ||
| 113 | 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, | ||
| 114 | /* KB_F9, KB_F10, KB_F11, KB_F12, KB_PSCREEN, KB_SCROLL, KB_PAUSE, KB_INSERT */ | ||
| 115 | 0x48, 0x49, 0x4A, 0x4B, 0x37, 0x0A, 0x00, 0x4D, | ||
| 116 | /* KB_HOME, KB_PAGEUP, KB_DEL, KB_END, KB_PAGEDOWN, KB_NUMLOCK, KB_KP_DIV, KB_KP_MULTI */ | ||
| 117 | 0x06, 0x08, 0x4E, 0x07, 0x09, 0x00, 0x00, 0x00, | ||
| 118 | |||
| 119 | /* KB_KP_MINUS, KB_KP_PLUS, KB_KP_ENTER, KB_KP_1, KB_KP_2, KB_KP_3, KB_KP_4, KB_KP_5 */ | ||
| 120 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 121 | /* KB_KP_6, KB_KP_7, KB_KP_8, KB_KP_9, KB_KP_0, KB_KP_DOT, KB_LALT, KB_RCTRL */ | ||
| 122 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x5B, | ||
| 123 | /* KB_RSHIFT, KB_RALT, KB_RWIN */ | ||
| 124 | 0x55, 0x5A, 0x00, | ||
| 125 | }; | ||
| 126 | |||
| 127 | 186 | void IRAM_ATTR gc_init_buffer(int32_t dev_mode, struct wired_data *wired_data) { | |
| 128 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→5) taken 186 times.
|
186 | switch (dev_mode) { |
| 129 | ✗ | case DEV_KB: | |
| 130 | { | ||
| 131 | ✗ | memset(wired_data->output, 0, sizeof(struct gc_kb_map)); | |
| 132 | ✗ | break; | |
| 133 | } | ||
| 134 | 186 | default: | |
| 135 | { | ||
| 136 | 186 | struct gc_map *map = (struct gc_map *)wired_data->output; | |
| 137 | 186 | struct gc_map *map_mask = (struct gc_map *)wired_data->output_mask; | |
| 138 | |||
| 139 | 186 | map->buttons = 0x8020; | |
| 140 | 186 | map_mask->buttons = 0xFFFF; | |
| 141 |
2/2✓ Branch 0 (7→6) taken 1116 times.
✓ Branch 1 (7→8) taken 186 times.
|
1302 | for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) { |
| 142 | 1116 | map->axes[gc_axes_idx[i]] = gc_axes_meta[i].neutral; | |
| 143 | } | ||
| 144 | 186 | memset(map_mask->axes, 0x00, sizeof(map_mask->axes)); | |
| 145 | 186 | break; | |
| 146 | } | ||
| 147 | } | ||
| 148 | 186 | } | |
| 149 | |||
| 150 | 1294 | void gc_meta_init(struct wired_ctrl *ctrl_data) { | |
| 151 | 1294 | memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*4); | |
| 152 | |||
| 153 |
2/2✓ Branch 0 (10→11) taken 10352 times.
✓ Branch 1 (10→12) taken 1294 times.
|
11646 | for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) { |
| 154 |
2/2✓ Branch 0 (8→4) taken 62112 times.
✓ Branch 1 (8→9) taken 10352 times.
|
72464 | for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) { |
| 155 |
1/2✗ Branch 0 (4→5) not taken.
✓ Branch 1 (4→6) taken 62112 times.
|
62112 | switch (config.out_cfg[i].dev_mode) { |
| 156 | ✗ | case DEV_KB: | |
| 157 | ✗ | ctrl_data[i].mask = gc_kb_mask; | |
| 158 | ✗ | ctrl_data[i].desc = gc_kb_desc; | |
| 159 | ✗ | ctrl_data[i].axes[j].meta = NULL; | |
| 160 | ✗ | break; | |
| 161 | 62112 | default: | |
| 162 | 62112 | ctrl_data[i].mask = gc_mask; | |
| 163 | 62112 | ctrl_data[i].desc = gc_desc; | |
| 164 | 62112 | ctrl_data[i].axes[j].meta = &gc_axes_meta[j]; | |
| 165 | 62112 | break; | |
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | 1294 | } | |
| 170 | |||
| 171 | 1294 | static void gc_ctrl_special_action(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) { | |
| 172 | /* Face buttons mapping convertion toggle between names & positions */ | ||
| 173 |
2/2✓ Branch 0 (2→3) taken 1142 times.
✓ Branch 1 (2→14) taken 152 times.
|
1294 | if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_MS]) { |
| 174 |
2/2✓ Branch 0 (3→4) taken 80 times.
✓ Branch 1 (3→7) taken 1062 times.
|
1142 | if (ctrl_data->btns[0].value & generic_btns_mask[PAD_MS]) { |
| 175 |
1/2✓ Branch 0 (5→6) taken 80 times.
✗ Branch 1 (5→14) not taken.
|
80 | if (!atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) { |
| 176 | 80 | atomic_set_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE); | |
| 177 | } | ||
| 178 | } | ||
| 179 | else { | ||
| 180 |
2/2✓ Branch 0 (8→9) taken 80 times.
✓ Branch 1 (8→14) taken 982 times.
|
1062 | if (atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) { |
| 181 | 80 | atomic_clear_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE); | |
| 182 | |||
| 183 |
2/2✓ Branch 0 (10→11) taken 40 times.
✓ Branch 1 (10→12) taken 40 times.
|
80 | if (btns_mask[ctrl_data->index] == gc_btns_mask) { |
| 184 | 40 | btns_mask[ctrl_data->index] = gc_btns_mask_alt; | |
| 185 | 40 | printf("# %s: Names based mapping\n", __FUNCTION__); | |
| 186 | } | ||
| 187 | else { | ||
| 188 | 40 | btns_mask[ctrl_data->index] = gc_btns_mask; | |
| 189 | 40 | printf("# %s: Position based mapping\n", __FUNCTION__); | |
| 190 | } | ||
| 191 | 80 | adapter_toggle_fb(ctrl_data->index, 300000, 0xFF, 0xFF); | |
| 192 | } | ||
| 193 | } | ||
| 194 | } | ||
| 195 | 1294 | } | |
| 196 | |||
| 197 | 1294 | static void gc_ctrl_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) { | |
| 198 | 1294 | struct gc_map map_tmp; | |
| 199 | 1294 | uint32_t map_mask = 0xFFFF; | |
| 200 | |||
| 201 | 1294 | memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp)); | |
| 202 | |||
| 203 |
2/2✓ Branch 0 (11→4) taken 41408 times.
✓ Branch 1 (11→12) taken 1294 times.
|
42702 | for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) { |
| 204 |
2/2✓ Branch 0 (4→5) taken 16022 times.
✓ Branch 1 (4→6) taken 25386 times.
|
41408 | if (ctrl_data->map_mask[0] & generic_btns_mask[i]) { |
| 205 |
2/2✓ Branch 0 (6→7) taken 1024 times.
✓ Branch 1 (6→8) taken 24362 times.
|
25386 | if (ctrl_data->btns[0].value & generic_btns_mask[i]) { |
| 206 | 1024 | map_tmp.buttons |= btns_mask[ctrl_data->index][i]; | |
| 207 | 1024 | map_mask &= ~btns_mask[ctrl_data->index][i]; | |
| 208 | 1024 | wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i]; | |
| 209 | } | ||
| 210 |
2/2✓ Branch 0 (8→5) taken 11087 times.
✓ Branch 1 (8→9) taken 13275 times.
|
24362 | else if (map_mask & btns_mask[ctrl_data->index][i]) { |
| 211 | 13275 | map_tmp.buttons &= ~btns_mask[ctrl_data->index][i]; | |
| 212 | 13275 | wired_data->cnt_mask[i] = 0; | |
| 213 | } | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | 1294 | gc_ctrl_special_action(ctrl_data, wired_data); | |
| 218 | |||
| 219 |
2/2✓ Branch 0 (23→14) taken 7764 times.
✓ Branch 1 (23→24) taken 1294 times.
|
9058 | for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) { |
| 220 |
2/2✓ Branch 0 (15→16) taken 6208 times.
✓ Branch 1 (15→21) taken 1556 times.
|
7764 | if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & gc_desc[0])) { |
| 221 |
1/2✗ Branch 0 (16→17) not taken.
✓ Branch 1 (16→18) taken 6208 times.
|
6208 | if (ctrl_data->axes[i].value > ctrl_data->axes[i].meta->size_max) { |
| 222 | ✗ | map_tmp.axes[gc_axes_idx[i]] = 255; | |
| 223 | } | ||
| 224 |
1/2✗ Branch 0 (18→19) not taken.
✓ Branch 1 (18→20) taken 6208 times.
|
6208 | else if (ctrl_data->axes[i].value < ctrl_data->axes[i].meta->size_min) { |
| 225 | ✗ | map_tmp.axes[gc_axes_idx[i]] = 0; | |
| 226 | } | ||
| 227 | else { | ||
| 228 | 6208 | map_tmp.axes[gc_axes_idx[i]] = (uint8_t)(ctrl_data->axes[i].value + ctrl_data->axes[i].meta->neutral); | |
| 229 | } | ||
| 230 | } | ||
| 231 | 7764 | wired_data->cnt_mask[axis_to_btn_id(i)] = ctrl_data->axes[i].cnt_mask; | |
| 232 | } | ||
| 233 | |||
| 234 | 1294 | memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp)); | |
| 235 | |||
| 236 | 1294 | TESTS_CMDS_LOG("\"wired_output\": {\"axes\": [%d, %d, %d, %d, %d, %d], \"btns\": %d},\n", | |
| 237 | map_tmp.axes[gc_axes_idx[0]], map_tmp.axes[gc_axes_idx[1]], map_tmp.axes[gc_axes_idx[2]], | ||
| 238 | map_tmp.axes[gc_axes_idx[3]], map_tmp.axes[gc_axes_idx[4]], map_tmp.axes[gc_axes_idx[5]], map_tmp.buttons); | ||
| 239 | BT_MON_LOG("\"wired_output\": {\"axes\": [%02X, %02X, %02X, %02X, %02X, %02X], \"btns\": %04X},\n", | ||
| 240 | map_tmp.axes[gc_axes_idx[0]], map_tmp.axes[gc_axes_idx[1]], map_tmp.axes[gc_axes_idx[2]], | ||
| 241 | 1294 | map_tmp.axes[gc_axes_idx[3]], map_tmp.axes[gc_axes_idx[4]], map_tmp.axes[gc_axes_idx[5]], map_tmp.buttons); | |
| 242 | 1294 | } | |
| 243 | |||
| 244 | ✗ | static void gc_kb_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) { | |
| 245 | ✗ | struct gc_kb_map map_tmp = {0}; | |
| 246 | ✗ | uint32_t code_idx = 0; | |
| 247 | |||
| 248 | ✗ | for (uint32_t i = 0; i < KBM_MAX && code_idx < ARRAY_SIZE(map_tmp.key_codes); i++) { | |
| 249 | ✗ | if (ctrl_data->map_mask[i / 32] & BIT(i & 0x1F)) { | |
| 250 | ✗ | if (ctrl_data->btns[i / 32].value & BIT(i & 0x1F)) { | |
| 251 | ✗ | if (gc_kb_scancode[i]) { | |
| 252 | ✗ | map_tmp.key_codes[code_idx++] = gc_kb_scancode[i]; | |
| 253 | } | ||
| 254 | } | ||
| 255 | } | ||
| 256 | } | ||
| 257 | ✗ | map_tmp.salt = (wired_data->output[0] + 1) & 0xF; | |
| 258 | |||
| 259 | ✗ | memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp)); | |
| 260 | ✗ | } | |
| 261 | |||
| 262 | 1294 | void gc_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) { | |
| 263 |
1/2✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→5) taken 1294 times.
|
1294 | switch (dev_mode) { |
| 264 | ✗ | case DEV_KB: | |
| 265 | ✗ | gc_kb_from_generic(ctrl_data, wired_data); | |
| 266 | ✗ | break; | |
| 267 | 1294 | case DEV_PAD: | |
| 268 | default: | ||
| 269 | 1294 | gc_ctrl_from_generic(ctrl_data, wired_data); | |
| 270 | 1294 | break; | |
| 271 | } | ||
| 272 | 1294 | } | |
| 273 | |||
| 274 | ✗ | void gc_fb_to_generic(int32_t dev_mode, struct raw_fb *raw_fb_data, struct generic_fb *fb_data) { | |
| 275 | ✗ | fb_data->wired_id = raw_fb_data->header.wired_id; | |
| 276 | ✗ | fb_data->type = raw_fb_data->header.type; | |
| 277 | |||
| 278 | /* This stop rumble when BR timeout trigger */ | ||
| 279 | ✗ | if (raw_fb_data->header.data_len == 0) { | |
| 280 | ✗ | fb_data->state = 0; | |
| 281 | ✗ | fb_data->lf_pwr = fb_data->hf_pwr = 0; | |
| 282 | } | ||
| 283 | else { | ||
| 284 | ✗ | fb_data->state = raw_fb_data->data[0]; | |
| 285 | ✗ | fb_data->lf_pwr = (fb_data->state) ? 0xFF : 0x00; | |
| 286 | ✗ | fb_data->hf_pwr = (fb_data->state) ? 0xFF : 0x00; | |
| 287 | } | ||
| 288 | ✗ | } | |
| 289 | |||
| 290 | ✗ | void IRAM_ATTR gc_gen_turbo_mask(struct wired_data *wired_data) { | |
| 291 | ✗ | struct gc_map *map_mask = (struct gc_map *)wired_data->output_mask; | |
| 292 | |||
| 293 | ✗ | map_mask->buttons = 0xFFFF; | |
| 294 | ✗ | memset(map_mask->axes, 0x00, sizeof(map_mask->axes)); | |
| 295 | |||
| 296 | ✗ | wired_gen_turbo_mask_btns16_pos(wired_data, &map_mask->buttons, btns_mask[wired_data->index]); | |
| 297 | ✗ | wired_gen_turbo_mask_axes8(wired_data, map_mask->axes, ADAPTER_MAX_AXES, gc_axes_idx, gc_axes_meta); | |
| 298 | ✗ | } | |
| 299 |