def __init__(self, device):
        self.device = device

        self.x = 0
        self.y = 0
        self.z = 0
        self.rx = 0
        self.ry = 0
        self.rz = 0
        self.hat_x = 0
        self.hat_y = 0
        self.buttons = []

        self.x_control = None
        self.y_control = None
        self.z_control = None
        self.rx_control = None
        self.ry_control = None
        self.rz_control = None
        self.hat_x_control = None
        self.hat_y_control = None
        self.button_controls = []

        def add_axis(control):
            name = control.name
            scale = 2.0 / (control.max - control.min)
            bias = -1.0 - control.min * scale
            if control.inverted:
                scale = -scale
                bias = -bias
            setattr(self, name + '_control', control)

            @control.event
            def on_change(value):
                setattr(self, name, value * scale + bias)

        def add_button(control):
            i = len(self.buttons)
            self.buttons.append(False)
            self.button_controls.append(control)

            @control.event
            def on_change(value):
                self.buttons[i] = value

        def add_hat(control):
            # 8-directional hat encoded as a single control (Windows/Mac)
            self.hat_x_control = control
            self.hat_y_control = control
            
            @control.event
            def on_change(value):
                if value & 0xffff == 0xffff:
                    self.hat_x = self.hat_y = 0
                else:
                    if control.max > 8: # DirectInput: scale value
                        value //= 0xfff
                    if 0 <= value < 8:
                        self.hat_x, self.hat_y = (
                            ( 0,  1),
                            ( 1,  1),
                            ( 1,  0),
                            ( 1, -1),
                            ( 0, -1),
                            (-1, -1),
                            (-1,  0),
                            (-1,  1),
                        )[value]
                    else:
                        # Out of range
                        self.hat_x = self.hat_y = 0

        for control in device.get_controls():
            if isinstance(control, AbsoluteAxis):
                if control.name in ('x', 'y', 'z', 'rx', 'ry', 'rz', 
                                    'hat_x', 'hat_y'):
                    add_axis(control)
                elif control.name == 'hat':
                    add_hat(control)
            elif isinstance(control, Button):
                add_button(control)
dataset/ETHPy150Open ardekantur/pyglet/pyglet/input/base.py/Joystick.__init__/original