Skip to content

Commit

Permalink
Auto-adjust emulated controller frequency #635
Browse files Browse the repository at this point in the history
  • Loading branch information
matlo committed Oct 4, 2019
1 parent b994e92 commit 2f429bb
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 31 deletions.
21 changes: 13 additions & 8 deletions core/controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ void adapter_init_static(void)
}
adapters[i].status = 0;
adapters[i].joystick = -1;
adapters[i].mfrequency = -1;
adapters[i].mperiod = -1;
}
for(j=0; j<E_DEVICE_TYPE_NB; ++j)
{
Expand Down Expand Up @@ -1115,13 +1115,18 @@ int adapter_send()
haptic_core_update(adapter->ff_core);
}

if (adapter->mfrequency == -1 && adapter->mstats != NULL) {
adapter->mfrequency = stats_get_frequency(adapter->mstats);
if (adapter->mfrequency != -1) {
int rfrequency = 2 * 1000000 / gimx_params.refresh_period;
if (adapter->mfrequency < rfrequency) {
gwarn(_("Expect jerky movements: mouse frequency is only %dHz.\n"), adapter->mfrequency);
gwarn(_("Required mouse frequency is %dHz.\n"), rfrequency);
if (adapter->mperiod == -1 && adapter->mstats != NULL)
{
adapter->mperiod = stats_get_period(adapter->mstats);
if (adapter->mperiod != -1)
{
ginfo(_("Mouse frequency is %dHz.\n"), 1000000 / adapter->mperiod);
if (adapter->mperiod >= gimx_params.refresh_period)
{
while (gimx_params.refresh_period <= adapter->mperiod)
{
gimx_params.refresh_period += 1000;
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ typedef struct {
} inactivity;
struct stats * cstats;
struct stats * mstats;
int mfrequency;
int mperiod;
} s_adapter;

int adapter_detect();
Expand Down
2 changes: 1 addition & 1 deletion core/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ static void show_stats(struct stats * s)
{
char rate[COLS];

int freq = stats_get_frequency(s);
int freq = 1000000 / stats_get_period(s);

if(freq >= 0)
{
Expand Down
8 changes: 5 additions & 3 deletions core/gimx.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,11 @@ int process_event(GE_Event* event)
cfg_process_motion_event(event);
unsigned int device = ginput_get_device_id(event);
int controller = adapter_get_controller(E_DEVICE_TYPE_MOUSE, device);
s_adapter * adapter = adapter_get(controller);
if (adapter->mstats != NULL) {
stats_update(adapter->mstats);
if (controller != -1) {
s_adapter * adapter = adapter_get(controller);
if (adapter->mstats != NULL) {
stats_update(adapter->mstats);
}
}
break;
}
Expand Down
29 changes: 22 additions & 7 deletions core/mainloop.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,18 @@ e_gimx_status mainloop()
unsigned int running_macros;
struct gtimer * timer = NULL;

unsigned int refresh_period = (unsigned int)gimx_params.refresh_period;

GTIMER_CALLBACKS callbacks = {
.fp_read = timer_read,
.fp_close = timer_close,
.fp_register = REGISTER_FUNCTION,
.fp_remove = REMOVE_FUNCTION,
};

if(adapter_get(0)->atype != E_ADAPTER_TYPE_BLUETOOTH || adapter_get(0)->ctype == C_TYPE_DS4)
{
GTIMER_CALLBACKS callbacks = {
.fp_read = timer_read,
.fp_close = timer_close,
.fp_register = REGISTER_FUNCTION,
.fp_remove = REMOVE_FUNCTION,
};
timer = gtimer_start(NULL, (unsigned int)gimx_params.refresh_period, &callbacks);
timer = gtimer_start(NULL, refresh_period, &callbacks);
if (timer == NULL)
{
done = 1;
Expand All @@ -97,6 +100,18 @@ e_gimx_status mainloop()
done = 1;
}

if (timer != NULL && (unsigned int)gimx_params.refresh_period != refresh_period)
{
refresh_period = gimx_params.refresh_period;
gtimer_close(timer);
gwarn(_("Lowering controller frequency to %dHz due to low mouse frequency.\n"), 1000000 / refresh_period);
timer = gtimer_start(NULL, refresh_period, &callbacks);
if (timer == NULL)
{
done = 1;
}
}

if (gimx_params.debug.mainloop) {
GPERF_TICK(mainloop, gtime_gettime());
if (gperf_mainloop.count > 0) {
Expand Down
20 changes: 10 additions & 10 deletions core/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct stats {
gtime last;
unsigned int cpt;
unsigned int periods[11]; // count periods from 0 to 10 ms
int frequency;
int period;
};

void stats_clean(struct stats *s) {
Expand All @@ -36,7 +36,7 @@ struct stats* stats_init(enum stats_type type) {
if (s->type == E_STATS_TYPE_CONTROLLER) {
s->last = gtime_gettime();
} else {
s->frequency = -1;
s->period = -1;
}

return s;
Expand All @@ -46,7 +46,7 @@ void stats_update(struct stats *s) {

s->cpt++;

if (s->type == E_STATS_TYPE_MOUSE && s->frequency == -1) {
if (s->type == E_STATS_TYPE_MOUSE && s->period == -1) {
gtime now = gtime_gettime();
if (s->last != 0) {
gtime delta = now - s->last;
Expand All @@ -59,37 +59,37 @@ void stats_update(struct stats *s) {
}
}
s->last = now;
// compute mouse frequency on first 1000 reports
if (s->cpt > 1000) {
// compute mouse frequency on first 250 reports (2s @125Hz, 2.5s @100Hz)
if (s->cpt > 250) {
unsigned int i;
for (i = 1; i < sizeof(s->periods) / sizeof(*s->periods); ++i) {
if (s->periods[i] > s->cpt * 10 / 100) {
if (gimx_params.debug.stats) {
printf("mouse frequency : %dHz\n", 1000 / i);
}
s->frequency = 1000 / i;
s->period = i * 1000;
}
}
}
}
}

int stats_get_frequency(struct stats *s) {
int stats_get_period(struct stats *s) {

int ret = -1;

if (s->type == E_STATS_TYPE_CONTROLLER) {
gtime tnow = gtime_gettime();

gtimediff tdiff = tnow - s->last;
gtime tdiff = tnow - s->last;

if (tdiff > STATS_PERIOD) {
ret = s->cpt * 1000000000UL / tdiff;
ret = GTIME_USEC(tdiff / s->cpt);
s->last = tnow;
s->cpt = 0;
}
} else if(s->type == E_STATS_TYPE_MOUSE) {
ret = s->frequency;
ret = s->period;
}

return ret;
Expand Down
2 changes: 1 addition & 1 deletion core/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ enum stats_type {
struct stats * stats_init(enum stats_type type);
void stats_clean(struct stats * s);
void stats_update(struct stats * s);
int stats_get_frequency(struct stats * s);
int stats_get_period(struct stats * s);

#endif /* STATS_H_ */

0 comments on commit 2f429bb

Please sign in to comment.