diff --git a/src/hooking/controls.cpp b/src/hooking/controls.cpp index e9ecb70..284846b 100644 --- a/src/hooking/controls.cpp +++ b/src/hooking/controls.cpp @@ -193,12 +193,13 @@ bool openDpadMenuRuneButton(ButtonState::Event lastEvent, uint32_t& buttonHold, buttonHold |= VPAD_BUTTON_UP; gameState.last_dpad_menu_open = EquipType::SheikahSlate; gameState.dpad_menu_open_requested = true; + gameState.current_dpad_menu_button = OpenXR::DpadMenuButton::Rune; return true; } return false; } -bool openDpadMenuBodySlots(ButtonState::Event lastEvent, HandGestureState handGesture, uint32_t& buttonHold, OpenXR::GameState& gameState) { +bool openDpadMenuBodySlots(ButtonState::Event lastEvent, HandGestureState handGesture, uint32_t& buttonHold, OpenXR::GameState& gameState, bool (*gripButton)(OpenXR::InputState)) { if (lastEvent == ButtonState::Event::LongPress && !gameState.dpad_menu_open_requested && gameState.right_hand_current_equip_type != EquipType::MagnetGlove) { if (isHandOverRightShoulderSlot(handGesture)) { //open arrow menu if bow is equipped in left hand @@ -241,6 +242,7 @@ bool openDpadMenuBodySlots(ButtonState::Event lastEvent, HandGestureState handGe gameState.last_dpad_menu_open = EquipType::SheikahSlate; } gameState.dpad_menu_open_requested = true; + gameState.current_dpad_menu_button = gripButton; return true; } return false; @@ -267,15 +269,15 @@ void keepDpadMenuOpen(uint32_t& buttonHold, OpenXR::GameState& gameState) { } } -bool closeDpadMenu(OpenXR::InputState& inputs, OpenXR::GameState& gameState) { +void closeDpadMenu(OpenXR::InputState& inputs, OpenXR::GameState& gameState) { if (!gameState.dpad_menu_open_requested) - return false; + return; - if (!inputs.inMenu.leftGrip.currentState && !inputs.inMenu.rightGrip.currentState && !inputs.inMenu.sort.currentState) { + if (!gameState.current_dpad_menu_button(inputs)) { gameState.dpad_menu_open_requested = false; gameState.was_dpad_menu_open = true; + gameState.current_dpad_menu_button = nullptr; } - return true; } void equipWeaponOnDpadMenuExit(uint32_t& buttonHold, OpenXR::GameState& gameState, float dt) { @@ -336,9 +338,10 @@ void processLeftHandInGameInput( constexpr RumbleParameters RuneRumble = { true, 0, RumbleType::OscillationSmooth, 1.0f, false, 1.0, 0.25f, 0.25f }; auto* rumbleMgr = VRManager::instance().XR->GetRumbleManager(); - bool isGrabPressed = inputs.inGame.grabState[0].lastEvent == ButtonState::Event::ShortPress; - bool isGrabPressedLong = inputs.inGame.grabState[0].lastEvent == ButtonState::Event::LongPress; - bool isCurrentGrabPressed = inputs.inGame.grabState[0].wasDownLastFrame; + bool isGrabPressed = inputs.shared.grabState[0].lastEvent == ButtonState::Event::ShortPress; + bool isGrabPressedLong = inputs.shared.grabState[0].lastEvent == ButtonState::Event::LongPress; + bool isCurrentGrabPressed = inputs.shared.grabState[0].wasDownLastFrame; + bool isCurrentInteractPressed = inputs.shared.grabState[0].wasDownLastFrame; // Rune rumbles if (gameState.left_hand_current_equip_type == EquipType::SheikahSlate) @@ -373,7 +376,7 @@ void processLeftHandInGameInput( // Handle shoulder slot interactions if (isHandOverLeftShoulderSlot(leftGesture) || isHandOverRightShoulderSlot(leftGesture)) { - if (openDpadMenuBodySlots(inputs.inGame.grabState[0].lastEvent, leftGesture, buttonHold, gameState)) + if (openDpadMenuBodySlots(inputs.shared.grabState[0].lastEvent, leftGesture, buttonHold, gameState, OpenXR::DpadMenuButton::LGrab)) // Don't process normal input when opening dpad menu return; @@ -408,7 +411,7 @@ void processLeftHandInGameInput( // Handle waist slot interaction (Rune) if (isHandOverLeftWaistSlot(leftGesture)) { // Handle dpad menu - if (openDpadMenuBodySlots(inputs.inGame.grabState[0].lastEvent, leftGesture, buttonHold, gameState)) + if (openDpadMenuBodySlots(inputs.shared.grabState[0].lastEvent, leftGesture, buttonHold, gameState, OpenXR::DpadMenuButton::LGrab)) // Don't process normal input when opening dpad menu return; @@ -485,17 +488,10 @@ void processLeftHandInGameInput( // } // return; //} - - if (isGrabPressed) { - // Handle grab action. is_riding_mount check added to prevent conflict with master cycle brake function - if (!gameState.prevent_grab_inputs && !gameState.is_riding_mount) { - buttonHold |= VPAD_BUTTON_A; - } - } - // Master Sword QTE fix. is_riding_mount check to prevent conflict with master cycle brake function - if (isHandNotOverAnySlot(leftGesture) && isGrabPressedLong && !gameState.is_riding_mount) { - if (!gameState.prevent_grab_inputs) { + // Handle interact action. is_riding_mount check added to prevent conflict with master cycle brake function + if (!gameState.prevent_grab_inputs && !gameState.is_riding_mount) { + if (isHandNotOverAnySlot(leftGesture) && isCurrentInteractPressed) { buttonHold |= VPAD_BUTTON_A; } } @@ -516,15 +512,16 @@ void processRightHandInGameInput( constexpr RumbleParameters OverSlotsRumble = { false, 1, RumbleType::OscillationRaisingSawtoothWave, 1.0f, false, 1.0, 0.25f, 0.25f }; auto* rumbleMgr = VRManager::instance().XR->GetRumbleManager(); - bool isGrabPressedShort = inputs.inGame.grabState[1].lastEvent == ButtonState::Event::ShortPress; - bool isGrabPressedLong = inputs.inGame.grabState[1].lastEvent == ButtonState::Event::LongPress; - bool isCurrentGrabPressed = inputs.inGame.grabState[1].wasDownLastFrame; + bool isGrabPressedShort = inputs.shared.grabState[1].lastEvent == ButtonState::Event::ShortPress; + bool isGrabPressedLong = inputs.shared.grabState[1].lastEvent == ButtonState::Event::LongPress; + bool isCurrentGrabPressed = inputs.shared.grabState[1].wasDownLastFrame; + bool isCurrentInteractPressed = inputs.inGame.interactState[1].wasDownLastFrame; bool isTriggerPressed = inputs.inGame.useRightItem.currentState; // Handle shoulder slot interactions if (isHandOverLeftShoulderSlot(rightGesture) || isHandOverRightShoulderSlot(rightGesture)) { // Handle dpad menu - if (openDpadMenuBodySlots(inputs.inGame.grabState[1].lastEvent, rightGesture, buttonHold, gameState)) + if (openDpadMenuBodySlots(inputs.shared.grabState[1].lastEvent, rightGesture, buttonHold, gameState, OpenXR::DpadMenuButton::RGrab)) // Don't process normal input when opening dpad menu return; @@ -589,7 +586,7 @@ void processRightHandInGameInput( // Handle waist slot interaction (Rune) if (isHandOverLeftWaistSlot(rightGesture)) { // Handle dpad menu - if (openDpadMenuBodySlots(inputs.inGame.grabState[1].lastEvent, rightGesture, buttonHold, gameState)) + if (openDpadMenuBodySlots(inputs.shared.grabState[1].lastEvent, rightGesture, buttonHold, gameState, OpenXR::DpadMenuButton::RGrab)) // Don't process normal input when opening dpad menu return; @@ -667,16 +664,8 @@ void processRightHandInGameInput( else gameState.right_hand_position_stored = false; - if (isGrabPressedShort) { - // Handle grab action - if (!gameState.prevent_grab_inputs) { - buttonHold |= VPAD_BUTTON_A; - } - } - - // Master Sword QTE fix - if (isHandNotOverAnySlot(rightGesture) && isGrabPressedLong) { - if (!gameState.prevent_grab_inputs) { + if (!gameState.prevent_grab_inputs) { + if (isHandNotOverAnySlot(rightGesture) && isCurrentInteractPressed) { buttonHold |= VPAD_BUTTON_A; } } @@ -791,8 +780,7 @@ void processMenuInput( return state.currentState ? btn : 0; }; - if (!closeDpadMenu(inputs, gameState)) - buttonHold |= mapButton(inputs.inMenu.sort, VPAD_BUTTON_Y); + closeDpadMenu(inputs, gameState); if (!gameState.prevent_inputs) { buttonHold |= mapButton(inputs.inMenu.back, VPAD_BUTTON_B); @@ -803,8 +791,10 @@ void processMenuInput( } buttonHold |= mapButton(inputs.inMenu.select, VPAD_BUTTON_A); + buttonHold |= mapButton(inputs.inMenu.sort, VPAD_BUTTON_Y); buttonHold |= mapButton(inputs.inMenu.leftTrigger, VPAD_BUTTON_L); buttonHold |= mapButton(inputs.inMenu.rightTrigger, VPAD_BUTTON_R); + buttonHold |= mapButton(inputs.inMenu.rotate, VPAD_BUTTON_STICK_R); if (inputs.inMenu.holdState.lastEvent == ButtonState::Event::ShortPress) buttonHold |= VPAD_BUTTON_X; @@ -1040,8 +1030,8 @@ void CemuHooks::hook_InjectXRInput(PPCInterpreter_t* hCPU) { } // Optional rune inputs (for seated players) - openDpadMenuRuneButton(inputs.inGame.useRune_runeMenuState.lastEvent, newXRBtnHold, gameState); - if (inputs.inGame.useRune_runeMenuState.lastEvent == ButtonState::Event::ShortPress) { + openDpadMenuRuneButton(inputs.shared.useRune_runeMenuState.lastEvent, newXRBtnHold, gameState); + if (inputs.shared.useRune_runeMenuState.lastEvent == ButtonState::Event::ShortPress) { newXRBtnHold |= VPAD_BUTTON_L; // Equip rune gameState.last_equip_type_held = EquipType::SheikahSlate; } @@ -1056,9 +1046,9 @@ void CemuHooks::hook_InjectXRInput(PPCInterpreter_t* hCPU) { newXRBtnHold |= mapXRButtonToVpad(inputs.inGame.run_interact, VPAD_BUTTON_A); // grabs to accelerate and brake when riding master cycle // Skip when the respective hand is inside a body slot so grips can still equip/unequip - if (inputs.inGame.grabState[1].wasDownLastFrame && isHandNotOverAnySlot(rightGesture)) + if (inputs.inGame.interactState[1].wasDownLastFrame && isHandNotOverAnySlot(rightGesture)) newXRBtnHold |= VPAD_BUTTON_A; - if (inputs.inGame.grabState[0].wasDownLastFrame && isHandNotOverAnySlot(leftGesture)) + if (inputs.inGame.interactState[0].wasDownLastFrame && isHandNotOverAnySlot(leftGesture)) newXRBtnHold |= VPAD_BUTTON_B; } else { @@ -1071,7 +1061,7 @@ void CemuHooks::hook_InjectXRInput(PPCInterpreter_t* hCPU) { // Whistle gesture if (isHandOverMouthSlot(leftGesture) && isHandOverMouthSlot(rightGesture)) { - if (inputs.inGame.grabState[0].wasDownLastFrame && inputs.inGame.grabState[1].wasDownLastFrame) { + if (inputs.shared.grabState[0].wasDownLastFrame && inputs.shared.grabState[1].wasDownLastFrame) { rumbleMgr->enqueueInputsRumbleCommand({ true, 0, RumbleType::OscillationRaisingSawtoothWave, 1.0f, false, 0.25, 0.2f, 0.2f }); newXRBtnHold |= VPAD_BUTTON_DOWN; } @@ -1150,11 +1140,11 @@ void CemuHooks::hook_CreateNewActor(PPCInterpreter_t* hCPU) { // } // // // test if controller is connected - // if (inputs.inGame.grab[OpenXR::EyeSide::LEFT].currentState == XR_TRUE && inputs.inGame.grab[OpenXR::EyeSide::LEFT].changedSinceLastSync == XR_TRUE) { + // if (inputs.shared.grab[OpenXR::EyeSide::LEFT].currentState == XR_TRUE && inputs.shared.grab[OpenXR::EyeSide::LEFT].changedSinceLastSync == XR_TRUE) { // Log::print("Trying to spawn new thing!"); // hCPU->gpr[3] = 1; // } - // else if (inputs.inGame.grab[OpenXR::EyeSide::RIGHT].currentState == XR_TRUE && inputs.inGame.grab[OpenXR::EyeSide::RIGHT].changedSinceLastSync == XR_TRUE) { + // else if (inputs.shared.grab[OpenXR::EyeSide::RIGHT].currentState == XR_TRUE && inputs.shared.grab[OpenXR::EyeSide::RIGHT].changedSinceLastSync == XR_TRUE) { // Log::print("Trying to spawn new thing!"); // hCPU->gpr[3] = 1; // } diff --git a/src/hooking/weapon.cpp b/src/hooking/weapon.cpp index 82a55b0..76132c0 100644 --- a/src/hooking/weapon.cpp +++ b/src/hooking/weapon.cpp @@ -471,7 +471,7 @@ void CemuHooks::hook_EquipWeapon(PPCInterpreter_t* hCPU) { auto input = VRManager::instance().XR->m_input.load(); // Check both hands for a short press to pick up weapon for (int side = 0; side < 2; ++side) { - auto& grabState = input.inGame.grabState[side]; + auto& grabState = input.shared.grabState[side]; // todo: Make sword smaller while its equipped. I think this might be a member value, but otherwise we can just scale the weapon matrix. //if (input.inGame.in_game && grabState.shortPress) { diff --git a/src/rendering/openxr.cpp b/src/rendering/openxr.cpp index 3f08b86..ecee020 100644 --- a/src/rendering/openxr.cpp +++ b/src/rendering/openxr.cpp @@ -275,6 +275,25 @@ void OpenXR::CreateActions() { checkXRResult(xrCreateAction(actionSet, &actionInfo, &action), std::format("Failed to create action for {}", id).c_str()); }; + { + XrActionSetCreateInfo actionSetInfo = { XR_TYPE_ACTION_SET_CREATE_INFO }; + strcpy_s(actionSetInfo.actionSetName, "shared"); + strcpy_s(actionSetInfo.localizedActionSetName, "Shared"); + actionSetInfo.priority = 0; + checkXRResult(xrCreateActionSet(m_instance, &actionSetInfo, &m_sharedActionSet), "Failed to create controller actions for shared!"); + + createAction(m_sharedActionSet, "pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT, m_gripPoseAction); + createAction(m_sharedActionSet, "aim_pose", "Aim Pose", XR_ACTION_TYPE_POSE_INPUT, m_aimPoseAction); + + createAction(m_sharedActionSet, "modmenu", "Mod Menu", XR_ACTION_TYPE_BOOLEAN_INPUT, m_modMenuAction); + createAction(m_sharedActionSet, "inventory_map", "Open/Close Inventory (Quick press) - Open/Close Map (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_inventory_mapAction); + + createAction(m_sharedActionSet, "grab", "Grab or select weapon/rune from body slots", XR_ACTION_TYPE_FLOAT_INPUT, m_grabAction); + createAction(m_sharedActionSet, "userune_dpadmenu", "Use Rune (Quick press) - Rune menu (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_useRune_dpadMenu_Action); + + createAction(m_sharedActionSet, "rumble", "Rumble", XR_ACTION_TYPE_VIBRATION_OUTPUT, m_rumbleAction); + } + { XrActionSetCreateInfo actionSetInfo = { XR_TYPE_ACTION_SET_CREATE_INFO }; strcpy_s(actionSetInfo.actionSetName, "gameplay_fps"); @@ -282,24 +301,17 @@ void OpenXR::CreateActions() { actionSetInfo.priority = 0; checkXRResult(xrCreateActionSet(m_instance, &actionSetInfo, &m_gameplayActionSet), "Failed to create controller actions for gameplay_fps!"); - createAction(m_gameplayActionSet, "pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT, m_inGameGripPoseAction); - createAction(m_gameplayActionSet, "aim_pose", "Aim Pose", XR_ACTION_TYPE_POSE_INPUT, m_inGameAimPoseAction); createAction(m_gameplayActionSet, "move", "Move", XR_ACTION_TYPE_VECTOR2F_INPUT, m_moveAction); createAction(m_gameplayActionSet, "camera", "Camera Rotation", XR_ACTION_TYPE_VECTOR2F_INPUT, m_cameraAction); - createAction(m_gameplayActionSet, "ingame_modmenu", "Mod Menu", XR_ACTION_TYPE_BOOLEAN_INPUT, m_inGame_modMenuAction); - createAction(m_gameplayActionSet, "grab_interact", "Interact / Pick up objects from floor or weapon from body slots", XR_ACTION_TYPE_FLOAT_INPUT, m_grab_interactAction); + createAction(m_gameplayActionSet, "interact", "Interact / Pick up objects from floor", XR_ACTION_TYPE_FLOAT_INPUT, m_interactAction); createAction(m_gameplayActionSet, "jump", "Jump", XR_ACTION_TYPE_BOOLEAN_INPUT, m_jumpAction); createAction(m_gameplayActionSet, "run_interact_cancel", "Interact (Quick press) - Run/Cancel Interaction (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_run_interactAction); - createAction(m_gameplayActionSet, "userune_dpadmenu", "Use Rune (Quick press) - Dpad menu (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_useRune_dpadMenu_Action); createAction(m_gameplayActionSet, "userighthanditem", "Use/Attack/Throw item held in right hand (Melee attacks/Draw bow/Throw object)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_useRightItemAction); createAction(m_gameplayActionSet, "uselefthanditem", "Use item held in left hand (Rune/Shield Parry)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_useLeftItemAction); createAction(m_gameplayActionSet, "crouch_scope", "Crouch (Quick press) - Open Scope (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_crouch_scopeAction); - createAction(m_gameplayActionSet, "ingame_inventory_map", "Open Inventory (Quick press) - Open Map (Long press)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_inGame_inventory_mapAction); - - createAction(m_gameplayActionSet, "rumble", "Rumble", XR_ACTION_TYPE_VIBRATION_OUTPUT, m_rumbleAction); } { @@ -309,11 +321,8 @@ void OpenXR::CreateActions() { actionSetInfo.priority = 0; checkXRResult(xrCreateActionSet(m_instance, &actionSetInfo, &m_menuActionSet), "Failed to create controller bindings for the menu!"); - createAction(m_menuActionSet, "pose", "Grip Pose", XR_ACTION_TYPE_POSE_INPUT, m_inMenuGripPoseAction); - createAction(m_menuActionSet, "aim_pose", "Aim Pose", XR_ACTION_TYPE_POSE_INPUT, m_inMenuAimPoseAction); - - createAction(m_menuActionSet, "scroll", "Scroll (Left Thumbstick)", XR_ACTION_TYPE_VECTOR2F_INPUT, m_scrollAction); - createAction(m_menuActionSet, "navigate", "Navigate (Right Thumbstick)", XR_ACTION_TYPE_VECTOR2F_INPUT, m_navigateAction); + createAction(m_menuActionSet, "scroll", "Scroll (Right Thumbstick)", XR_ACTION_TYPE_VECTOR2F_INPUT, m_scrollAction); + createAction(m_menuActionSet, "navigate", "Navigate (Left Thumbstick)", XR_ACTION_TYPE_VECTOR2F_INPUT, m_navigateAction); createAction(m_menuActionSet, "select", "Select (A Button)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_selectAction); createAction(m_menuActionSet, "cancel", "Back/Cancel (B Button)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_backAction); createAction(m_menuActionSet, "sort", "Sort (Y Button)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_sortAction); @@ -322,22 +331,25 @@ void OpenXR::CreateActions() { createAction(m_menuActionSet, "right_grip", "Switch To Right Tab (R Button)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_rightGripAction); createAction(m_menuActionSet, "lefttrigger", "Left Trigger", XR_ACTION_TYPE_BOOLEAN_INPUT, m_leftTriggerAction); createAction(m_menuActionSet, "righttrigger", "Right Trigger", XR_ACTION_TYPE_BOOLEAN_INPUT, m_rightTriggerAction); - - createAction(m_menuActionSet, "inmenu_inventory_map", "Close Inventory (Wii U - Start Button) - Close Map (Wii U - Select Button)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_inMenu_inventory_mapAction); - createAction(m_menuActionSet, "inmenu_modmenu", "Mod Menu", XR_ACTION_TYPE_BOOLEAN_INPUT, m_inMenu_modMenuAction); + createAction(m_menuActionSet, "rotate", "Rotate (In inventory) (Right Thumbstick Click)", XR_ACTION_TYPE_BOOLEAN_INPUT, m_rotateAction); } { std::array suggestedBindings = { + // === shared suggestions === + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, + + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/left/input/select/click") }, + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/right/input/select/click") }, + // === gameplay suggestions === - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, XrActionSuggestedBinding{ .action = m_crouch_scopeAction, .binding = GetXRPath("/user/hand/left/input/menu/click") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/left/input/select/click") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/right/input/select/click") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/left/input/select/click") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/right/input/select/click") }, // === menu suggestions === //XrActionSuggestedBinding{ .action = m_inMenu_mapAction, .binding = GetXRPath("/user/hand/right/input/menu/click") }, @@ -355,35 +367,37 @@ void OpenXR::CreateActions() { { std::array suggestedBindings = { + // === shared suggestions === + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, + + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/left/input/squeeze/value") }, + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/right/input/squeeze/value") }, + + XrActionSuggestedBinding{ .action = m_useRune_dpadMenu_Action, .binding = GetXRPath("/user/hand/left/input/y/click") }, + XrActionSuggestedBinding{ .action = m_modMenuAction, .binding = GetXRPath("/user/hand/left/input/x/click") }, + XrActionSuggestedBinding{ .action = m_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, + + XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/left/output/haptic") }, + XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/right/output/haptic") }, + // === gameplay suggestions === - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, XrActionSuggestedBinding{ .action = m_moveAction, .binding = GetXRPath("/user/hand/left/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_cameraAction, .binding = GetXRPath("/user/hand/right/input/thumbstick") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/left/input/squeeze/value") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/right/input/squeeze/value") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/left/input/squeeze/value") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/right/input/squeeze/value") }, XrActionSuggestedBinding{ .action = m_jumpAction, .binding = GetXRPath("/user/hand/right/input/b/click") }, XrActionSuggestedBinding{ .action = m_run_interactAction, .binding = GetXRPath("/user/hand/right/input/a/click") }, - XrActionSuggestedBinding{ .action = m_useRune_dpadMenu_Action, .binding = GetXRPath("/user/hand/left/input/y/click") }, - XrActionSuggestedBinding{ .action = m_inGame_modMenuAction, .binding = GetXRPath("/user/hand/left/input/x/click") }, XrActionSuggestedBinding{ .action = m_useLeftItemAction, .binding = GetXRPath("/user/hand/left/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_useRightItemAction, .binding = GetXRPath("/user/hand/right/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_crouch_scopeAction, .binding = GetXRPath("/user/hand/left/input/thumbstick/click") }, - XrActionSuggestedBinding{ .action = m_inGame_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, - - XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/left/output/haptic") }, - XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/right/output/haptic") }, // === menu suggestions === - XrActionSuggestedBinding{ .action = m_inMenuGripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuGripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuAimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuAimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, XrActionSuggestedBinding{ .action = m_scrollAction, .binding = GetXRPath("/user/hand/right/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_navigateAction, .binding = GetXRPath("/user/hand/left/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_selectAction, .binding = GetXRPath("/user/hand/right/input/a/click") }, @@ -394,8 +408,7 @@ void OpenXR::CreateActions() { XrActionSuggestedBinding{ .action = m_rightGripAction, .binding = GetXRPath("/user/hand/right/input/squeeze/value") }, XrActionSuggestedBinding{ .action = m_leftTriggerAction, .binding = GetXRPath("/user/hand/left/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_rightTriggerAction, .binding = GetXRPath("/user/hand/right/input/trigger/value") }, - XrActionSuggestedBinding{ .action = m_inMenu_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, - XrActionSuggestedBinding{ .action = m_inMenu_modMenuAction, .binding = GetXRPath("/user/hand/left/input/x/click") }, + XrActionSuggestedBinding{ .action = m_rotateAction, .binding = GetXRPath("/user/hand/left/input/thumbstick/click") }, }; XrInteractionProfileSuggestedBinding suggestedBindingsInfo = { XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING }; suggestedBindingsInfo.interactionProfile = GetXRPath("/interaction_profiles/oculus/touch_controller"); @@ -406,35 +419,37 @@ void OpenXR::CreateActions() { { std::array suggestedBindings = { + // === shared suggestions === + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_gripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, + XrActionSuggestedBinding{ .action = m_aimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, + + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/left/input/squeeze/force") }, + XrActionSuggestedBinding{ .action = m_grabAction, .binding = GetXRPath("/user/hand/right/input/squeeze/force") }, + + XrActionSuggestedBinding{ .action = m_useRune_dpadMenu_Action, .binding = GetXRPath("/user/hand/left/input/b/click") }, + XrActionSuggestedBinding{ .action = m_modMenuAction, .binding = GetXRPath("/user/hand/left/input/a/click") }, + XrActionSuggestedBinding{ .action = m_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, + + XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/left/output/haptic") }, + XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/right/output/haptic") }, + // === gameplay suggestions === - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameGripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, - XrActionSuggestedBinding{ .action = m_inGameAimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, XrActionSuggestedBinding{ .action = m_moveAction, .binding = GetXRPath("/user/hand/left/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_cameraAction, .binding = GetXRPath("/user/hand/right/input/thumbstick") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/left/input/squeeze/force") }, - XrActionSuggestedBinding{ .action = m_grab_interactAction, .binding = GetXRPath("/user/hand/right/input/squeeze/force") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/left/input/squeeze/force") }, + XrActionSuggestedBinding{ .action = m_interactAction, .binding = GetXRPath("/user/hand/right/input/squeeze/force") }, XrActionSuggestedBinding{ .action = m_jumpAction, .binding = GetXRPath("/user/hand/right/input/b/click") }, XrActionSuggestedBinding{ .action = m_run_interactAction, .binding = GetXRPath("/user/hand/right/input/a/click") }, - XrActionSuggestedBinding{ .action = m_useRune_dpadMenu_Action, .binding = GetXRPath("/user/hand/left/input/b/click") }, - XrActionSuggestedBinding{ .action = m_inGame_modMenuAction, .binding = GetXRPath("/user/hand/left/input/a/click") }, XrActionSuggestedBinding{ .action = m_useLeftItemAction, .binding = GetXRPath("/user/hand/left/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_useRightItemAction, .binding = GetXRPath("/user/hand/right/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_crouch_scopeAction, .binding = GetXRPath("/user/hand/left/input/thumbstick/click") }, - XrActionSuggestedBinding{ .action = m_inGame_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, - - XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/left/output/haptic") }, - XrActionSuggestedBinding{ .action = m_rumbleAction, .binding = GetXRPath("/user/hand/right/output/haptic") }, // === menu suggestions === - XrActionSuggestedBinding{ .action = m_inMenuGripPoseAction, .binding = GetXRPath("/user/hand/left/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuGripPoseAction, .binding = GetXRPath("/user/hand/right/input/grip/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuAimPoseAction, .binding = GetXRPath("/user/hand/left/input/aim/pose") }, - XrActionSuggestedBinding{ .action = m_inMenuAimPoseAction, .binding = GetXRPath("/user/hand/right/input/aim/pose") }, XrActionSuggestedBinding{ .action = m_scrollAction, .binding = GetXRPath("/user/hand/right/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_navigateAction, .binding = GetXRPath("/user/hand/left/input/thumbstick") }, XrActionSuggestedBinding{ .action = m_selectAction, .binding = GetXRPath("/user/hand/right/input/a/click") }, @@ -445,8 +460,7 @@ void OpenXR::CreateActions() { XrActionSuggestedBinding{ .action = m_rightGripAction, .binding = GetXRPath("/user/hand/right/input/squeeze/force") }, XrActionSuggestedBinding{ .action = m_leftTriggerAction, .binding = GetXRPath("/user/hand/left/input/trigger/value") }, XrActionSuggestedBinding{ .action = m_rightTriggerAction, .binding = GetXRPath("/user/hand/right/input/trigger/value") }, - XrActionSuggestedBinding{ .action = m_inMenu_inventory_mapAction, .binding = GetXRPath("/user/hand/right/input/thumbstick/click") }, - XrActionSuggestedBinding{ .action = m_inMenu_modMenuAction, .binding = GetXRPath("/user/hand/left/input/a/click") }, + XrActionSuggestedBinding{ .action = m_rotateAction, .binding = GetXRPath("/user/hand/left/input/thumbstick/click") }, }; XrInteractionProfileSuggestedBinding suggestedBindingsInfo = { XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING }; suggestedBindingsInfo.interactionProfile = GetXRPath("/interaction_profiles/valve/index_controller"); @@ -456,25 +470,17 @@ void OpenXR::CreateActions() { } XrSessionActionSetsAttachInfo attachInfo = { XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO }; - std::array actionSets = { m_gameplayActionSet, m_menuActionSet }; + std::array actionSets = { m_sharedActionSet, m_gameplayActionSet, m_menuActionSet }; attachInfo.countActionSets = (uint32_t)actionSets.size(); attachInfo.actionSets = actionSets.data(); checkXRResult(xrAttachSessionActionSets(m_session, &attachInfo), "Failed to attach action sets to session!"); for (EyeSide side : { EyeSide::LEFT, EyeSide::RIGHT }) { XrActionSpaceCreateInfo createInfo = { XR_TYPE_ACTION_SPACE_CREATE_INFO }; - createInfo.action = m_inGameGripPoseAction; - createInfo.subactionPath = m_handPaths[side]; - createInfo.poseInActionSpace = s_xrIdentityPose; - checkXRResult(xrCreateActionSpace(m_session, &createInfo, &m_inGameHandSpaces[side]), "Failed to create action space for hand pose!"); - } - - for (EyeSide side : { EyeSide::LEFT, EyeSide::RIGHT }) { - XrActionSpaceCreateInfo createInfo = { XR_TYPE_ACTION_SPACE_CREATE_INFO }; - createInfo.action = m_inMenuGripPoseAction; + createInfo.action = m_gripPoseAction; createInfo.subactionPath = m_handPaths[side]; createInfo.poseInActionSpace = s_xrIdentityPose; - checkXRResult(xrCreateActionSpace(m_session, &createInfo, &m_inMenuHandSpaces[side]), "Failed to create action space for hand pose!"); + checkXRResult(xrCreateActionSpace(m_session, &createInfo, &m_handSpaces[side]), "Failed to create action space for hand pose!"); } // initialize rumble manager @@ -527,11 +533,11 @@ void CheckButtonState(bool buttonPressed, ButtonState& buttonState) { } std::optional OpenXR::UpdateActions(XrTime predictedFrameTime, glm::fquat controllerRotation, bool inMenu) { - XrActiveActionSet activeActionSet = { (inMenu ? m_menuActionSet : m_gameplayActionSet), XR_NULL_PATH }; + XrActiveActionSet activeActionSets[2] = { { m_sharedActionSet, XR_NULL_PATH }, { (inMenu ? m_menuActionSet : m_gameplayActionSet), XR_NULL_PATH } }; XrActionsSyncInfo syncInfo = { XR_TYPE_ACTIONS_SYNC_INFO }; - syncInfo.countActiveActionSets = 1; - syncInfo.activeActionSets = &activeActionSet; + syncInfo.countActiveActionSets = 2; + syncInfo.activeActionSets = &activeActionSets[0]; checkXRResult(xrSyncActions(m_session, &syncInfo), "Failed to sync actions!"); InputState newState = m_input.load(); @@ -540,7 +546,7 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim for (EyeSide side : { EyeSide::LEFT, EyeSide::RIGHT }) { XrActionStateGetInfo getPoseInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; - getPoseInfo.action = newState.shared.in_game ? m_inGameGripPoseAction : m_inMenuGripPoseAction; + getPoseInfo.action = m_gripPoseAction; getPoseInfo.subactionPath = m_handPaths[side]; newState.shared.pose[side] = { XR_TYPE_ACTION_STATE_POSE }; checkXRResult(xrGetActionStatePose(m_session, &getPoseInfo, &newState.shared.pose[side]), "Failed to get pose of controller!"); @@ -551,7 +557,7 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim spaceLocation.next = &spaceVelocity; newState.shared.poseVelocity[side].linearVelocity = { 0.0f, 0.0f, 0.0f }; newState.shared.poseVelocity[side].angularVelocity = { 0.0f, 0.0f, 0.0f }; - XrSpace handSpace = newState.shared.in_game ? m_inGameHandSpaces[side] : m_inMenuHandSpaces[side]; + XrSpace handSpace = m_handSpaces[side]; checkXRResult(xrLocateSpace(handSpace, m_stageSpace, predictedFrameTime, &spaceLocation), "Failed to get location from controllers!"); if ((spaceLocation.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0 && (spaceLocation.locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) != 0) { newState.shared.poseLocation[side] = spaceLocation; @@ -574,7 +580,7 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim } // update shared actions XrActionStateGetInfo getInventoryMapInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; - getInventoryMapInfo.action = newState.shared.in_game ? m_inGame_inventory_mapAction : m_inMenu_inventory_mapAction; + getInventoryMapInfo.action = m_inventory_mapAction; getInventoryMapInfo.subactionPath = XR_NULL_PATH; auto& inventory_mapAction = newState.shared.inventory_map; inventory_mapAction = { XR_TYPE_ACTION_STATE_BOOLEAN }; @@ -587,7 +593,7 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim } XrActionStateGetInfo getModMenuInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; - getModMenuInfo.action = newState.shared.in_game ? m_inGame_modMenuAction : m_inMenu_modMenuAction; + getModMenuInfo.action = m_modMenuAction; getModMenuInfo.subactionPath = XR_NULL_PATH; auto& modMenuAction = newState.shared.modMenu; modMenuAction = { XR_TYPE_ACTION_STATE_BOOLEAN }; @@ -599,6 +605,32 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim CheckButtonState(buttonPressed, modMenuButtonState); } + for (EyeSide side : { EyeSide::LEFT, EyeSide::RIGHT }) { + XrActionStateGetInfo getGrabInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; + getGrabInfo.action = m_grabAction; + getGrabInfo.subactionPath = m_handPaths[side]; + newState.shared.grab[side] = { XR_TYPE_ACTION_STATE_FLOAT }; + checkXRResult(xrGetActionStateFloat(m_session, &getGrabInfo, &newState.shared.grab[side]), "Failed to get grab action value!"); + + auto& buttonState = newState.shared.grabState[side]; + if (newState.shared.grab[side].isActive == XR_TRUE) { + auto buttonPressed = newState.shared.grab[side].currentState > 0.75f; + CheckButtonState(buttonPressed, buttonState); + } + } + + XrActionStateGetInfo getUseRuneInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; + getUseRuneInfo.action = m_useRune_dpadMenu_Action; + getUseRuneInfo.subactionPath = XR_NULL_PATH; + newState.shared.useRune_dpadMenu = { XR_TYPE_ACTION_STATE_BOOLEAN }; + checkXRResult(xrGetActionStateBoolean(m_session, &getUseRuneInfo, &newState.shared.useRune_dpadMenu), "Failed to get use rune action value!"); + + auto& useRuneButtonState = newState.shared.useRune_runeMenuState; + if (newState.shared.useRune_dpadMenu.isActive == XR_TRUE) { + auto buttonPressed = newState.shared.useRune_dpadMenu.currentState == XR_TRUE; + CheckButtonState(buttonPressed, useRuneButtonState); + } + // update in-menu or in-game actions if (inMenu) { XrActionStateGetInfo getScrollInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; @@ -666,18 +698,24 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim getRightTriggerInfo.subactionPath = XR_NULL_PATH; newState.inMenu.rightTrigger = { XR_TYPE_ACTION_STATE_BOOLEAN }; checkXRResult(xrGetActionStateBoolean(m_session, &getRightTriggerInfo, &newState.inMenu.rightTrigger), "Failed to get right trigger action value!"); + + XrActionStateGetInfo getRotateInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; + getRotateInfo.action = m_rotateAction; + getRotateInfo.subactionPath = XR_NULL_PATH; + newState.inMenu.rotate = { XR_TYPE_ACTION_STATE_BOOLEAN }; + checkXRResult(xrGetActionStateBoolean(m_session, &getRotateInfo, &newState.inMenu.rotate), "Failed to get rotate action value!"); } else { for (EyeSide side : { EyeSide::LEFT, EyeSide::RIGHT }) { XrActionStateGetInfo getGrabInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; - getGrabInfo.action = m_grab_interactAction; + getGrabInfo.action = m_interactAction; getGrabInfo.subactionPath = m_handPaths[side]; - newState.inGame.grab[side] = { XR_TYPE_ACTION_STATE_FLOAT }; - checkXRResult(xrGetActionStateFloat(m_session, &getGrabInfo, &newState.inGame.grab[side]), "Failed to get grab action value!"); + newState.inGame.interact[side] = { XR_TYPE_ACTION_STATE_FLOAT }; + checkXRResult(xrGetActionStateFloat(m_session, &getGrabInfo, &newState.inGame.interact[side]), "Failed to get grab action value!"); - auto& buttonState = newState.inGame.grabState[side]; - if (newState.inGame.grab[side].isActive == XR_TRUE) { - auto buttonPressed = newState.inGame.grab[side].currentState > 0.75f; + auto& buttonState = newState.inGame.interactState[side]; + if (newState.inGame.interact[side].isActive == XR_TRUE) { + auto buttonPressed = newState.inGame.interact[side].currentState > 0.75f; CheckButtonState(buttonPressed, buttonState); } } @@ -722,18 +760,6 @@ std::optional OpenXR::UpdateActions(XrTime predictedFrameTim CheckButtonState(buttonPressed, runButtonState); } - XrActionStateGetInfo getUseRuneInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; - getUseRuneInfo.action = m_useRune_dpadMenu_Action; - getUseRuneInfo.subactionPath = XR_NULL_PATH; - newState.inGame.useRune_dpadMenu = { XR_TYPE_ACTION_STATE_BOOLEAN }; - checkXRResult(xrGetActionStateBoolean(m_session, &getUseRuneInfo, &newState.inGame.useRune_dpadMenu), "Failed to get use rune action value!"); - - auto& useRuneButtonState = newState.inGame.useRune_runeMenuState; - if (newState.inGame.useRune_dpadMenu.isActive == XR_TRUE) { - auto buttonPressed = newState.inGame.useRune_dpadMenu.currentState == XR_TRUE; - CheckButtonState(buttonPressed, useRuneButtonState); - } - XrActionStateGetInfo getUseRightItemInfo = { XR_TYPE_ACTION_STATE_GET_INFO }; getUseRightItemInfo.action = m_useRightItemAction; getUseRightItemInfo.subactionPath = XR_NULL_PATH; diff --git a/src/rendering/openxr.h b/src/rendering/openxr.h index ede8927..51a4171 100644 --- a/src/rendering/openxr.h +++ b/src/rendering/openxr.h @@ -65,6 +65,11 @@ class OpenXR { ButtonState inventory_mapState; XrActionStateBoolean modMenu; ButtonState modMenuState; + + std::array grab; + std::array grabState; // LEFT/RIGHT + XrActionStateBoolean useRune_dpadMenu; + ButtonState useRune_runeMenuState; } shared; struct InGame { @@ -74,19 +79,17 @@ class OpenXR { XrActionStateVector2f move; XrActionStateVector2f camera; - std::array grab; + std::array interact; XrActionStateBoolean jump_cancel; XrActionStateBoolean run_interact; ButtonState runState; - XrActionStateBoolean useRune_dpadMenu; - ButtonState useRune_runeMenuState; XrActionStateBoolean useLeftItem; XrActionStateBoolean useRightItem; std::array drop_weapon; // LEFT/RIGHT - std::array grabState; // LEFT/RIGHT + std::array interactState; // LEFT/RIGHT } inGame; struct InMenu { XrActionStateVector2f scroll; @@ -103,11 +106,26 @@ class OpenXR { XrActionStateBoolean leftTrigger; XrActionStateBoolean rightTrigger; + + XrActionStateBoolean rotate; } inMenu; }; std::atomic m_input = InputState{}; std::atomic m_inputCameraRotation = glm::identity(); + class DpadMenuButton { + public: + static bool LGrab(InputState inputState) { + return inputState.shared.grabState[0].wasDownLastFrame; + }; + static bool RGrab(InputState inputState) { + return inputState.shared.grabState[1].wasDownLastFrame; + }; + static bool Rune(InputState inputState) { + return inputState.shared.useRune_runeMenuState.wasDownLastFrame; + }; + }; + struct GameState { uint32_t previous_button_hold; bool in_game = false; @@ -116,6 +134,7 @@ class OpenXR { bool dpad_menu_open_requested = false; bool was_dpad_menu_open = false; EquipType last_dpad_menu_open = EquipType::None; + bool (*current_dpad_menu_button)(InputState) = nullptr; bool prevent_inputs = false; std::chrono::steady_clock::time_point prevent_inputs_time; @@ -196,33 +215,36 @@ class OpenXR { XrSession m_session = XR_NULL_HANDLE; XrSpace m_stageSpace = XR_NULL_HANDLE; XrSpace m_headSpace = XR_NULL_HANDLE; - std::array m_inGameHandSpaces = { XR_NULL_HANDLE, XR_NULL_HANDLE }; - std::array m_inMenuHandSpaces = { XR_NULL_HANDLE, XR_NULL_HANDLE }; + std::array m_handSpaces = { XR_NULL_HANDLE, XR_NULL_HANDLE }; std::array m_handPaths = { XR_NULL_PATH, XR_NULL_PATH }; - XrAction m_inGameGripPoseAction = XR_NULL_HANDLE; - XrAction m_inGameAimPoseAction = XR_NULL_HANDLE; - XrAction m_inMenuGripPoseAction = XR_NULL_HANDLE; - XrAction m_inMenuAimPoseAction = XR_NULL_HANDLE; + //shared actions + XrActionSet m_sharedActionSet = XR_NULL_HANDLE; + + XrAction m_gripPoseAction = XR_NULL_HANDLE; + XrAction m_aimPoseAction = XR_NULL_HANDLE; + + XrAction m_modMenuAction = XR_NULL_HANDLE; //imgui mod menu + XrAction m_inventory_mapAction = XR_NULL_HANDLE; + + XrAction m_grabAction = XR_NULL_HANDLE; + XrAction m_useRune_dpadMenu_Action = XR_NULL_HANDLE; + + XrAction m_rumbleAction = XR_NULL_HANDLE; // gameplay actions XrActionSet m_gameplayActionSet = XR_NULL_HANDLE; XrAction m_moveAction = XR_NULL_HANDLE; XrAction m_cameraAction = XR_NULL_HANDLE; - XrAction m_grab_interactAction = XR_NULL_HANDLE; + XrAction m_interactAction = XR_NULL_HANDLE; XrAction m_jumpAction = XR_NULL_HANDLE; XrAction m_run_interactAction = XR_NULL_HANDLE; - XrAction m_useRune_dpadMenu_Action = XR_NULL_HANDLE; - XrAction m_inGame_modMenuAction = XR_NULL_HANDLE; //imgui mod menu XrAction m_useLeftItemAction = XR_NULL_HANDLE; XrAction m_useRightItemAction = XR_NULL_HANDLE; XrAction m_crouch_scopeAction = XR_NULL_HANDLE; - XrAction m_inGame_inventory_mapAction = XR_NULL_HANDLE; - - XrAction m_rumbleAction = XR_NULL_HANDLE; // menu actions XrActionSet m_menuActionSet = XR_NULL_HANDLE; @@ -238,8 +260,7 @@ class OpenXR { XrAction m_leftTriggerAction= XR_NULL_HANDLE; XrAction m_rightTriggerAction = XR_NULL_HANDLE; - XrAction m_inMenu_modMenuAction = XR_NULL_HANDLE; //imgui mod menu - XrAction m_inMenu_inventory_mapAction = XR_NULL_HANDLE; + XrAction m_rotateAction = XR_NULL_HANDLE; //right stick click std::unique_ptr m_renderer; std::unique_ptr m_rumbleManager;