Developer Referenceinput_handler
GamepadMapper
Maps client (browser Gamepad API) button/axis indices onto the fixed Xbox-pad model in STANDARD_XPAD_CONFIG, producing both joydev and evdev event payloads.
Attributes
attributeconfig= config_templateattributeclient_input_name= client_input_nameFunctions
func__init__(self, config_template, client_input_name, client_num_btns, client_num_axes) -> NoneSource Code
def __init__(self, config_template: dict, client_input_name: str,
client_num_btns: int, client_num_axes: int) -> None:
self.config = config_template
self.client_input_name = client_input_nameparamselfparamconfig_templatedictparamclient_input_namestrparamclient_num_btnsintparamclient_num_axesintReturns
Nonefuncget_mapped_events(self, client_event_idx, client_value, is_button_event) -> Optional[dict]Translate one client control change into wire-ready event payloads.
Source Code
def get_mapped_events(self, client_event_idx: int, client_value: float,
is_button_event: bool) -> Optional[dict]:
"""Translate one client control change into wire-ready event payloads.
Args:
client_event_idx: Client button or axis index.
client_value: The control's new value (see normalize_axis_value).
is_button_event: True for a button, False for an axis.
Returns:
`{'js_event_data': bytes, 'evdev_event_template': (type, code,
value)}`, or None when the control has no mapping.
"""
internal_abstract_idx = -1
is_trigger_axis = False
is_hat_axis = False
target_evdev_type = None
final_value = 0
if is_button_event:
if client_event_idx in self.config["mapping"]["dpad_to_hat"]:
internal_abstract_idx, hat_direction_value = self.config["mapping"]["dpad_to_hat"][client_event_idx]
is_hat_axis = True
target_evdev_type = EV_ABS
final_value = hat_direction_value * int(client_value)
elif client_event_idx in self.config["mapping"]["client_btns_to_internal_axes"]:
internal_abstract_idx = self.config["mapping"]["client_btns_to_internal_axes"][client_event_idx]
is_trigger_axis = internal_abstract_idx in self.config["mapping"]["trigger_internal_abstract_axis_indices"]
target_evdev_type = EV_ABS
final_value = client_value
else:
internal_abstract_idx = self.config["mapping"]["btns"].get(client_event_idx)
target_evdev_type = EV_KEY
final_value = int(client_value)
else:
internal_abstract_idx = self.config["mapping"]["axes"].get(client_event_idx)
is_trigger_axis = internal_abstract_idx in self.config["mapping"]["trigger_internal_abstract_axis_indices"]
is_hat_axis = internal_abstract_idx in self.config["mapping"]["hat_internal_abstract_axis_indices"]
target_evdev_type = EV_ABS
final_value = client_value
if internal_abstract_idx is None or internal_abstract_idx < 0:
return None
evdev_code = -1
js_event_value = 0
evdev_event_value = 0
if target_evdev_type == EV_KEY:
if 0 <= internal_abstract_idx < len(self.config["btn_map"]):
evdev_code = self.config["btn_map"][internal_abstract_idx]
js_event_value = evdev_event_value = final_value
else: return None
elif target_evdev_type == EV_ABS:
if 0 <= internal_abstract_idx < len(self.config["axes_map"]):
evdev_code = self.config["axes_map"][internal_abstract_idx]
js_event_value = normalize_axis_value(final_value, is_trigger_axis, is_hat_axis, for_js_event=True)
evdev_event_value = normalize_axis_value(final_value, is_trigger_axis, is_hat_axis, for_js_event=False)
else: return None
else:
return None
if evdev_code != -1:
js_event_type = JS_EVENT_BUTTON if target_evdev_type == EV_KEY else JS_EVENT_AXIS
js_event_data = get_js_event_packed(js_event_type, internal_abstract_idx, js_event_value)
evdev_event_template = (target_evdev_type, evdev_code, evdev_event_value)
return {'js_event_data': js_event_data, 'evdev_event_template': evdev_event_template}
return Noneparamselfparamclient_event_idxintClient button or axis index.
paramclient_valuefloatThe control's new value (see normalize_axis_value).
paramis_button_eventboolTrue for a button, False for an axis.
Returns
typing.Optional`{'js_event_data': bytes, 'evdev_event_template': (type, code,