GCC Code Coverage Report


Directory: main/
File: adapter/wired/pcfx.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 95 0.0%
Functions: 0 6 0.0%
Branches: 0 48 0.0%

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/config.h"
10 #include "adapter/wired/wired.h"
11 #include "tests/cmds.h"
12 #include "bluetooth/mon.h"
13 #include "pcfx.h"
14
15 enum {
16 PCFX_I = 0,
17 PCFX_II,
18 PCFX_III,
19 PCFX_IV,
20 PCFX_V,
21 PCFX_VI,
22 PCFX_SELECT,
23 PCFX_RUN,
24 PCFX_LD_UP,
25 PCFX_LD_RIGHT,
26 PCFX_LD_DOWN,
27 PCFX_LD_LEFT,
28 PCFX_MODE1,
29 PCFX_MODE2 = 14,
30 };
31
32 enum {
33 PCFX_M_LEFT = 0,
34 PCFX_M_RIGHT,
35 };
36
37 static DRAM_ATTR const uint8_t pcfx_mouse_axes_idx[ADAPTER_MAX_AXES] =
38 {
39 /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */
40 1, 0, 1, 0, 1, 0
41 };
42
43 static DRAM_ATTR const struct ctrl_meta pcfx_mouse_axes_meta[ADAPTER_MAX_AXES] =
44 {
45 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
46 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128, .polarity = 1},
47 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
48 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128, .polarity = 1},
49 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
50 {.size_min = -128, .size_max = 127, .neutral = 0x00, .abs_max = 127, .abs_min = 128},
51 };
52
53 struct pcfx_map {
54 uint16_t buttons;
55 uint8_t ids[0];
56 } __packed;
57
58 struct pcfx_mouse_map {
59 uint8_t axes[2];
60 uint8_t buttons;
61 uint8_t id;
62 uint8_t align[2];
63 uint8_t relative[2];
64 int32_t raw_axes[2];
65 } __packed;
66
67 static const uint32_t pcfx_mask[4] = {0xBB3F0F00, 0x00000000, 0x00000000, BR_COMBO_MASK};
68 static const uint32_t pcfx_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
69 static DRAM_ATTR const uint32_t pcfx_btns_mask[32] = {
70 0, 0, 0, 0,
71 0, 0, 0, 0,
72 BIT(PCFX_LD_LEFT), BIT(PCFX_LD_RIGHT), BIT(PCFX_LD_DOWN), BIT(PCFX_LD_UP),
73 0, 0, 0, 0,
74 BIT(PCFX_III), BIT(PCFX_I), BIT(PCFX_II), BIT(PCFX_V),
75 BIT(PCFX_RUN), BIT(PCFX_SELECT), 0, 0,
76 BIT(PCFX_IV), BIT(PCFX_IV), 0, 0,
77 BIT(PCFX_VI), BIT(PCFX_VI), 0, 0,
78 };
79
80 static const uint32_t pcfx_mouse_mask[4] = {0x110000F0, 0x00000000, 0x00000000, BR_COMBO_MASK};
81 static const uint32_t pcfx_mouse_desc[4] = {0x000000F0, 0x00000000, 0x00000000, 0x00000000};
82 static const uint32_t pcfx_mouse_btns_mask[32] = {
83 0, 0, 0, 0,
84 0, 0, 0, 0,
85 0, 0, 0, 0,
86 0, 0, 0, 0,
87 0, 0, 0, 0,
88 0, 0, 0, 0,
89 BIT(PCFX_M_RIGHT), 0, 0, 0,
90 BIT(PCFX_M_LEFT), 0, 0, 0,
91 };
92
93 void IRAM_ATTR pcfx_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
94 switch (dev_mode) {
95 case DEV_MOUSE:
96 {
97 struct pcfx_mouse_map *map = (struct pcfx_mouse_map *)wired_data->output;
98
99 map->id = 0xD0;
100 map->buttons = 0x00;
101 for (uint32_t i = 0; i < 2; i++) {
102 map->raw_axes[i] = 0;
103 map->relative[i] = 1;
104 }
105 break;
106 }
107 default:
108 {
109 struct pcfx_map *map = (struct pcfx_map *)wired_data->output;
110
111 map->buttons = 0x0000;
112 map->ids[0] = 0x00;
113 map->ids[1] = 0xF0;
114
115 wired_data->output_mask32[0] = 0xFFFFFFFF;
116 break;
117 }
118 }
119 }
120
121 void pcfx_meta_init(struct wired_ctrl *ctrl_data) {
122 memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*WIRED_MAX_DEV);
123
124 for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
125 for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
126 switch (config.out_cfg[i].dev_mode) {
127 case DEV_MOUSE:
128 ctrl_data[i].mask = pcfx_mouse_mask;
129 ctrl_data[i].desc = pcfx_mouse_desc;
130 ctrl_data[i].axes[j].meta = &pcfx_mouse_axes_meta[j];
131 break;
132 default:
133 ctrl_data[i].mask = pcfx_mask;
134 ctrl_data[i].desc = pcfx_desc;
135 break;
136 }
137 }
138 }
139 }
140
141 void pcfx_ctrl_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
142 struct pcfx_map map_tmp;
143 uint32_t map_mask = 0xFFFF;
144
145 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
146
147 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
148 if (ctrl_data->map_mask[0] & BIT(i)) {
149 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
150 map_tmp.buttons |= pcfx_btns_mask[i];
151 map_mask &= ~pcfx_btns_mask[i];
152 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
153 }
154 else if (map_mask & pcfx_btns_mask[i]) {
155 map_tmp.buttons &= ~pcfx_btns_mask[i];
156 wired_data->cnt_mask[i] = 0;
157 }
158 }
159 }
160
161 /* Mode 1 */
162 if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_LJ]) {
163 if (ctrl_data->btns[0].value & generic_btns_mask[PAD_LJ]) {
164 if (!atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) {
165 atomic_set_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE);
166 }
167 }
168 else {
169 if (atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) {
170 atomic_clear_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE);
171
172 map_tmp.buttons ^= BIT(PCFX_MODE1);
173 }
174 }
175 }
176
177 /* Mode 2 */
178 if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_RJ]) {
179 if (ctrl_data->btns[0].value & generic_btns_mask[PAD_RJ]) {
180 if (!atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2)) {
181 atomic_set_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2);
182 }
183 }
184 else {
185 if (atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2)) {
186 atomic_clear_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE2);
187
188 map_tmp.buttons ^= BIT(PCFX_MODE2);
189 }
190 }
191 }
192
193 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
194
195 TESTS_CMDS_LOG("\"wired_output\": {\"btns\": %d},\n", map_tmp.buttons);
196 BT_MON_LOG("\"wired_output\": {\"btns\": %04X},\n", map_tmp.buttons);
197 }
198
199 static void pcfx_mouse_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
200 struct pcfx_mouse_map map_tmp;
201 int32_t *raw_axes = (int32_t *)(wired_data->output + 8);
202
203 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
204
205 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
206 if (ctrl_data->map_mask[0] & BIT(i)) {
207 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
208 map_tmp.buttons |= pcfx_mouse_btns_mask[i];
209 }
210 else {
211 map_tmp.buttons &= ~pcfx_mouse_btns_mask[i];
212 }
213 }
214 }
215
216 for (uint32_t i = 2; i < 4; i++) {
217 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & pcfx_mouse_desc[0])) {
218 if (ctrl_data->axes[i].relative) {
219 map_tmp.relative[pcfx_mouse_axes_idx[i]] = 1;
220 atomic_add(&raw_axes[pcfx_mouse_axes_idx[i]], ctrl_data->axes[i].value);
221 }
222 else {
223 map_tmp.relative[pcfx_mouse_axes_idx[i]] = 0;
224 raw_axes[pcfx_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
225 }
226 }
227 }
228
229 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
230 }
231
232 void pcfx_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
233 switch (dev_mode) {
234 case DEV_MOUSE:
235 pcfx_mouse_from_generic(ctrl_data, wired_data);
236 break;
237 default:
238 pcfx_ctrl_from_generic(ctrl_data, wired_data);
239 break;
240 }
241 }
242
243 void IRAM_ATTR pcfx_gen_turbo_mask(struct wired_data *wired_data) {
244 struct pcfx_map *map_mask = (struct pcfx_map *)wired_data->output_mask;
245
246 wired_data->output_mask32[0] = 0xFFFFFFFF;
247
248 wired_gen_turbo_mask_btns16_pos(wired_data, &map_mask->buttons, pcfx_btns_mask);
249 }
250