GCC Code Coverage Report


Directory: main/
File: adapter/wired/wii.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 64 0.0%
Functions: 0 4 0.0%
Branches: 0 30 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 "wii.h"
14
15 enum {
16 WII_CLASSIC_R = 1,
17 WII_CLASSIC_PLUS,
18 WII_CLASSIC_HOME,
19 WII_CLASSIC_MINUS,
20 WII_CLASSIC_L,
21 WII_CLASSIC_D_DOWN,
22 WII_CLASSIC_D_RIGHT,
23 WII_CLASSIC_D_UP,
24 WII_CLASSIC_D_LEFT,
25 WII_CLASSIC_ZR,
26 WII_CLASSIC_X,
27 WII_CLASSIC_A,
28 WII_CLASSIC_Y,
29 WII_CLASSIC_B,
30 WII_CLASSIC_ZL,
31 };
32
33 static DRAM_ATTR const struct ctrl_meta wiic_axes_meta[ADAPTER_MAX_AXES] =
34 {
35 {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x66, .abs_min = 0x66},
36 {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x66, .abs_min = 0x66},
37 {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x66, .abs_min = 0x66},
38 {.size_min = -128, .size_max = 127, .neutral = 0x80, .abs_max = 0x66, .abs_min = 0x66},
39 {.size_min = 0, .size_max = 255, .neutral = 0x16, .abs_max = 0xDA, .abs_min = 0x00},
40 {.size_min = 0, .size_max = 255, .neutral = 0x16, .abs_max = 0xDA, .abs_min = 0x00},
41 };
42
43 struct wiic_map {
44 uint8_t axes[6];
45 uint16_t buttons;
46 } __packed;
47
48 static DRAM_ATTR const uint8_t wiic_axes_idx[ADAPTER_MAX_AXES] =
49 {
50 /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */
51 0, 2, 1, 3, 4, 5
52 };
53
54 static const uint32_t wiic_mask[4] = {0xFFFFFFFF, 0x00000000, 0x00000000, BR_COMBO_MASK};
55 static const uint32_t wiic_pro_desc[4] = {0x000000FF, 0x00000000, 0x00000000, 0x00000000};
56 static const uint32_t wiic_desc[4] = {0x110000FF, 0x00000000, 0x00000000, 0x00000000};
57 static DRAM_ATTR const uint32_t wiic_btns_mask[32] = {
58 0, 0, 0, 0,
59 0, 0, 0, 0,
60 BIT(WII_CLASSIC_D_LEFT), BIT(WII_CLASSIC_D_RIGHT), BIT(WII_CLASSIC_D_DOWN), BIT(WII_CLASSIC_D_UP),
61 0, 0, 0, 0,
62 BIT(WII_CLASSIC_Y), BIT(WII_CLASSIC_A), BIT(WII_CLASSIC_B), BIT(WII_CLASSIC_X),
63 BIT(WII_CLASSIC_PLUS), BIT(WII_CLASSIC_MINUS), BIT(WII_CLASSIC_HOME), 0,
64 BIT(WII_CLASSIC_L), BIT(WII_CLASSIC_ZL), BIT(WII_CLASSIC_L), 0,
65 BIT(WII_CLASSIC_R), BIT(WII_CLASSIC_ZR), BIT(WII_CLASSIC_R), 0,
66 };
67
68 void IRAM_ATTR wii_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
69 switch (dev_mode) {
70 default:
71 {
72 struct wiic_map *map = (struct wiic_map *)wired_data->output;
73
74 memset(wired_data->output, 0, 32);
75 map->buttons = 0xFFFF;
76 for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) {
77 map->axes[wiic_axes_idx[i]] = wiic_axes_meta[i].neutral;
78 }
79 memset(wired_data->output_mask, 0x00, sizeof(struct wiic_map));
80 break;
81 }
82 }
83 }
84
85 void wii_meta_init(struct wired_ctrl *ctrl_data) {
86 memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*4);
87
88 for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
89 for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
90 switch (config.out_cfg[i].dev_mode) {
91 case DEV_PAD_ALT:
92 ctrl_data[i].mask = wiic_mask;
93 ctrl_data[i].desc = wiic_desc;
94 ctrl_data[i].axes[j].meta = &wiic_axes_meta[j];
95 break;
96 default:
97 ctrl_data[i].mask = wiic_mask;
98 ctrl_data[i].desc = wiic_pro_desc;
99 ctrl_data[i].axes[j].meta = &wiic_axes_meta[j];
100 break;
101 }
102 }
103 }
104 }
105
106 void wii_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
107 struct wiic_map map_tmp;
108 uint32_t map_mask = 0xFFFF;
109
110 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
111
112 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
113 if (ctrl_data->map_mask[0] & generic_btns_mask[i]) {
114 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
115 map_tmp.buttons &= ~wiic_btns_mask[i];
116 map_mask &= ~wiic_btns_mask[i];
117 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
118 }
119 else if (map_mask & wiic_btns_mask[i]) {
120 map_tmp.buttons |= wiic_btns_mask[i];
121 wired_data->cnt_mask[i] = 0;
122 }
123 }
124 }
125
126 if (dev_mode == DEV_PAD) {
127 /* Wii Classic Pro analogs status is link to digital buttons */
128 if (map_tmp.buttons & BIT(WII_CLASSIC_L)) {
129 map_tmp.axes[wiic_axes_idx[TRIG_L]] = 0x00;
130 }
131 else {
132 map_tmp.axes[wiic_axes_idx[TRIG_L]] = 0xF8;
133 }
134 if (map_tmp.buttons & BIT(WII_CLASSIC_R)) {
135 map_tmp.axes[wiic_axes_idx[TRIG_R]] = 0x00;
136 }
137 else {
138 map_tmp.axes[wiic_axes_idx[TRIG_R]] = 0xF8;
139 }
140 }
141
142 for (uint32_t i = 0; i < ADAPTER_MAX_AXES; i++) {
143 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & ctrl_data->desc[0])) {
144 if (ctrl_data->axes[i].value > ctrl_data->axes[i].meta->size_max) {
145 map_tmp.axes[wiic_axes_idx[i]] = 255;
146 }
147 else if (ctrl_data->axes[i].value < ctrl_data->axes[i].meta->size_min) {
148 map_tmp.axes[wiic_axes_idx[i]] = 0;
149 }
150 else {
151 map_tmp.axes[wiic_axes_idx[i]] = (uint8_t)(ctrl_data->axes[i].value + ctrl_data->axes[i].meta->neutral);
152 }
153 }
154 wired_data->cnt_mask[axis_to_btn_id(i)] = ctrl_data->axes[i].cnt_mask;
155 }
156
157 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
158
159 TESTS_CMDS_LOG("\"wired_output\": {\"axes\": [%d, %d, %d, %d, %d, %d], \"btns\": %d},\n",
160 map_tmp.axes[wiic_axes_idx[0]], map_tmp.axes[wiic_axes_idx[1]], map_tmp.axes[wiic_axes_idx[2]],
161 map_tmp.axes[wiic_axes_idx[3]], map_tmp.axes[wiic_axes_idx[4]], map_tmp.axes[wiic_axes_idx[5]], map_tmp.buttons);
162 BT_MON_LOG("\"wired_output\": {\"axes\": [%02X, %02X, %02X, %02X, %02X, %02X], \"btns\": %04X},\n",
163 map_tmp.axes[wiic_axes_idx[0]], map_tmp.axes[wiic_axes_idx[1]], map_tmp.axes[wiic_axes_idx[2]],
164 map_tmp.axes[wiic_axes_idx[3]], map_tmp.axes[wiic_axes_idx[4]], map_tmp.axes[wiic_axes_idx[5]], map_tmp.buttons);
165 }
166
167 void IRAM_ATTR wii_gen_turbo_mask(struct wired_data *wired_data) {
168 struct wiic_map *map_mask = (struct wiic_map *)wired_data->output_mask;
169
170 memset(map_mask, 0x00, sizeof(*map_mask));
171
172 wired_gen_turbo_mask_btns16_neg(wired_data, &map_mask->buttons, wiic_btns_mask);
173 wired_gen_turbo_mask_axes8(wired_data, map_mask->axes, ADAPTER_MAX_AXES, wiic_axes_idx, wiic_axes_meta);
174 }
175