8 |
9 | | Byte Dec |
10 | Byte Hex |
11 | Name |
12 | Values |
13 | Description |
14 |
15 |
16 | | 0 |
17 | 0x00 |
18 | Report ID |
19 | |
20 |
21 |
22 | | 1 |
23 | 0x01 |
24 | Feature flags (physical effects) |
25 | |
26 |
27 |
28 | | 2 |
29 | 0x02 |
30 | Feature flags (lights) |
31 |
32 | bit 0: MIC_MUTE_LED_CONTROL_ENABLE
33 | bit 1: POWER_SAVE_CONTROL_ENABLE
34 | bit 2: LIGHTBAR_CONTROL_ENABLE
35 | bit 3: RELEASE_LEDS
36 | bit 4: PLAYER_INDICATOR_CONTROL_ENABLE
37 | bit 5: UNKNOWN_FLAG_5
38 | bit 6: OVERALL_EFFECT_POWER
39 | bit 7: UNKNOWN_FLAG_7
40 | |
41 |
42 | Flag RELEASE_LEDS makes trouble and is currently disabled. All other known flags are enabled.
43 | |
44 |
45 |
46 | | 3 |
47 | 0x03 |
48 | Motor rumble right |
49 | 0 - 255 |
50 | A.K.A. "small rumble" |
51 |
52 |
53 | | 4 |
54 | 0x04 |
55 | Motor rumble left |
56 | 0 - 255 |
57 | A.K.A. "big rumble" |
58 |
59 |
60 | | 5 |
61 | 0x05 |
62 | |
63 | |
64 | headphone, speaker, mic volume, audio flags (USB_Host_Shield_2.0) |
65 |
66 |
67 | | 6 |
68 | 0x06 |
69 | |
70 | |
71 | headphone, speaker, mic volume, audio flags (USB_Host_Shield_2.0) |
72 |
73 |
74 | | 7 |
75 | 0x07 |
76 | |
77 | |
78 | headphone, speaker, mic volume, audio flags (USB_Host_Shield_2.0) |
79 |
80 |
81 | | 8 |
82 | 0x08 |
83 | |
84 | |
85 |
86 |
87 | | 9 |
88 | 0x09 |
89 | Mute button led |
90 |
91 | 0x00 - Off
92 | 0x01 - On
93 | |
94 |
95 |
96 | | 10 |
97 | 0x0A |
98 | Power save control |
99 |
100 | 0x00 - Unmute mic
101 | 0x10 - Mute mic
102 | |
103 |
104 |
105 | | 11 |
106 | 0x0B |
107 | Right trigger - effect mode |
108 |
109 | 0x01 - CONTINUOUS_RESISTANCE
110 | 0x02 - SECTION_RESISTANCE
111 | 0x06 - VIBRATING
112 | 0x23 - EFFECT_EXTENDED
113 | 0xFC - CALIBRATE
114 | |
115 |
116 |
117 | | 12 |
118 | 0x0C |
119 | Right trigger - Parameter 1 |
120 | |
121 | Start of resistance section |
122 |
123 |
124 | | 13 |
125 | 0x0D |
126 | Right trigger - Parameter 2 |
127 | |
128 |
129 |
130 | | 14 |
131 | 0x0E |
132 | Right trigger - Parameter 3 |
133 | |
134 |
135 |
136 | | 15 |
137 | 0x0F |
138 | Right trigger - Parameter 4 |
139 | |
140 |
141 |
142 | | 16 |
143 | 0x10 |
144 | Right trigger - Parameter 5 |
145 | |
146 |
147 |
148 | | 17 |
149 | 0x11 |
150 | Right trigger - Parameter 6 |
151 | |
152 |
153 |
154 | | 18 |
155 | 0x12 |
156 | Right trigger - Parameter 7 |
157 | |
158 |
159 |
160 | | 19 |
161 | 0x13 |
162 | |
163 | |
164 |
165 |
166 | | 20 |
167 | 0x14 |
168 | |
169 | |
170 |
171 |
172 | | 21 |
173 | 0x15 |
174 | |
175 | |
176 |
177 |
178 | | 22 |
179 | 0x16 |
180 | Left trigger - effect mode |
181 |
182 | 0x01 - CONTINUOUS_RESISTANCE
183 | 0x02 - SECTION_RESISTANCE
184 | 0x06 - VIBRATING
185 | 0x23 - EFFECT_EXTENDED
186 | 0xFC - CALIBRATE
187 | |
188 |
189 |
190 | | 23 |
191 | 0x17 |
192 | Left trigger - Parameter 1 |
193 | |
194 | Start of resistance section |
195 |
196 |
197 | | 24 |
198 | 0x18 |
199 | Left trigger - Parameter 2 |
200 | |
201 |
202 |
203 | | 25 |
204 | 0x19 |
205 | Left trigger - Parameter 3 |
206 | |
207 |
208 |
209 | | 26 |
210 | 0x1A |
211 | Left trigger - Parameter 4 |
212 | |
213 |
214 |
215 | | 27 |
216 | 0x1B |
217 | Left trigger - Parameter 5 |
218 | |
219 |
220 |
221 | | 28 |
222 | 0x1C |
223 | Left trigger - Parameter 6 |
224 | |
225 |
226 |
227 | | 29 |
228 | 0x1D |
229 | Left trigger - Parameter 7 |
230 | |
231 |
232 |
233 | | 30 |
234 | 0x1E |
235 |
236 |
237 | | 31 |
238 | 0x1F |
239 |
240 |
241 | | 32 |
242 | 0x20 |
243 |
244 |
245 | | 33 |
246 | 0x21 |
247 |
248 |
249 | | 34 |
250 | 0x22 |
251 |
252 |
253 | | 35 |
254 | 0x23 |
255 |
256 |
257 | | 36 |
258 | 0x24 |
259 |
260 |
261 | | 37 |
262 | 0x25 |
263 | |
264 | |
265 | Trigger motor effect strengths? (USB_Host_Shield_2.0) |
266 |
267 |
268 | | 38 |
269 | 0x26 |
270 | |
271 | |
272 | Speaker volume? (USB_Host_Shield_2.0) |
273 |
274 |
275 | | 39 |
276 | 0x27 |
277 | |
278 | |
279 | Led brightness, pulse? (USB_Host_Shield_2.0) |
280 |
281 |
282 | | 40 |
283 | 0x28 |
284 | |
285 | |
286 | LIGHTBAR_SETUP_CONTROL_ENABLE? (dualsense (Javascript)) |
287 |
288 |
289 | | 41 |
290 | 0x29 |
291 | Lightbar control |
292 |
293 |
294 | 0b100 - LIGHTBAR_CONTROL_ENABLE
295 | 0b000 - LIGHTBAR_CONTROL_DISABLE?
296 |
297 | |
298 | |
299 |
300 |
301 | | 42 |
302 | 0x2A |
303 | Lightbar setup |
304 |
305 |
306 | 0x01 - LIGHT_ON
307 | 0x02 - LIGHT_OFF
308 |
309 | |
310 | |
311 |
312 |
313 | | 43 |
314 | 0x2B |
315 | Led brightness |
316 |
317 |
318 | 0x01 - FULL
319 | 0x02 - MEDIUM
320 | 0x03 - LOW
321 |
322 | |
323 | Sets brightness of mute button and player leds.
324 | Only works when light-effects flag MIC_MUTE_LED_CONTROL_ENABLE is NOT set. This is done interally when
325 | setting brightness.
326 | |
327 |
328 |
329 | | 44 |
330 | 0x2C |
331 | Player leds |
332 |
333 |
334 | 0b00000 - OFF
335 | 0b00100 - CENTER
336 | 0b01010 - INNER
337 | 0b10001 - OUTER
338 | 0b11111 - ALL
339 |
340 | |
341 |
342 | CENTER: The single, center LED.
343 | INNER: The two LEDs adjacent to and directly surrounding the CENTER LED.
344 | OUTER: The two outermost LEDs surrounding the INNER LEDs.
345 | |
346 |
347 |
348 | | 45 |
349 | 0x2D |
350 | Lightbar led color red |
351 |
352 | 0 - 255
353 | |
354 | |
355 |
356 |
357 | | 46 |
358 | 0x2E |
359 | Lightbar led color green |
360 |
361 | 0 - 255
362 | |
363 | |
364 |
365 |
366 | | 47 |
367 | 0x2F |
368 | Lightbar led color blue |
369 |
370 | 0 - 255
371 | |
372 | |
373 |
374 |
375 |
--------------------------------------------------------------------------------
/src/dualsense_controller/core/state/mapping/StateValueMapper.py:
--------------------------------------------------------------------------------
1 | from functools import partial
2 | from typing import Final
3 |
4 | from dualsense_controller.core.state.mapping.common import Float, FromTo, Integer, StateValueMappingData
5 | from dualsense_controller.core.state.mapping.enum import StateValueMapping
6 | from dualsense_controller.core.state.mapping.typedef import FromToTuple, MapFn
7 | from dualsense_controller.core.state.read_state.value_type import JoyStick
8 | from dualsense_controller.core.state.typedef import Number
9 |
10 | _NumberType = Float | Integer
11 |
12 |
13 | class StateValueMapper:
14 |
15 | @staticmethod
16 | def _number_map(value: float, in_min: float, in_max: float, out_min: float, out_max: float) -> float | None:
17 | if value is None:
18 | return None
19 | if in_min == out_min and in_max == out_max:
20 | return value
21 | return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
22 |
23 | @classmethod
24 | def _number_raw_to_mapped(cls, from_to: FromTo | None, value: Number | None) -> Number:
25 | if value is None:
26 | return None
27 | if from_to is None:
28 | return value
29 | to_type: _NumberType = from_to.to_type
30 | value_type: Number = to_type.value_type
31 | from_to_tuple: FromToTuple = from_to.as_tuple
32 | mapped_value: Number = value_type(cls._number_map(value, *from_to_tuple))
33 | if isinstance(mapped_value, float):
34 | mapped_value = round(mapped_value, to_type.round_digits)
35 | return mapped_value
36 |
37 | @classmethod
38 | def _number_mapped_to_raw(cls, from_to: FromTo, value: Number) -> Number:
39 | if from_to is None:
40 | return value
41 | raw_value: int = int(cls._number_map(value, *from_to.swapped.as_tuple))
42 | return raw_value
43 |
44 | @classmethod
45 | def _joystick_mapped_to_raw(cls, from_to: FromTo, value: JoyStick) -> JoyStick:
46 | return JoyStick(
47 | x=cls._number_mapped_to_raw(from_to, value.x),
48 | y=cls._number_mapped_to_raw(from_to, value.y)
49 | )
50 |
51 | @classmethod
52 | def _joystick_raw_to_mapped(
53 | cls,
54 | from_to_x: FromTo,
55 | from_to_y: FromTo,
56 | value: JoyStick,
57 | ) -> JoyStick:
58 | return JoyStick(
59 | x=cls._number_raw_to_mapped(from_to_x, value.x),
60 | y=cls._number_raw_to_mapped(from_to_y, value.y),
61 | )
62 |
63 | @property
64 | def mapping_data(self) -> StateValueMappingData | None:
65 | return self._mapping_data
66 |
67 | def __init__(
68 | self,
69 | mapping: StateValueMapping,
70 | left_joystick_deadzone: Number = 0,
71 | right_joystick_deadzone: Number = 0,
72 | left_trigger_deadzone: Number = 0,
73 | right_trigger_deadzone: Number = 0,
74 | gyroscope_threshold: int = 0,
75 | accelerometer_threshold: int = 0,
76 | orientation_threshold: int = 0,
77 | ):
78 |
79 | self.left_stick_deadzone_mapped: Final[Number] = left_joystick_deadzone
80 | self.right_stick_deadzone_mapped: Final[Number] = right_joystick_deadzone
81 | self.left_trigger_deadzone_mapped: Final[Number] = left_trigger_deadzone
82 | self.right_trigger_deadzone_mapped: Final[Number] = right_trigger_deadzone
83 | self.gyroscope_threshold_mapped: Final[int] = gyroscope_threshold
84 | self.accelerometer_threshold_mapped: Final[int] = accelerometer_threshold
85 | self.orientation_threshold_mapped: Final[int] = orientation_threshold
86 |
87 | self._mapping_data: StateValueMappingData = mapping.value
88 | if isinstance(self._mapping_data, tuple):
89 | self._mapping_data = self._mapping_data[0]
90 |
91 | # #################################################### DEADZONE AND THRESHOLD ###############################
92 | self.left_stick_deadzone_mapped_to_raw: Number = (
93 | left_joystick_deadzone if self._mapping_data is None else self._number_mapped_to_raw(
94 | self._mapping_data.left_stick_deadzone,
95 | left_joystick_deadzone
96 | )
97 | )
98 | self.right_stick_deadzone_mapped_to_raw: Number = (
99 | right_joystick_deadzone if self._mapping_data is None else self._number_mapped_to_raw(
100 | self._mapping_data.right_stick_deadzone,
101 | right_joystick_deadzone
102 | )
103 | )
104 | self.left_trigger_deadzone_mapped_to_raw: Number = (
105 | left_trigger_deadzone if self._mapping_data is None else self._number_mapped_to_raw(
106 | self._mapping_data.left_trigger_deadzone,
107 | left_trigger_deadzone
108 | )
109 | )
110 | self.right_trigger_deadzone_mapped_to_raw: Number = (
111 | right_trigger_deadzone if self._mapping_data is None else self._number_mapped_to_raw(
112 | self._mapping_data.right_trigger_deadzone,
113 | right_trigger_deadzone
114 | )
115 | )
116 | self.gyroscope_threshold_mapped_to_raw: Number = (
117 | gyroscope_threshold if self._mapping_data is None else self._number_mapped_to_raw(
118 | self._mapping_data.right_trigger_deadzone,
119 | gyroscope_threshold
120 | )
121 | )
122 | self.accelerometer_threshold_mapped_to_raw: Number = (
123 | accelerometer_threshold if self._mapping_data is None else self._number_mapped_to_raw(
124 | self._mapping_data.right_trigger_deadzone,
125 | accelerometer_threshold
126 | )
127 | )
128 | self.orientation_threshold_mapped_to_raw: Number = (
129 | orientation_threshold if self._mapping_data is None else self._number_mapped_to_raw(
130 | self._mapping_data.right_trigger_deadzone,
131 | orientation_threshold
132 | )
133 | )
134 |
135 | # #################################################### JOYSTICKS ###############################
136 | self.left_stick_x_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
137 | self._number_raw_to_mapped,
138 | self._mapping_data.left_stick_x,
139 | )
140 | self.left_stick_x_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
141 | self._number_mapped_to_raw,
142 | self._mapping_data.left_stick_x
143 | )
144 | self.left_stick_y_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
145 | self._number_raw_to_mapped,
146 | self._mapping_data.left_stick_y,
147 | )
148 | self.left_stick_y_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
149 | self._number_mapped_to_raw,
150 | self._mapping_data.left_stick_y
151 | )
152 | self.left_stick_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
153 | self._joystick_raw_to_mapped,
154 | self._mapping_data.left_stick_x,
155 | self._mapping_data.left_stick_y,
156 | )
157 | self.left_stick_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
158 | self._joystick_mapped_to_raw,
159 | self._mapping_data.left_stick_x,
160 | self._mapping_data.left_stick_y,
161 | )
162 | self.right_stick_x_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
163 | self._number_raw_to_mapped,
164 | self._mapping_data.right_stick_x,
165 | )
166 | self.right_stick_x_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
167 | self._number_mapped_to_raw,
168 | self._mapping_data.right_stick_x
169 | )
170 | self.right_stick_y_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
171 | self._number_raw_to_mapped,
172 | self._mapping_data.right_stick_y,
173 | )
174 | self.right_stick_y_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
175 | self._number_mapped_to_raw,
176 | self._mapping_data.right_stick_y
177 | )
178 | self.right_stick_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
179 | self._joystick_raw_to_mapped,
180 | self._mapping_data.right_stick_x,
181 | self._mapping_data.right_stick_y,
182 | )
183 | self.right_stick_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
184 | self._joystick_mapped_to_raw,
185 | self._mapping_data.right_stick_x,
186 | self._mapping_data.right_stick_y,
187 | )
188 |
189 | # #################################################### TRIGGERS ###############################
190 | self.left_trigger_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
191 | self._number_raw_to_mapped,
192 | self._mapping_data.left_trigger
193 | )
194 | self.left_trigger_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
195 | self._number_mapped_to_raw,
196 | self._mapping_data.left_trigger
197 | )
198 | self.right_trigger_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
199 | self._number_raw_to_mapped,
200 | self._mapping_data.right_trigger
201 | )
202 | self.right_trigger_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
203 | self._number_mapped_to_raw,
204 | self._mapping_data.right_trigger
205 | )
206 |
207 | # #################################################### MOTORS ###############################
208 | self.set_left_motor_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
209 | self._number_mapped_to_raw,
210 | self._mapping_data.set_motor_left
211 | )
212 | self.set_left_motor_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
213 | self._number_raw_to_mapped,
214 | self._mapping_data.set_motor_left
215 | )
216 | self.set_right_motor_mapped_to_raw: MapFn | None = None if self._mapping_data is None else partial(
217 | self._number_mapped_to_raw,
218 | self._mapping_data.set_motor_right
219 | )
220 | self.set_right_motor_raw_to_mapped: MapFn | None = None if self._mapping_data is None else partial(
221 | self._number_raw_to_mapped,
222 | self._mapping_data.set_motor_right
223 | )
224 |
--------------------------------------------------------------------------------