d/qwerty: Move left/right controllers with CTRL/ALT

In qwerty_sdl.c the u_device_assign_xdev_roles function is used for
knowing which devices are being used by the user. These could
be other physical devices. And as such the idea of a default focused
device is introduced and depends upon which devices the user already
has. With this change qwerty devices should be properly introduced
to fill any device the user may not have.
This commit is contained in:
Mateo de Mayo 2021-03-11 16:30:14 -03:00
parent 62e05f267a
commit f8f14a1d9e
4 changed files with 125 additions and 11 deletions

View file

@ -50,6 +50,22 @@ qwerty_device(struct xrt_device *xd)
return qd;
}
struct qwerty_hmd *
qwerty_hmd(struct xrt_device *xd)
{
struct qwerty_hmd *qh = (struct qwerty_hmd *)xd;
assert(qh);
return qh;
}
struct qwerty_controller *
qwerty_controller(struct xrt_device *xd)
{
struct qwerty_controller *qc = (struct qwerty_controller *)xd;
assert(qc);
return qc;
}
static void
qwerty_update_inputs(struct xrt_device *xd)
{
@ -276,3 +292,21 @@ qwerty_change_movement_speed(struct qwerty_device *qd, float steps)
{
qd->movement_speed *= powf(MOVEMENT_SPEED_STEP, steps);
}
void
qwerty_release_all(struct qwerty_device *qd)
{
qd->left_pressed = false;
qd->right_pressed = false;
qd->forward_pressed = false;
qd->backward_pressed = false;
qd->up_pressed = false;
qd->down_pressed = false;
qd->look_left_pressed = false;
qd->look_right_pressed = false;
qd->look_up_pressed = false;
qd->look_down_pressed = false;
qd->sprint_pressed = false;
qd->yaw_delta = 0;
qd->pitch_delta = 0;
}

View file

@ -115,6 +115,10 @@ qwerty_add_look_delta(struct qwerty_device *qd, float yaw, float pitch);
void
qwerty_change_movement_speed(struct qwerty_device *qd, float steps);
//! Release all movement input
void
qwerty_release_all(struct qwerty_device *qd);
/*!
* @}
*/
@ -131,6 +135,10 @@ qwerty_change_movement_speed(struct qwerty_device *qd, float steps);
struct qwerty_hmd *
qwerty_hmd_create(void);
//! Cast to qwerty_hmd. Ensures returning a valid HMD or crashing.
struct qwerty_hmd *
qwerty_hmd(struct xrt_device *xd);
/*!
* @}
*/
@ -147,6 +155,10 @@ qwerty_hmd_create(void);
struct qwerty_controller *
qwerty_controller_create(bool is_left, struct qwerty_hmd *qhmd);
//! Cast to qwerty_controller. Ensures returning a valid controller or crashing.
struct qwerty_controller *
qwerty_controller(struct xrt_device *xd);
/*!
* @}
*/

View file

@ -30,6 +30,11 @@ qwerty_create_auto_prober(void);
/*!
* Process an SDL_Event (like a key press) and dispatches a suitable action
* to the appropriate qwerty_device.
*
* @note A qwerty_controller might not be in use (for example if you have
* physical controllers connected), though its memory will be modified by these
* events regardless. A qwerty_hmd not in use will not be modified as it never
* gets created.
*/
void
qwerty_process_event(struct xrt_device **xdevs, size_t num_xdevs, SDL_Event event);

View file

@ -7,10 +7,8 @@
* @ingroup drv_qwerty
*/
// @note: This file will process more than one device, that's
// why some comments reference multiple devices
#include "qwerty_device.h"
#include "util/u_device.h"
#include "xrt/xrt_device.h"
#include <SDL2/SDL.h>
@ -20,7 +18,9 @@
static void
find_qwerty_devices(struct xrt_device **xdevs,
size_t num_xdevs,
struct xrt_device **xd_hmd)
struct xrt_device **xd_hmd,
struct xrt_device **xd_left,
struct xrt_device **xd_right)
{
for (size_t i = 0; i < num_xdevs; i++) {
if (xdevs[i] == NULL) {
@ -29,33 +29,96 @@ find_qwerty_devices(struct xrt_device **xdevs,
if (strcmp(xdevs[i]->str, QWERTY_HMD_STR) == 0) {
*xd_hmd = xdevs[i];
} else if (strcmp(xdevs[i]->str, QWERTY_LEFT_STR) == 0) {
*xd_left = xdevs[i];
} else if (strcmp(xdevs[i]->str, QWERTY_RIGHT_STR) == 0) {
*xd_right = xdevs[i];
}
}
}
// Determines the default qwerty device based on which devices are in use
struct qwerty_device *
default_qwerty_device(struct xrt_device **xdevs,
size_t num_xdevs,
struct xrt_device *xd_hmd,
struct xrt_device *xd_left,
struct xrt_device *xd_right)
{
int head, left, right;
head = left = right = XRT_DEVICE_ROLE_UNASSIGNED;
u_device_assign_xdev_roles(xdevs, num_xdevs, &head, &left, &right);
struct qwerty_device *default_qdev = NULL;
if (xdevs[head] == xd_hmd) {
default_qdev = qwerty_device(xd_hmd);
} else if (xdevs[right] == xd_right) {
default_qdev = qwerty_device(xd_right);
} else if (xdevs[left] == xd_left) {
default_qdev = qwerty_device(xd_left);
} else { // Even here, xd_right is allocated and so we can modify it
default_qdev = qwerty_device(xd_right);
}
return default_qdev;
}
void
qwerty_process_event(struct xrt_device **xdevs, size_t num_xdevs, SDL_Event event)
{
static struct xrt_device *xd_hmd = NULL;
static struct xrt_device *xd_left = NULL;
static struct xrt_device *xd_right = NULL;
static bool alt_pressed = false;
static bool ctrl_pressed = false;
// Default focused device: the one focused when CTRL and ALT are not pressed
static struct qwerty_device *default_qdev;
// We can cache the devices as they don't get destroyed during runtime
static bool cached = false;
if (!cached) {
find_qwerty_devices(xdevs, num_xdevs, &xd_hmd);
find_qwerty_devices(xdevs, num_xdevs, &xd_hmd, &xd_left, &xd_right);
default_qdev = default_qwerty_device(xdevs, num_xdevs, xd_hmd, xd_left, xd_right);
cached = true;
}
bool using_qhmd = xd_hmd != NULL;
struct qwerty_device *qd_hmd = using_qhmd ? qwerty_device(xd_hmd) : NULL;
// Initialize different views of the same pointers.
if (!qd_hmd) {
return;
}
struct qwerty_controller *qleft = qwerty_controller(xd_left);
struct qwerty_device *qd_left = &qleft->base;
struct qwerty_controller *qright = qwerty_controller(xd_right);
struct qwerty_device *qd_right = &qright->base;
bool using_qhmd = xd_hmd != NULL;
struct qwerty_hmd *qhmd = using_qhmd ? qwerty_hmd(xd_hmd) : NULL;
struct qwerty_device *qd_hmd = using_qhmd ? &qhmd->base : NULL;
// clang-format off
// CTRL/ALT keys logic
bool alt_down = event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_LALT;
bool alt_up = event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_LALT;
bool ctrl_down = event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_LCTRL;
bool ctrl_up = event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_LCTRL;
if (alt_down) alt_pressed = true;
if (alt_up) alt_pressed = false;
if (ctrl_down) ctrl_pressed = true;
if (ctrl_up) ctrl_pressed = false;
bool change_focus = alt_down || alt_up || ctrl_down || ctrl_up;
if (change_focus) {
if (using_qhmd) qwerty_release_all(qd_hmd);
qwerty_release_all(qd_right);
qwerty_release_all(qd_left);
}
// Determine focused device
struct qwerty_device *qdev = qd_hmd;
struct qwerty_device *qdev;
if (ctrl_pressed) qdev = qd_left;
else if (alt_pressed) qdev = qd_right;
else qdev = default_qdev;
// WASDQE Movement
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_a) qwerty_press_left(qdev);