gamepad_resampler_skeleton
This commit is contained in:
parent
82660c25a0
commit
015bbb1f44
@ -35,6 +35,7 @@ src = [
|
|||||||
'src/hid/hid_gamepad.c',
|
'src/hid/hid_gamepad.c',
|
||||||
'src/hid/hid_keyboard.c',
|
'src/hid/hid_keyboard.c',
|
||||||
'src/hid/hid_mouse.c',
|
'src/hid/hid_mouse.c',
|
||||||
|
'src/resampler/gamepad_resampler.c',
|
||||||
'src/trait/frame_source.c',
|
'src/trait/frame_source.c',
|
||||||
'src/trait/packet_source.c',
|
'src/trait/packet_source.c',
|
||||||
'src/uhid/gamepad_uhid.c',
|
'src/uhid/gamepad_uhid.c',
|
||||||
|
141
app/src/resampler/gamepad_resampler.c
Normal file
141
app/src/resampler/gamepad_resampler.c
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "gamepad_resampler.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "input_events.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
/** Downcast gamepad processor to sc_gamepad_resampler */
|
||||||
|
#define DOWNCAST(GP) \
|
||||||
|
container_of(GP, struct sc_gamepad_resampler, gamepad_processor)
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_gamepad_processor_slot_init(struct sc_gamepad_resampler_slot *slot,
|
||||||
|
uint32_t gamepad_id) {
|
||||||
|
assert(gamepad_id != SC_GAMEPAD_ID_INVALID);
|
||||||
|
slot->gamepad_id = gamepad_id;
|
||||||
|
slot->buttons = 0;
|
||||||
|
slot->axis_left_x = 0;
|
||||||
|
slot->axis_left_y = 0;
|
||||||
|
slot->axis_right_x = 0;
|
||||||
|
slot->axis_right_y = 0;
|
||||||
|
slot->axis_left_trigger = 0;
|
||||||
|
slot->axis_right_trigger = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
sc_gamepad_processor_slot_find(struct sc_gamepad_resampler *resampler,
|
||||||
|
uint32_t gamepad_id) {
|
||||||
|
for (size_t i = 0; i < SC_MAX_GAMEPADS; ++i) {
|
||||||
|
if (gamepad_id == resampler->slots[i].gamepad_id) {
|
||||||
|
// found
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
|
||||||
|
const struct sc_gamepad_device_event *event) {
|
||||||
|
struct sc_gamepad_resampler *resampler = DOWNCAST(gp);
|
||||||
|
|
||||||
|
if (event->type == SC_GAMEPAD_DEVICE_ADDED) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
assert(event->type == SC_GAMEPAD_DEVICE_REMOVED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_gamepad_processor_process_gamepad_axis(struct sc_gamepad_processor *gp,
|
||||||
|
const struct sc_gamepad_axis_event *event) {
|
||||||
|
struct sc_gamepad_resampler *resampler = DOWNCAST(gp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_gamepad_processor_process_gamepad_button(struct sc_gamepad_processor *gp,
|
||||||
|
const struct sc_gamepad_button_event *event) {
|
||||||
|
struct sc_gamepad_resampler *resampler = DOWNCAST(gp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_gamepad_resampler_trigger(void *userdata) {
|
||||||
|
struct sc_gamepad_resampler *resampler = userdata;
|
||||||
|
|
||||||
|
sc_tick now = sc_tick_now();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < SC_MAX_GAMEPADS; ++i) {
|
||||||
|
struct sc_gamepad_resampler_slot *slot = &resampler->slots[i];
|
||||||
|
if (slot->gamepad_id != SC_GAMEPAD_ID_INVALID
|
||||||
|
&& slot->deadline != SC_TICK_INVALID
|
||||||
|
&& slot->deadline - now >= resampler->min_interval) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
run_resampler(void *data) {
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_gamepad_resampler_init(struct sc_gamepad_resampler *resampler,
|
||||||
|
struct sc_gamepad_processor *delegate,
|
||||||
|
sc_tick min_interval) {
|
||||||
|
bool ok = sc_mutex_init(&resampler->mutex);
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = sc_cond_init(&resampler->cond);
|
||||||
|
if (!ok) {
|
||||||
|
goto error_destroy_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
ok = sc_thread_create(&resampler->thread, run_resampler, "scrcpy-gp-rs",
|
||||||
|
resampler);
|
||||||
|
if (!ok) {
|
||||||
|
LOGE("Could not start gamepad resampler thread");
|
||||||
|
goto error_destroy_cond;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct sc_gamepad_processor_ops ops = {
|
||||||
|
.process_gamepad_device = sc_gamepad_processor_process_gamepad_device,
|
||||||
|
.process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis,
|
||||||
|
.process_gamepad_button = sc_gamepad_processor_process_gamepad_button,
|
||||||
|
};
|
||||||
|
|
||||||
|
resampler->gamepad_processor.ops = &ops;
|
||||||
|
|
||||||
|
resampler->delegate = delegate;
|
||||||
|
resampler->min_interval = min_interval;
|
||||||
|
resampler->stopped = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < SC_MAX_GAMEPADS; ++i) {
|
||||||
|
resampler->slots[i].gamepad_id = SC_GAMEPAD_ID_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error_destroy_mutex:
|
||||||
|
sc_mutex_destroy(&resampler->mutex);
|
||||||
|
error_destroy_cond:
|
||||||
|
sc_cond_destroy(&resampler->cond);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_stop(struct sc_gamepad_resampler *resampler);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_join(struct sc_gamepad_resampler *resampler);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_destroy(struct sc_gamepad_resampler *resampler);
|
53
app/src/resampler/gamepad_resampler.h
Normal file
53
app/src/resampler/gamepad_resampler.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef SC_GAMEPAD_RESAMPLER_H
|
||||||
|
#define SC_GAMEPAD_RESAMPLER_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "hid/hid_gamepad.h" // for SC_MAX_GAMEPADS
|
||||||
|
#include "trait/gamepad_processor.h"
|
||||||
|
#include "util/thread.h"
|
||||||
|
#include "util/tick.h"
|
||||||
|
|
||||||
|
struct sc_gamepad_resampler_slot {
|
||||||
|
uint32_t gamepad_id;
|
||||||
|
sc_tick deadline;
|
||||||
|
uint32_t buttons;
|
||||||
|
uint16_t axis_left_x;
|
||||||
|
uint16_t axis_left_y;
|
||||||
|
uint16_t axis_right_x;
|
||||||
|
uint16_t axis_right_y;
|
||||||
|
uint16_t axis_left_trigger;
|
||||||
|
uint16_t axis_right_trigger;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_gamepad_resampler {
|
||||||
|
struct sc_gamepad_processor gamepad_processor; // gamepad processor trait
|
||||||
|
|
||||||
|
struct sc_gamepad_processor *delegate;
|
||||||
|
sc_tick min_interval;
|
||||||
|
|
||||||
|
sc_mutex mutex;
|
||||||
|
sc_cond cond;
|
||||||
|
sc_thread thread;
|
||||||
|
bool stopped;
|
||||||
|
|
||||||
|
struct sc_gamepad_resampler_slot slots[SC_MAX_GAMEPADS];
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_gamepad_resampler_init(struct sc_gamepad_resampler *resampler,
|
||||||
|
struct sc_gamepad_processor *delegate,
|
||||||
|
sc_tick min_interval);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_stop(struct sc_gamepad_resampler *resampler);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_join(struct sc_gamepad_resampler *resampler);
|
||||||
|
|
||||||
|
void
|
||||||
|
sc_gamepad_resampler_destroy(struct sc_gamepad_resampler *resampler);
|
||||||
|
|
||||||
|
#endif
|
@ -9,6 +9,8 @@ typedef int64_t sc_tick;
|
|||||||
#define PRItick PRIi64
|
#define PRItick PRIi64
|
||||||
#define SC_TICK_FREQ 1000000 // microsecond
|
#define SC_TICK_FREQ 1000000 // microsecond
|
||||||
|
|
||||||
|
#define SC_TICK_INVALID INT64_MIN
|
||||||
|
|
||||||
// To be adapted if SC_TICK_FREQ changes
|
// To be adapted if SC_TICK_FREQ changes
|
||||||
#define SC_TICK_TO_NS(tick) ((tick) * 1000)
|
#define SC_TICK_TO_NS(tick) ((tick) * 1000)
|
||||||
#define SC_TICK_TO_US(tick) (tick)
|
#define SC_TICK_TO_US(tick) (tick)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user