import ctypes from . import ecodes _u8 = ctypes.c_uint8 _u16 = ctypes.c_uint16 _u32 = ctypes.c_uint32 _s16 = ctypes.c_int16 _s32 = ctypes.c_int32 class Replay(ctypes.Structure): """ Defines scheduling of the force-feedback effect @length: duration of the effect @delay: delay before effect should start playing """ _fields_ = [ ("length", _u16), ("delay", _u16), ] class Trigger(ctypes.Structure): """ Defines what triggers the force-feedback effect @button: number of the button triggering the effect @interval: controls how soon the effect can be re-triggered """ _fields_ = [ ("button", _u16), ("interval", _u16), ] class Envelope(ctypes.Structure): """ Generic force-feedback effect envelope @attack_length: duration of the attack (ms) @attack_level: level at the beginning of the attack @fade_length: duration of fade (ms) @fade_level: level at the end of fade The @attack_level and @fade_level are absolute values; when applying envelope force-feedback core will convert to positive/negative value based on polarity of the default level of the effect. Valid range for the attack and fade levels is 0x0000 - 0x7fff """ _fields_ = [ ("attack_length", _u16), ("attack_level", _u16), ("fade_length", _u16), ("fade_level", _u16), ] class Constant(ctypes.Structure): """ Defines parameters of a constant force-feedback effect @level: strength of the effect; may be negative @envelope: envelope data """ _fields_ = [ ("level", _s16), ("ff_envelope", Envelope), ] class Ramp(ctypes.Structure): """ Defines parameters of a ramp force-feedback effect @start_level: beginning strength of the effect; may be negative @end_level: final strength of the effect; may be negative @envelope: envelope data """ _fields_ = [ ("start_level", _s16), ("end_level", _s16), ("ff_envelope", Envelope), ] class Condition(ctypes.Structure): """ Defines a spring or friction force-feedback effect @right_saturation: maximum level when joystick moved all way to the right @left_saturation: same for the left side @right_coeff: controls how fast the force grows when the joystick moves to the right @left_coeff: same for the left side @deadband: size of the dead zone, where no force is produced @center: position of the dead zone """ _fields_ = [ ("right_saturation", _u16), ("left_saturation", _u16), ("right_coeff", _s16), ("left_coeff", _s16), ("deadband", _u16), ("center", _s16), ] class Periodic(ctypes.Structure): """ Defines parameters of a periodic force-feedback effect @waveform: kind of the effect (wave) @period: period of the wave (ms) @magnitude: peak value @offset: mean value of the wave (roughly) @phase: 'horizontal' shift @envelope: envelope data @custom_len: number of samples (FF_CUSTOM only) @custom_data: buffer of samples (FF_CUSTOM only) """ _fields_ = [ ("waveform", _u16), ("period", _u16), ("magnitude", _s16), ("offset", _s16), ("phase", _u16), ("envelope", Envelope), ("custom_len", _u32), ("custom_data", ctypes.POINTER(_s16)), ] class Rumble(ctypes.Structure): """ Defines parameters of a periodic force-feedback effect @strong_magnitude: magnitude of the heavy motor @weak_magnitude: magnitude of the light one Some rumble pads have two motors of different weight. Strong_magnitude represents the magnitude of the vibration generated by the heavy one. """ _fields_ = [ ("strong_magnitude", _u16), ("weak_magnitude", _u16), ] class EffectType(ctypes.Union): _fields_ = [ ("ff_constant_effect", Constant), ("ff_ramp_effect", Ramp), ("ff_periodic_effect", Periodic), ("ff_condition_effect", Condition * 2), # one for each axis ("ff_rumble_effect", Rumble), ] class Effect(ctypes.Structure): _fields_ = [ ("type", _u16), ("id", _s16), ("direction", _u16), ("ff_trigger", Trigger), ("ff_replay", Replay), ("u", EffectType), ] class UInputUpload(ctypes.Structure): _fields_ = [ ("request_id", _u32), ("retval", _s32), ("effect", Effect), ("old", Effect), ] class UInputErase(ctypes.Structure): _fields_ = [ ("request_id", _u32), ("retval", _s32), ("effect_id", _u32), ] # ff_types = { # ecodes.FF_CONSTANT, # ecodes.FF_PERIODIC, # ecodes.FF_RAMP, # ecodes.FF_SPRING, # ecodes.FF_FRICTION, # ecodes.FF_DAMPER, # ecodes.FF_RUMBLE, # ecodes.FF_INERTIA, # ecodes.FF_CUSTOM, # }