-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathforce_feedback.h
183 lines (148 loc) · 3.48 KB
/
force_feedback.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#ifndef __FORCE_FEEDBACK_H
#define __FORCE_FEEDBACK_H
#include <stdint.h>
#include <stdbool.h>
#include <hidapi/hidapi.h>
#define LG4FF_MAX_EFFECTS 16
#define FF_EFFECT_STARTED 0
#define FF_EFFECT_ALLSET 1
#define FF_EFFECT_PLAYING 2
#define FF_EFFECT_UPDATING 3
#if __linux__
#include <linux/input.h>
#else
// from the linux kernel source, include/uapi/linux/input.h
// required for dealing with linux uinput, should be easily adapted to dinput8 as well since they are pretty similar, if you really want to write a virtual driver for windows as well
struct ff_envelope{
uint16_t attack_length;
uint16_t attack_level;
uint16_t fade_length;
uint16_t fade_level;
};
struct ff_rumble_effect{
uint16_t strong_magnitude;
uint16_t weak_magnitude;
};
struct ff_condition_effect{
uint16_t right_saturation;
uint16_t left_saturation;
int16_t right_coeff;
int16_t left_coeff;
uint16_t deadband;
int16_t center;
};
struct ff_periodic_effect{
uint16_t waveform;
uint16_t period;
int16_t magnitude;
int16_t offset;
uint16_t phase;
struct ff_envelope envelope;
uint32_t custom_len;
int16_t *custom_data;
};
struct ff_ramp_effect{
int16_t start_level;
int16_t end_level;
struct ff_envelope;
};
struct ff_constant_effect{
int16_t level;
struct ff_envelope;
};
struct ff_trigger{
uint16_t button;
uint16_t interval;
};
struct ff_replay{
uint16_t length;
uint16_t delay;
};
struct ff_effect{
uint16_t type;
int16_t id;
uint16_t direction;
struct ff_trigger trigger;
struct ff_replay replay;
union {
struct ff_constant_effect constant;
struct ff_ramp_effect ramp;
struct ff_periodic_effect periodic;
struct ff_condition_effect condition[2];
struct ff_rumble_effect rumble;
} u;
};
#define FF_RUMBLE 0x50
#define FF_PERIODIC 0x51
#define FF_CONSTANT 0x52
#define FF_SPRING 0x53
#define FF_FRICTION 0x54
#define FF_DAMPER 0x55
#define FF_INERTIA 0x56
#define FF_RAMP 0x57
#define FF_SQUARE 0x58
#define FF_TRIANGLE 0x59
#define FF_SINE 0x5a
#define FF_SAW_UP 0x5b
#define FF_SAW_DOWN 0x5c
#define FF_CUSTOM 0x5d
#define FF_GAIN 0x60
#define FF_AUTOCENTER 0x61
#endif
// ported from https://github.com/berarma/new-lg4ff/blob/master/hid-lg4ff.c
// effect state tracking before wheel rendering
struct lg4ff_effect_state{
struct ff_effect effect;
struct ff_envelope *envelope;
uint64_t start_at;
uint64_t play_at;
uint64_t stop_at;
uint32_t flags;
uint64_t time_playing;
uint64_t updated_at;
uint32_t phase;
uint32_t phase_adj;
uint32_t count;
// unused?
#if 0
uint32_t cmd;
uint64_t cmd_start_time;
uint32_t cmd_start_count;
#endif
double direction_gain;
int32_t slope;
};
struct lg4ff_effect_parameters{
int32_t level;
int32_t d1;
int32_t d2;
int32_t k1;
int32_t k2;
uint32_t clip;
};
struct lg4ff_slot{
int32_t id;
struct lg4ff_effect_parameters parameters;
uint8_t current_cmd[7];
uint32_t cmd_op;
bool is_updated;
int32_t effect_type;
};
struct lg4ff_device{
uint16_t product_id;
struct lg4ff_effect_state states[LG4FF_MAX_EFFECTS];
struct lg4ff_slot slots[4];
int32_t effects_used;
int32_t gain;
int32_t app_gain;
int32_t spring_level;
int32_t damper_level;
int32_t friction_level;
int32_t peak_ffb_level;
hid_device *hid_handle;
};
void lg4ff_init_slots(struct lg4ff_device *device);
int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, struct ff_effect *old, bool log, bool play_on_upload);
int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value, bool log);
int lg4ff_timer(struct lg4ff_device *device);
#endif