d/opengloves: Add force feedback extension support

This commit is contained in:
Daniel Willmott 2022-09-09 13:47:40 +01:00 committed by Moses Turner
parent 74f14f2414
commit ddda9ec727
4 changed files with 88 additions and 2 deletions

View file

@ -140,6 +140,14 @@ static const std::map<std::string, int> opengloves_alpha_encoding_key_string{
{"", OPENGLOVES_ALPHA_ENCODING_MAX} // Junk key
};
static const std::map<int, std::string> opengloves_alpha_encoding_output_key_string{
{OPENGLOVES_ALPHA_ENCODING_FinThumb, "A"}, // thumb force feedback
{OPENGLOVES_ALPHA_ENCODING_FinIndex, "B"}, // index force feedback
{OPENGLOVES_ALPHA_ENCODING_FinMiddle, "C"}, // middle force feedback
{OPENGLOVES_ALPHA_ENCODING_FinRing, "D"}, // ring force feedback
{OPENGLOVES_ALPHA_ENCODING_FinPinky, "E"}, // pinky force feedback
};
static std::map<int, std::string>
opengloves_alpha_encoding_parse_to_map(const std::string &str)
{
@ -247,4 +255,20 @@ opengloves_alpha_encoding_decode(const char *data, struct opengloves_input *out)
out->gestures.grab.activated = input_map.find(OPENGLOVES_ALPHA_ENCODING_GesGrab) != input_map.end();
out->gestures.pinch.activated = input_map.find(OPENGLOVES_ALPHA_ENCODING_GesPinch) != input_map.end();
out->buttons.menu.pressed = input_map.find(OPENGLOVES_ALPHA_ENCODING_BtnMenu) != input_map.end();
}
}
void
opengloves_alpha_encoding_encode(const struct opengloves_output *output, char *out_buff)
{
sprintf(out_buff, "%s%d%s%d%s%d%s%d%s%d\n",
opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinThumb).c_str(),
(int)(output->force_feedback.thumb * 1000),
opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinIndex).c_str(),
(int)(output->force_feedback.index * 1000),
opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinMiddle).c_str(),
(int)(output->force_feedback.middle * 1000),
opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinRing).c_str(),
(int)(output->force_feedback.ring * 1000),
opengloves_alpha_encoding_output_key_string.at(OPENGLOVES_ALPHA_ENCODING_FinPinky).c_str(),
(int)(output->force_feedback.little * 1000));
}

View file

@ -17,6 +17,8 @@ extern "C" {
void
opengloves_alpha_encoding_decode(const char *data, struct opengloves_input *out_kv);
void
opengloves_alpha_encoding_encode(const struct opengloves_output *output, char *out_buff);
#ifdef __cplusplus
}
#endif

View file

@ -66,6 +66,20 @@ struct opengloves_input
struct opengloves_input_gestures gestures;
};
struct opengloves_output_force_feedback
{
float thumb;
float index;
float middle;
float ring;
float little;
};
struct opengloves_output
{
struct opengloves_output_force_feedback force_feedback;
};
#ifdef __cplusplus
}
#endif

View file

@ -159,6 +159,45 @@ opengloves_device_update_inputs(struct xrt_device *xdev)
os_mutex_unlock(&od->lock);
}
static void
opengloves_ffb_location_convert(const struct xrt_output_force_feedback *xrt_ffb,
struct opengloves_output_force_feedback *out_ffb)
{
switch (xrt_ffb->location) {
case XRT_FORCE_FEEDBACK_LOCATION_LEFT_THUMB: out_ffb->thumb = xrt_ffb->value; break;
case XRT_FORCE_FEEDBACK_LOCATION_LEFT_INDEX: out_ffb->index = xrt_ffb->value; break;
case XRT_FORCE_FEEDBACK_LOCATION_LEFT_MIDDLE: out_ffb->middle = xrt_ffb->value; break;
case XRT_FORCE_FEEDBACK_LOCATION_LEFT_RING: out_ffb->ring = xrt_ffb->value; break;
case XRT_FORCE_FEEDBACK_LOCATION_LEFT_PINKY: out_ffb->little = xrt_ffb->value; break;
}
}
static void
opengloves_device_set_output(struct xrt_device *xdev, enum xrt_output_name name, const union xrt_output_value *value)
{
struct opengloves_device *od = opengloves_device(xdev);
switch (name) {
case XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT:
case XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT: {
struct opengloves_output out;
int location_count = value->force_feedback.force_feedback_location_count;
const struct xrt_output_force_feedback *ffb = value->force_feedback.force_feedback;
for (int i = 0; i < location_count; i++) {
opengloves_ffb_location_convert(ffb + i, &out.force_feedback);
}
char buff[64];
opengloves_alpha_encoding_encode(&out, buff);
opengloves_communication_device_write(od->ocd, buff, strlen(buff));
}
default: break;
}
}
static void
opengloves_device_destroy(struct xrt_device *xdev)
{
@ -235,7 +274,8 @@ struct xrt_device *
opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_hand hand)
{
enum u_device_alloc_flags flags = (enum u_device_alloc_flags)(U_DEVICE_ALLOC_TRACKING_NONE);
struct opengloves_device *od = U_DEVICE_ALLOCATE(struct opengloves_device, flags, 8, 0);
struct opengloves_device *od = U_DEVICE_ALLOCATE(struct opengloves_device, flags, 8, 1);
od->base.name = XRT_DEVICE_HAND_TRACKER;
od->base.device_type = XRT_DEVICE_TYPE_HAND_TRACKER;
@ -251,6 +291,7 @@ opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_h
od->hand == XRT_HAND_LEFT ? XRT_INPUT_GENERIC_HAND_TRACKING_LEFT : XRT_INPUT_GENERIC_HAND_TRACKING_RIGHT;
od->base.hand_tracking_supported = true;
od->base.force_feedback_supported = true;
// inputs
od->base.update_inputs = opengloves_device_update_inputs;
@ -266,6 +307,11 @@ opengloves_device_create(struct opengloves_communication_device *ocd, enum xrt_h
od->base.inputs[OPENGLOVES_INDEX_JOYSTICK_MAIN].name = XRT_INPUT_INDEX_THUMBSTICK;
od->base.inputs[OPENGLOVES_INDEX_JOYSTICK_MAIN_CLICK].name = XRT_INPUT_INDEX_THUMBSTICK_CLICK;
// outputs
od->base.outputs[0].name =
od->hand == XRT_HAND_LEFT ? XRT_OUTPUT_NAME_FORCE_FEEDBACK_LEFT : XRT_OUTPUT_NAME_FORCE_FEEDBACK_RIGHT;
od->base.set_output = opengloves_device_set_output;
// startup thread
int ret = os_thread_helper_init(&od->oth);
if (ret != 0) {