diff --git a/src/api/event.c b/src/api/event.c index 7011461c..83d17009 100644 --- a/src/api/event.c +++ b/src/api/event.c @@ -13,17 +13,18 @@ static int nextEvent(lua_State* L) { } switch (event->type) { - case EVENT_QUIT: + case EVENT_QUIT: { lua_pushstring(L, "quit"); lua_pushnumber(L, event->data.quit.exitCode); return 2; + } case EVENT_CONTROLLER_ADDED: { lua_pushstring(L, "controlleradded"); luax_pushtype(L, Controller, event->data.controlleradded.controller); lovrRelease(&event->data.controlleradded.controller->ref); return 2; - } + } case EVENT_CONTROLLER_REMOVED: { lua_pushstring(L, "controllerremoved"); @@ -32,6 +33,20 @@ static int nextEvent(lua_State* L) { return 2; } + case EVENT_CONTROLLER_PRESSED: { + lua_pushstring(L, "controllerpressed"); + luax_pushtype(L, Controller, event->data.controllerpressed.controller); + luax_pushenum(L, &ControllerButtons, event->data.controllerpressed.button); + return 3; + } + + case EVENT_CONTROLLER_RELEASED: { + lua_pushstring(L, "controllerreleased"); + luax_pushtype(L, Controller, event->data.controllerreleased.controller); + luax_pushenum(L, &ControllerButtons, event->data.controllerreleased.button); + return 3; + } + default: return 0; } @@ -82,6 +97,16 @@ int l_lovrEventPush(lua_State* L) { case EVENT_CONTROLLER_REMOVED: data.controllerremoved.controller = luax_checktype(L, 2, Controller); break; + + case EVENT_CONTROLLER_PRESSED: + data.controllerpressed.controller = luax_checktype(L, 2, Controller); + data.controllerpressed.button = *(ControllerButton*) luax_checkenum(L, 3, &ControllerButtons, "button"); + break; + + case EVENT_CONTROLLER_RELEASED: + data.controllerreleased.controller = luax_checktype(L, 2, Controller); + data.controllerreleased.button = *(ControllerButton*) luax_checkenum(L, 3, &ControllerButtons, "button"); + break; } Event event = { .type = type, .data = data }; diff --git a/src/event/event.h b/src/event/event.h index d6ebf89d..0844f68c 100644 --- a/src/event/event.h +++ b/src/event/event.h @@ -6,7 +6,9 @@ typedef enum { EVENT_QUIT, EVENT_CONTROLLER_ADDED, - EVENT_CONTROLLER_REMOVED + EVENT_CONTROLLER_REMOVED, + EVENT_CONTROLLER_PRESSED, + EVENT_CONTROLLER_RELEASED } EventType; typedef struct { @@ -21,10 +23,22 @@ typedef struct { Controller* controller; } ControllerRemovedEvent; +typedef struct { + Controller* controller; + ControllerButton button; +} ControllerPressedEvent; + +typedef struct { + Controller* controller; + ControllerButton button; +} ControllerReleasedEvent; + typedef union { QuitEvent quit; ControllerAddedEvent controlleradded; ControllerRemovedEvent controllerremoved; + ControllerPressedEvent controllerpressed; + ControllerReleasedEvent controllerreleased; } EventData; typedef struct { diff --git a/src/headset/openvr.c b/src/headset/openvr.c index 9de81299..09e974e1 100644 --- a/src/headset/openvr.c +++ b/src/headset/openvr.c @@ -10,6 +10,16 @@ static HeadsetState state; +static ControllerButton getButton(uint32_t button) { + switch (button) { + case EVRButtonId_k_EButton_System: return CONTROLLER_BUTTON_SYSTEM; + case EVRButtonId_k_EButton_ApplicationMenu: return CONTROLLER_BUTTON_MENU; + case EVRButtonId_k_EButton_Grip: return CONTROLLER_BUTTON_GRIP; + case EVRButtonId_k_EButton_SteamVR_Touchpad: return CONTROLLER_BUTTON_TOUCHPAD; + default: return -1; + } +} + static TrackedDevicePose_t getPose(unsigned int deviceIndex) { if (state.isRendering) { return state.renderPoses[deviceIndex]; @@ -116,9 +126,34 @@ void lovrHeadsetPoll() { switch (vrEvent.eventType) { case EVREventType_VREvent_TrackedDeviceActivated: case EVREventType_VREvent_TrackedDeviceDeactivated: - case EVREventType_VREvent_TrackedDeviceRoleChanged: + case EVREventType_VREvent_TrackedDeviceRoleChanged: { lovrHeadsetRefreshControllers(); break; + } + + case EVREventType_VREvent_ButtonPress: + case EVREventType_VREvent_ButtonUnpress: { + int isPress = vrEvent.eventType == EVREventType_VREvent_ButtonPress; + Controller* controller; + int i; + vec_foreach(&state.controllers, controller, i) { + if (controller->id == vrEvent.trackedDeviceIndex) { + Event event; + if (isPress) { + event.type = EVENT_CONTROLLER_PRESSED; + event.data.controllerpressed.controller = controller; + event.data.controllerpressed.button = getButton(vrEvent.data.controller.button); + } else { + event.type = EVENT_CONTROLLER_RELEASED; + event.data.controllerreleased.controller = controller; + event.data.controllerreleased.button = getButton(vrEvent.data.controller.button); + } + lovrEventPush(event); + break; + } + } + break; + } } } } @@ -171,7 +206,7 @@ float lovrHeadsetGetBoundsDepth() { void lovrHeadsetGetBoundsGeometry(float* geometry) { if (!state.isInitialized) { - memset(geometry, 0.f, 12 * sizeof(float)); + memset(geometry, 0, 12 * sizeof(float)); } else { struct HmdQuad_t quad; state.chaperone->GetPlayAreaRect(&quad); @@ -402,17 +437,10 @@ float lovrHeadsetControllerGetAxis(Controller* controller, ControllerAxis axis) state.system->GetControllerState(controller->id, &input, sizeof(input)); switch (axis) { - case CONTROLLER_AXIS_TRIGGER: - return input.rAxis[1].x; - - case CONTROLLER_AXIS_TOUCHPAD_X: - return input.rAxis[0].x; - - case CONTROLLER_AXIS_TOUCHPAD_Y: - return input.rAxis[0].y; - - default: - error("Bad controller axis"); + case CONTROLLER_AXIS_TRIGGER: return input.rAxis[1].x; + case CONTROLLER_AXIS_TOUCHPAD_X: return input.rAxis[0].x; + case CONTROLLER_AXIS_TOUCHPAD_Y: return input.rAxis[0].y; + default: error("Bad controller axis"); } return 0.; @@ -426,10 +454,10 @@ int lovrHeadsetControllerIsDown(Controller* controller, ControllerButton button) switch (button) { case CONTROLLER_BUTTON_SYSTEM: - return (input.ulButtonPressed >> EVRButtonId_k_EButton_ApplicationMenu) & 1; + return (input.ulButtonPressed >> EVRButtonId_k_EButton_System) & 1; case CONTROLLER_BUTTON_MENU: - return (input.ulButtonPressed >> EVRButtonId_k_EButton_System) & 1; + return (input.ulButtonPressed >> EVRButtonId_k_EButton_ApplicationMenu) & 1; case CONTROLLER_BUTTON_GRIP: return (input.ulButtonPressed >> EVRButtonId_k_EButton_Grip) & 1; diff --git a/src/lovr.c b/src/lovr.c index 38ab40c1..d6694ac7 100644 --- a/src/lovr.c +++ b/src/lovr.c @@ -118,6 +118,12 @@ void lovrInit(lua_State* L, int argc, char** argv) { " end, " " controllerremoved = function(c) " " if lovr.controllerremoved then lovr.controllerremoved(c) end " + " end, " + " controllerpressed = function(c, b) " + " if lovr.controllerpressed then lovr.controllerpressed(c, b) end " + " end, " + " controllerreleased = function(c, b) " + " if lovr.controllerreleased then lovr.controllerreleased(c, b) end " " end " "}, { " " __index = function(self, event) "