Files
2025-11-01 06:09:32 +05:30

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,
# }