199 lines
4.8 KiB
Python
199 lines
4.8 KiB
Python
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,
|
|
# }
|