mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 04:04:18 +02:00
Refactor OpenXR controller input handling and update settings panel interactions
This commit is contained in:
1 parent
60c443654f
commit
e681294709
11 files changed
+163
-95
No files matched your search
@@ -1,9 +1,9 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
//
|
||||
// The in-headset settings panel's controller handling, tested without a
|
||||
// headset: the thumbstick chord that opens and closes it, the release latch that
|
||||
// keeps a closing press out of the game, selection, scrolling, and where a hit
|
||||
// lands on the panel's canvas.
|
||||
// headset: the button that opens and closes it in each controller mode, the
|
||||
// release latch that keeps a closing press out of the game, selection,
|
||||
// scrolling, and where a hit lands on the panel's canvas.
|
||||
|
||||
#include "vr/openxr_settings_panel.h"
|
||||
|
||||
@@ -32,6 +32,8 @@ void CheckNear(float actual, float expected, const char* what, float tolerance =
|
||||
}
|
||||
|
||||
constexpr float kDt = 1.0f / 90.0f;
|
||||
constexpr OpenXRControllerMode kWiiRemote = OpenXRControllerMode::WiiRemote;
|
||||
constexpr OpenXRControllerMode kGamepad = OpenXRControllerMode::Gamepad;
|
||||
|
||||
std::array<HandInputs, 2> Released() {
|
||||
return {};
|
||||
@@ -44,46 +46,80 @@ std::array<HandInputs, 2> Chord() {
|
||||
return hands;
|
||||
}
|
||||
|
||||
void ChordOpensAndClosesOnce() {
|
||||
std::array<HandInputs, 2> LeftY() {
|
||||
std::array<HandInputs, 2> hands{};
|
||||
hands[0].secondary = true;
|
||||
return hands;
|
||||
}
|
||||
|
||||
void LeftYOpensAndClosesOnceAsAWiiRemote() {
|
||||
Controls controls;
|
||||
bool open = false;
|
||||
|
||||
auto right_b = Released();
|
||||
right_b[1].secondary = true;
|
||||
Frame frame = controls.Update(right_b, open, kDt, kWiiRemote);
|
||||
Check(!open && !frame.withheld, "right B neither opens nor withholds");
|
||||
frame = controls.Update(Chord(), open, kDt, kWiiRemote);
|
||||
Check(!open && !frame.withheld, "as a Wii Remote the thumbstick chord does not open the panel");
|
||||
controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
|
||||
frame = controls.Update(LeftY(), open, kDt, kWiiRemote);
|
||||
Check(open && frame.open && frame.withheld, "left Y opens the panel");
|
||||
frame = controls.Update(LeftY(), open, kDt, kWiiRemote);
|
||||
Check(open, "holding left Y does not toggle again");
|
||||
frame = controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
Check(open && frame.withheld, "the panel stays open and keeps the controllers after left Y is released");
|
||||
|
||||
frame = controls.Update(LeftY(), open, kDt, kWiiRemote);
|
||||
Check(!open && !frame.open, "left Y closes the panel again");
|
||||
Check(frame.withheld, "the closing press is still withheld from the game");
|
||||
frame = controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
Check(!frame.withheld, "the game gets the controllers back once everything is released");
|
||||
}
|
||||
|
||||
void ChordOpensAndClosesOnceAsAGamepad() {
|
||||
Controls controls;
|
||||
bool open = false;
|
||||
|
||||
Frame frame = controls.Update(LeftY(), open, kDt, kGamepad);
|
||||
Check(!open && !frame.withheld, "as a gamepad left Y is GameCube Y, not the panel");
|
||||
auto one = Released();
|
||||
one[0].thumbstick_click = true;
|
||||
Frame frame = controls.Update(one, open, kDt);
|
||||
frame = controls.Update(one, open, kDt, kGamepad);
|
||||
Check(!open && !frame.withheld, "one thumbstick click alone neither opens nor withholds");
|
||||
|
||||
frame = controls.Update(Chord(), open, kDt);
|
||||
frame = controls.Update(Chord(), open, kDt, kGamepad);
|
||||
Check(open && frame.open && frame.withheld, "clicking both thumbsticks opens the panel");
|
||||
frame = controls.Update(Chord(), open, kDt);
|
||||
frame = controls.Update(Chord(), open, kDt, kGamepad);
|
||||
Check(open, "holding the chord does not toggle again");
|
||||
frame = controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(Released(), open, kDt, kGamepad);
|
||||
Check(open && frame.withheld, "the panel stays open and keeps the controllers after the chord is released");
|
||||
|
||||
frame = controls.Update(Chord(), open, kDt);
|
||||
frame = controls.Update(Chord(), open, kDt, kGamepad);
|
||||
Check(!open && !frame.open, "the chord closes the panel again");
|
||||
Check(frame.withheld, "the closing chord is still withheld from the game");
|
||||
frame = controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(Released(), open, kDt, kGamepad);
|
||||
Check(!frame.withheld, "the game gets the controllers back once everything is released");
|
||||
}
|
||||
|
||||
void MenuClosesAndItsPressStaysOutOfTheGame() {
|
||||
Controls controls;
|
||||
bool open = false;
|
||||
controls.Update(Chord(), open, kDt);
|
||||
controls.Update(Released(), open, kDt);
|
||||
controls.Update(LeftY(), open, kDt, kWiiRemote);
|
||||
controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
|
||||
auto menu = Released();
|
||||
menu[0].menu = true;
|
||||
Frame frame = controls.Update(menu, open, kDt);
|
||||
Frame frame = controls.Update(menu, open, kDt, kWiiRemote);
|
||||
Check(!open, "the left menu button closes an open panel");
|
||||
frame = controls.Update(menu, open, kDt);
|
||||
Check(frame.withheld, "HOME held across the close does not reach the game");
|
||||
frame = controls.Update(menu, open, kDt, kWiiRemote);
|
||||
Check(frame.withheld, "+ held across the close does not reach the game");
|
||||
Check(!open, "a held menu button does not reopen the panel");
|
||||
frame = controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
Check(!frame.withheld, "released, the controllers go back to the game");
|
||||
|
||||
frame = controls.Update(menu, open, kDt);
|
||||
frame = controls.Update(menu, open, kDt, kWiiRemote);
|
||||
Check(!open && !frame.withheld, "with the panel closed the menu button is the game's");
|
||||
}
|
||||
|
||||
@@ -93,49 +129,49 @@ void SelectWaitsForAReleaseAndFollowsTheTrigger() {
|
||||
// Opened from the settings bar while a trigger is held for the game.
|
||||
auto trigger = Released();
|
||||
trigger[1].trigger = 1.0f;
|
||||
controls.Update(trigger, open, kDt);
|
||||
controls.Update(trigger, open, kDt, kWiiRemote);
|
||||
open = true;
|
||||
Frame frame = controls.Update(trigger, open, kDt);
|
||||
Frame frame = controls.Update(trigger, open, kDt, kWiiRemote);
|
||||
Check(frame.open && !frame.select, "a trigger held from before the panel opened does not click");
|
||||
frame = controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
Check(!frame.select, "nothing held, nothing selected");
|
||||
frame = controls.Update(trigger, open, kDt);
|
||||
frame = controls.Update(trigger, open, kDt, kWiiRemote);
|
||||
Check(frame.select && frame.pointing_hand == 1, "a fresh right trigger selects and points with the right hand");
|
||||
|
||||
auto left = Released();
|
||||
left[0].trigger = 0.9f;
|
||||
controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(left, open, kDt);
|
||||
controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
frame = controls.Update(left, open, kDt, kWiiRemote);
|
||||
Check(frame.select && frame.pointing_hand == 0, "pulling the left trigger hands the pointer to the left hand");
|
||||
|
||||
auto button = Released();
|
||||
button[1].primary = true;
|
||||
controls.Update(Released(), open, kDt);
|
||||
frame = controls.Update(button, open, kDt);
|
||||
controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
frame = controls.Update(button, open, kDt, kWiiRemote);
|
||||
Check(frame.select && frame.pointing_hand == 0, "A selects without moving the pointer to another hand");
|
||||
}
|
||||
|
||||
void ThumbstickScrolls() {
|
||||
Controls controls;
|
||||
bool open = true;
|
||||
controls.Update(Released(), open, kDt);
|
||||
controls.Update(Released(), open, kDt, kWiiRemote);
|
||||
|
||||
auto small = Released();
|
||||
small[1].stick_y = 0.2f;
|
||||
Check(controls.Update(small, open, kDt).wheel == 0.0f, "a resting thumbstick does not scroll");
|
||||
Check(controls.Update(small, open, kDt, kWiiRemote).wheel == 0.0f, "a resting thumbstick does not scroll");
|
||||
|
||||
auto up = Released();
|
||||
up[1].stick_y = 1.0f;
|
||||
CheckNear(controls.Update(up, open, 0.5f).wheel, kScrollStepsPerSecond * 0.1f,
|
||||
CheckNear(controls.Update(up, open, 0.5f, kWiiRemote).wheel, kScrollStepsPerSecond * 0.1f,
|
||||
"full deflection scrolls up at the full rate, with a long frame clamped");
|
||||
auto down = Released();
|
||||
down[0].stick_y = -1.0f;
|
||||
down[1].stick_y = 0.3f;
|
||||
Check(controls.Update(down, open, kDt).wheel < 0.0f, "the more deflected stick decides the direction");
|
||||
Check(controls.Update(down, open, kDt, kWiiRemote).wheel < 0.0f, "the more deflected stick decides the direction");
|
||||
|
||||
bool closed = false;
|
||||
Controls idle;
|
||||
Check(idle.Update(up, closed, kDt).wheel == 0.0f, "a closed panel does not scroll");
|
||||
Check(idle.Update(up, closed, kDt, kWiiRemote).wheel == 0.0f, "a closed panel does not scroll");
|
||||
}
|
||||
|
||||
void HitsMapOntoTheCanvas() {
|
||||
@@ -175,7 +211,8 @@ void BridgeAccumulatesWheelUntilTaken() {
|
||||
} // namespace
|
||||
|
||||
int main() {
|
||||
ChordOpensAndClosesOnce();
|
||||
LeftYOpensAndClosesOnceAsAWiiRemote();
|
||||
ChordOpensAndClosesOnceAsAGamepad();
|
||||
MenuClosesAndItsPressStaysOutOfTheGame();
|
||||
SelectWaitsForAReleaseAndFollowsTheTrigger();
|
||||
ThumbstickScrolls();
|
||||
|
||||
@@ -247,24 +247,33 @@ void TestButtons() {
|
||||
Check(RemoteButtons(left, right) == kButtonOne, "right stick up is 1");
|
||||
right.stick_y = -0.9f;
|
||||
Check(RemoteButtons(left, right) == kButtonTwo, "right stick down is 2");
|
||||
right.stick_y = 0.3f;
|
||||
Check(RemoteButtons(left, right) == 0, "a light push is no press");
|
||||
right.stick_y = 0.0f;
|
||||
right.stick_x = -0.9f;
|
||||
Check(RemoteButtons(left, right) == kButtonMinus, "right stick left is -");
|
||||
Check(RemoteButtons(left, right) == 0, "right stick left is unbound");
|
||||
right.stick_x = 0.9f;
|
||||
Check(RemoteButtons(left, right) == kButtonPlus, "right stick right is +");
|
||||
right.stick_x = 0.3f;
|
||||
Check(RemoteButtons(left, right) == 0, "a light push is no press");
|
||||
Check(RemoteButtons(left, right) == 0, "right stick right is unbound");
|
||||
|
||||
right = {};
|
||||
left.primary = true;
|
||||
left.menu = true;
|
||||
Check(RemoteButtons(left, right) == (kButtonMinus | kButtonPlus), "left X and menu are - and +");
|
||||
left = {};
|
||||
left.squeeze = 0.8f;
|
||||
left.trigger = 0.7f;
|
||||
Check(RemoteButtons(left, right) == (kButtonHome | kButtonC | kButtonZ), "left menu, grip, trigger are HOME, C, Z");
|
||||
// Left X and Y have no Wii button in the profile.
|
||||
Check(RemoteButtons(left, right) == (kButtonC | kButtonZ), "left grip and trigger are C and Z");
|
||||
// Left Y is the settings panel's button, and nothing presses HOME.
|
||||
left = {};
|
||||
left.primary = true;
|
||||
left.secondary = true;
|
||||
Check(RemoteButtons(left, right) == 0, "left X/Y are unbound");
|
||||
right.secondary = true;
|
||||
right.thumbstick_click = true;
|
||||
left.thumbstick_click = true;
|
||||
Check(RemoteButtons(left, right) == 0, "left Y, right B and the stick clicks are unbound");
|
||||
left = {};
|
||||
right = {};
|
||||
left.menu = true;
|
||||
Check((RemoteButtons(left, right) & kButtonHome) == 0, "left menu is no longer HOME");
|
||||
|
||||
left.stick_x = 1.0f;
|
||||
left.stick_y = 1.0f;
|
||||
|
||||
Reference in new issue
Block a user