Skip to content

Commit

Permalink
add argument for logging effects
Browse files Browse the repository at this point in the history
  • Loading branch information
Kethen committed Aug 26, 2024
1 parent 1bcb54f commit b86c7da
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 19 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ start driver on wheel:
[-c <0/1/2>]
play effect on upload, for 'Fast' update type in BeamNG.drive:
[-u]
log effects
[-v]
```

### Usage Examples
Expand Down Expand Up @@ -167,6 +169,7 @@ range: 900
hide effects: false
combine pedals: 0
play effect on upload: false
log effects: false
sent range setting command for range 900
sent auto center disable command
Expand Down
9 changes: 5 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ then
$CC -g -c switch_mode.c -o switch_mode.o
$CC -g -c configure.c -o configure.o
$CC -g -c force_feedback.c -o force_feedback.o
$CC -g -c log_effect.c -o log_effect.o
$CC -g -c main.c -o main.o
$CC probe.o device_ids.o driver_loops.o switch_mode.o configure.o force_feedback.o main.o -o lg4ff_userspace -lhidapi-hidraw -lm
$CC probe.o device_ids.o driver_loops.o switch_mode.o configure.o force_feedback.o main.o -o lg4ff_userspace_usb -lhidapi-libusb -lm
$CC probe.o device_ids.o driver_loops.o switch_mode.o configure.o force_feedback.o log_effect.o main.o -o lg4ff_userspace -lhidapi-hidraw -lm
$CC probe.o device_ids.o driver_loops.o switch_mode.o configure.o force_feedback.o log_effect.o main.o -o lg4ff_userspace_usb -lhidapi-libusb -lm
else
$CC probe.c device_ids.c driver_loops.c switch_mode.c configure.c force_feedback.c main.c -O2 -o lg4ff_userspace -lhidapi-hidraw -lm
$CC probe.c device_ids.c driver_loops.c switch_mode.c configure.c force_feedback.c main.c -O2 -o lg4ff_userspace_usb -lhidapi-libusb -lm
$CC probe.c device_ids.c driver_loops.c switch_mode.c configure.c force_feedback.c log_effect.c main.c -O2 -o lg4ff_userspace -lhidapi-hidraw -lm
$CC probe.c device_ids.c driver_loops.c switch_mode.c configure.c force_feedback.c log_effect.c main.c -O2 -o lg4ff_userspace_usb -lhidapi-libusb -lm
fi

rm -f *.o
6 changes: 3 additions & 3 deletions driver_loops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ static void *uinput_poll_loop(void *arg){
}
default:{
pthread_mutex_lock(&loop_context->device_mutex);
lg4ff_play_effect(&loop_context->ffb_device, e.code, e.value);
lg4ff_play_effect(&loop_context->ffb_device, e.code, e.value, loop_context->context.log_effects);
pthread_mutex_unlock(&loop_context->device_mutex);
}
}
Expand All @@ -1027,9 +1027,9 @@ static void *uinput_poll_loop(void *arg){
upload.request_id = e.value;
ioctl(loop_context->uinput_fd, UI_BEGIN_FF_UPLOAD, &upload);
pthread_mutex_lock(&loop_context->device_mutex);
upload.retval = lg4ff_upload_effect(&loop_context->ffb_device, &upload.effect, &upload.old);
upload.retval = lg4ff_upload_effect(&loop_context->ffb_device, &upload.effect, &upload.old, loop_context->context.log_effects);
if(loop_context->context.play_on_upload && upload.retval == 0){
lg4ff_play_effect(&loop_context->ffb_device, upload.effect.id, 1);
lg4ff_play_effect(&loop_context->ffb_device, upload.effect.id, 1, loop_context->context.log_effects);
}
pthread_mutex_unlock(&loop_context->device_mutex);
ioctl(loop_context->uinput_fd, UI_END_FF_UPLOAD, &upload);
Expand Down
1 change: 1 addition & 0 deletions driver_loops.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct loop_context{
bool hide_effects;
int combine_pedals;
bool play_on_upload;
bool log_effects;
};

void start_loops(struct loop_context context);
Expand Down
14 changes: 12 additions & 2 deletions force_feedback.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "logging.h"
#include "force_feedback.h"
#include "log_effect.h"

#define test_bit(bit, field) (*(field) & (1 << bit))
#define __set_bit(bit, field) {*(field) = *(field) | (1 << bit);}
Expand Down Expand Up @@ -42,7 +43,7 @@ uint64_t get_time_ms(){
return tp.tv_nsec / 1000000 + tp.tv_sec * 1000;
}

int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, struct ff_effect *old)
int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, struct ff_effect *old, bool log)
{
struct lg4ff_effect_state *state;
uint64_t now = get_time_ms();
Expand All @@ -64,10 +65,15 @@ int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, s
state->updated_at = now;
}

if(log){
STDOUT("--upload--\n");
log_effect(effect);
}

return 0;
}

int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value)
int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value, bool log)
{
struct lg4ff_effect_state *state;
uint64_t now = get_time_ms();
Expand All @@ -83,6 +89,10 @@ int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value)
__set_bit(FF_EFFECT_STARTED, &state->flags);
state->start_at = now;
state->count = value;
if(log){
STDOUT("--play--\n");
log_effect(&state->effect);
}
} else {
if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
STOP_EFFECT(state);
Expand Down
23 changes: 21 additions & 2 deletions force_feedback.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ struct ff_effect{
} 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
Expand Down Expand Up @@ -157,8 +176,8 @@ struct lg4ff_device{
};

void lg4ff_init_slots(struct lg4ff_device *device);
int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, struct ff_effect *old);
int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value);
int lg4ff_upload_effect(struct lg4ff_device *device, struct ff_effect *effect, struct ff_effect *old, bool log);
int lg4ff_play_effect(struct lg4ff_device *device, int effect_id, int value, bool log);
int lg4ff_timer(struct lg4ff_device *device);

#endif
76 changes: 76 additions & 0 deletions log_effect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <stdlib.h>

#include "force_feedback.h"
#include "logging.h"

#define STR(s) #s

static void log_envelope(struct ff_envelope *e){
}

void log_effect(struct ff_effect *e){
const char *effect_name = NULL;
#define EFFECT_NAME(n) case FF_##n: effect_name = STR(n); break;
switch(e->type){
EFFECT_NAME(RUMBLE);
EFFECT_NAME(PERIODIC);
EFFECT_NAME(CONSTANT);
EFFECT_NAME(SPRING);
EFFECT_NAME(FRICTION);
EFFECT_NAME(DAMPER);
EFFECT_NAME(INERTIA);
EFFECT_NAME(RAMP);
default:
STDERR("unknown effect type 0x%04x\n", e->type);
exit(1);
}
#undef EFFECT_NAME
STDOUT("--effect %s, id %d--\n", effect_name, e->id);
STDOUT("direction: 0x%04x\n", e->direction);
STDOUT("trigger: button 0x%04x, interval %d\n", e->trigger.button, e->trigger.interval);
STDOUT("replay: length %d, delay %d\n", e->replay.length, e->replay.delay);

#define LOG_ENVELOPE(_e) STDOUT("envelope: attack length %d, attack level %d, fade length %d, fade level %d\n", _e.attack_length, _e.attack_level, _e.fade_length, _e.fade_level);

switch(e->type){
case FF_RUMBLE:
STDOUT("rumble: strong magnitude %d, weak magnitude %d\n", e->u.rumble.strong_magnitude, e->u.rumble.weak_magnitude);
break;
case FF_PERIODIC:
const char *periodic_name = 0;
#define PERIODIC_NAME(n) case FF_##n: periodic_name = STR(n); break;
switch(e->u.periodic.waveform){
PERIODIC_NAME(SQUARE);
PERIODIC_NAME(TRIANGLE);
PERIODIC_NAME(SINE);
PERIODIC_NAME(SAW_UP);
PERIODIC_NAME(SAW_DOWN);
PERIODIC_NAME(CUSTOM);
default:
STDERR("unknown waveform 0x%04x\n", e->u.periodic.waveform)
exit(1);
}
#undef PERIODIC_NAME
STDOUT("periodic: waveform %s, period %d, magnitude %d, offset %d, phase %d, custom len %d, custom 0x%016x\n", periodic_name, e->u.periodic.period, e->u.periodic.magnitude, e->u.periodic.offset, e->u.periodic.phase, e->u.periodic.custom_len, e->u.periodic.custom_data);
LOG_ENVELOPE(e->u.periodic.envelope);
break;
case FF_CONSTANT:
STDOUT("constant: level %d\n", e->u.constant.level);
LOG_ENVELOPE(e->u.constant.envelope);
break;
case FF_SPRING:
case FF_FRICTION:
case FF_DAMPER:
case FF_INERTIA:
for(int i = 0; i < 2; i++){
STDOUT("condition #%d: right saturation %d, left saturation %d, right coeff %d, left coeff %d, deadband %d, center %d\n", i, e->u.condition[i].right_saturation, e->u.condition[i].left_saturation, e->u.condition[i].right_coeff, e->u.condition[i].left_coeff, e->u.condition[i].deadband, e->u.condition[i].center);
}
break;
case FF_RAMP:
STDOUT("ramp: start level %d, end level %d\n", e->u.ramp.start_level, e->u.ramp.end_level);
LOG_ENVELOPE(e->u.ramp.envelope);
break;
}

#undef LOG_ENVELOPE
}
6 changes: 6 additions & 0 deletions log_effect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef __LOG_EFFECT_H
#include "force_feedback.h"

void log_effect(struct ff_effect *e);

#endif
10 changes: 7 additions & 3 deletions logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
#define __LOGGING_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define STDOUT(...){ \
fprintf(stdout, __VA_ARGS__); \
char _log_buf[512]; \
int _log_len = sprintf(_log_buf, __VA_ARGS__); \
write(1, _log_buf, _log_len); \
}

#define STDERR(...){ \
fprintf(stderr, __VA_ARGS__); \
char _log_buf[512]; \
int _log_len = sprintf(_log_buf, __VA_ARGS__); \
write(2, _log_buf, _log_len); \
}

#endif
20 changes: 15 additions & 5 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ static void print_help(char *binary_name){
STDOUT(" combine pedals, 0 for not combining any, 1 for combining gas and brake, 2 for combining gas and clutch, defaults to 0:\n");
STDOUT(" [-c <0/1/2>]\n");
STDOUT(" play effect on upload, for 'Fast' update type in BeamNG.drive:\n");
STDOUT(" [-u]\n")
STDOUT(" [-u]\n");
STDOUT(" log effects\n");
STDOUT(" [-v]\n");
}

enum operation_mode{
Expand Down Expand Up @@ -111,7 +113,9 @@ static int start_driver(
int range,
bool hide_effects,
int combine_pedals,
bool play_on_upload){
bool play_on_upload,
bool log_effects
){
list_devices(hidraw_devices, wheels);
STDOUT("starting driver on wheel %d\n", wheel_num);
STDOUT("gain: %d\n", gain);
Expand All @@ -123,6 +127,7 @@ static int start_driver(
STDOUT("hide effects: %s\n", hide_effects? "true": "false");
STDOUT("combine pedals: %d\n", combine_pedals);
STDOUT("play effect on upload: %s\n", play_on_upload? "true" : "false");
STDOUT("log effects: %s\n", log_effects? "true" : "false");

struct loop_context lc = {
.device = hidraw_devices[wheel_num - 1],
Expand All @@ -134,7 +139,8 @@ static int start_driver(
.range = range,
.hide_effects = hide_effects,
.combine_pedals = combine_pedals,
.play_on_upload = play_on_upload
.play_on_upload = play_on_upload,
.log_effects = log_effects
};
start_loops(lc);

Expand Down Expand Up @@ -163,8 +169,9 @@ int main(int argc, char** argv){
bool hide_effects = false;
int combine_pedals = 0;
bool play_on_upload = false;
bool log_effects = false;

while ((opt = getopt(argc, argv, "lhm:n:wg:a:s:d:f:r:Hc:u")) != -1){
while ((opt = getopt(argc, argv, "lhm:n:wg:a:s:d:f:r:Hc:uv")) != -1){
#define CLAMP_ARG_VALUE(name, field, min, max){ \
if(field > max){ \
field = max; \
Expand Down Expand Up @@ -239,6 +246,9 @@ int main(int argc, char** argv){
case 'u':
play_on_upload = true;
break;
case 'v':
log_effects = true;
break;
default:
print_help(argv[0]);
return 0;
Expand All @@ -264,7 +274,7 @@ int main(int argc, char** argv){
reboot_wheel(hidraw_devices, wheels_found, device_number, wmode);
return 0;
case OPERATION_MODE_DRIVER:
start_driver(hidraw_devices, wheels_found, device_number, gain, auto_center, spring_level, damper_level, friction_level, range, hide_effects, combine_pedals, play_on_upload);
start_driver(hidraw_devices, wheels_found, device_number, gain, auto_center, spring_level, damper_level, friction_level, range, hide_effects, combine_pedals, play_on_upload, log_effects);
return 0;
default:
print_help(argv[0]);
Expand Down

0 comments on commit b86c7da

Please sign in to comment.