Hold the gas while a bare hand holds the wheel

- On a Quest 3 the race controls never engaged: grabbing the wheel gave no gas and a right pinch
  stayed A. They waited for the game to switch the remote's pointer off, and MKW keeps it on in a
  race (the log only ever said "the game's pointer is on").
- The race controls now apply while a bare hand holds the wheel: that holds the gas, and a free
  hand's pinch (either hand) uses an item. With no bare hand on the wheel a right pinch stays A,
  which is what the pause menu and the results need. The flick still works in the whole cockpit.
- The game-pointer publication (KPAD hook and bridge) is gone. The "tracked hands" source line is
  logged at most once a second: camera-tracked hands drop in and out of view often.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
iChris4andClaude Opus 5.5 committed 2026-09-25 00:40:56 +02:00
1 parent 771a143254
commit d3ad9fbd56
8 files changed
+72 -86

No files matched your search

+13 -12
View File
@@ -256,23 +256,24 @@ inline void ApplyHandDrivenButtons(std::array<wii_remote::HandInputs, 2>& hands,
}
}
// In a cockpit race, after the wheel: a bare hand on the wheel holds the gas
// (A: the right primary button), and an item pinch uses an item (the left
// trigger: the Wii Remote's Z, the GameCube's L). A hand-driven right hand's
// pinch stops meaning A there. The grasp itself never becomes a squeeze, which
// would press the gamepad's shoulders (GameCube R drifts).
inline void ApplyBareHandRace(std::array<wii_remote::HandInputs, 2>& hands,
const std::array<bool, 2>& hand_driven, const std::array<bool, 2>& bare_held,
// In the cockpit, after the wheel. While a bare hand holds the wheel it holds
// the gas (A: the right primary button, whatever a right pinch says), and an
// item pinch uses an item (the left trigger: the Wii Remote's Z, the
// GameCube's L). With no bare hand on the wheel nothing changes, so a right
// pinch stays A for the menus inside a race (the pause menu, the results),
// which the game's pointer cannot tell from driving: MKW keeps it on in a
// race. The grasp itself never becomes a squeeze, which would press the
// gamepad's shoulders (GameCube R drifts). True while a bare hand holds.
inline bool ApplyBareHandRace(std::array<wii_remote::HandInputs, 2>& hands, const std::array<bool, 2>& bare_held,
const std::array<bool, 2>& item_pinch) noexcept {
if (hand_driven[1]) {
hands[1].primary = false;
}
if (bare_held[0] || bare_held[1]) {
hands[1].primary = true;
if (!bare_held[0] && !bare_held[1]) {
return false;
}
hands[1].primary = true;
if (item_pinch[0] || item_pinch[1]) {
hands[0].trigger = 1.0f;
}
return true;
}
// One bare hand for the flick detector: its palm's height in the seated frame.
+2 -2
View File
@@ -232,16 +232,16 @@ private:
hand_tracking::HandJointFrame m_joint_frame{};
std::array<hand_tracking::Source, kHands> m_logged_sources{hand_tracking::Source::None,
hand_tracking::Source::None};
XrTime m_sources_logged_at = 0;
// Per frame, from the actions: a controller is in the hand (its squeeze is
// bound), and the hand drives simple_controller (Android only).
std::array<bool, kHands> m_squeeze_active{};
std::array<bool, kHands> m_hand_driven{};
std::array<bool, kHands> m_pinch{};
// Bare-hand driving: each hand's bare latch (camera joints, last grasp) and
// item pinch gate, and the game's pointer switch as last logged.
// item pinch gate.
std::array<hand_tracking::BareLatch, kHands> m_bare_latch{};
std::array<hand_tracking::PinchGate, kHands> m_pinch_gate{};
int m_logged_game_pointer = -2;
// A flick of the bare hands plays one shake on the remote's accelerometer
// from this input time (0 when none is playing).
hand_tracking::FlickDetector m_flick;
-8
View File
@@ -56,18 +56,10 @@ bool OpenXRReadWiiRemote(OpenXRWiiRemoteSample& sample) noexcept;
// WPADControlMotor for the emulated remote.
void OpenXRSetWiiRemoteRumble(bool active) noexcept;
// Guest side: whether the game has the remote's pointer switched on, as KPAD
// reads it each time the game polls the VR remote (Input::WiiController::
// TogglePointer flips it). Tracked bare hands use it to tell driving from a
// menu inside a race; OpenXRInput logs every change.
void OpenXRPublishGamePointer(bool enabled) noexcept;
// XR side.
void OpenXRPublishWiiRemote(uint32_t sdl_joystick_id, const OpenXRWiiRemoteSample& sample) noexcept;
void OpenXRWithdrawWiiRemote() noexcept;
bool OpenXRWiiRemoteRumbleRequested() noexcept;
// The game's pointer switch: 1 on, 0 off, -1 not known (no remote polled yet).
int OpenXRGamePointerState() noexcept;
// The geometry and signal conditioning behind a sample, kept free of OpenXR
// types so it can be checked headlessly (tests/vr_wii_remote_tests.cpp).