gamepad_resampler_skeleton

This commit is contained in:
Romain Vimont 2024-09-08 08:53:19 +02:00
parent 82660c25a0
commit 015bbb1f44
4 changed files with 197 additions and 0 deletions

View File

@ -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',

View 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);

View 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

View File

@ -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)