mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 06:00:25 +02:00
Toggle the first-person camera with a right thumbstick click
Clicking the right thumbstick flips first person exactly as the F10 checkbox does, and saves it the same way. It works on the VR controllers in either presentation (with a short tick on the right controller) and on any other gamepad while VR is running. It never reached the game: SDL's stick click only lands in Aurora's extended buttons. A click counts on release, and only if the left thumbstick stayed up and the headset settings panel stayed closed throughout, so the two-thumbstick panel chord in gamepad mode never toggles the camera. A gamepad whose right stick click is bound to a GameCube control on its port, as a button or in an input expression, keeps it for the game. The XR side only posts a request; the toggle itself runs on the game thread with the checkbox. [vr] first_person_toggle_click (default true) and a checkbox under the camera toggle turn the click off. mkw_vr_camera_toggle_tests covers the click rule. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c11a7c9a61
commit
dd7f046214
11 files changed
+245
-4
No files matched your search
@@ -63,6 +63,7 @@ struct RuntimeUserConfig {
|
||||
std::optional<std::string> vrControllerMode;
|
||||
std::optional<uint32_t> vrFrameInterpolationFps;
|
||||
std::optional<bool> vrFirstPerson;
|
||||
std::optional<bool> vrFirstPersonToggleClick;
|
||||
std::optional<float> vrFirstPersonUnitsPerMeter;
|
||||
std::optional<float> vrFirstPersonHeadUpMeters;
|
||||
std::optional<float> vrFirstPersonHeadForwardMeters;
|
||||
@@ -502,6 +503,9 @@ inline void EnsureConfigFile() {
|
||||
"# the kart, with the horizon kept level. Changeable live from the\n"
|
||||
"# F10 menu, and only during a single-screen race.\n"
|
||||
"first_person = false\n"
|
||||
"# Clicking the right thumbstick, on the VR controllers or on any\n"
|
||||
"# gamepad while VR runs, toggles first_person as the F10 checkbox does.\n"
|
||||
"first_person_toggle_click = true\n"
|
||||
"# Where the head sits: \"cockpit\" puts it at the driver's own eyes,\n"
|
||||
"# behind the steering wheel, at a life-size scale that allows for\n"
|
||||
"# the character's height, so the wheel is within reach.\n"
|
||||
@@ -742,6 +746,7 @@ inline RuntimeUserConfig ParseConfigDocument(const toml::value& document) {
|
||||
config.vrStopAtDisplayCopy = FindConfigValue<bool>(document, "vr", "stop_at_display_copy");
|
||||
config.vrSkipCopyClears = FindConfigValue<bool>(document, "vr", "skip_copy_clears");
|
||||
config.vrFirstPerson = FindConfigValue<bool>(document, "vr", "first_person");
|
||||
config.vrFirstPersonToggleClick = FindConfigValue<bool>(document, "vr", "first_person_toggle_click");
|
||||
if (auto value = FindConfigFloat(document, "vr", "first_person_units_per_meter");
|
||||
value && *value >= 1.0f && *value <= 10000.0f) {
|
||||
config.vrFirstPersonUnitsPerMeter = *value;
|
||||
@@ -1066,6 +1071,11 @@ inline bool SetVrFirstPerson(bool value) {
|
||||
return WriteSetting("vr", "first_person", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrFirstPersonToggleClick(bool value) {
|
||||
Mutable().vrFirstPersonToggleClick = value;
|
||||
return WriteSetting("vr", "first_person_toggle_click", value ? "true" : "false");
|
||||
}
|
||||
|
||||
inline bool SetVrFirstPersonUnitsPerMeter(float value) {
|
||||
value = std::clamp(value, 1.0f, 10000.0f);
|
||||
Mutable().vrFirstPersonUnitsPerMeter = value;
|
||||
@@ -1510,6 +1520,10 @@ inline bool VrFirstPerson(bool fallback = false) {
|
||||
return Get().vrFirstPerson.value_or(fallback);
|
||||
}
|
||||
|
||||
inline bool VrFirstPersonToggleClick(bool fallback = true) {
|
||||
return Get().vrFirstPersonToggleClick.value_or(fallback);
|
||||
}
|
||||
|
||||
inline float VrFirstPersonUnitsPerMeter(float fallback = kVrFirstPersonUnitsPerMeterDefault) {
|
||||
return std::clamp(Get().vrFirstPersonUnitsPerMeter.value_or(fallback), 1.0f, 10000.0f);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,10 @@ void AdvancePresentedFrame() noexcept;
|
||||
// converted with the world scale currently in effect, so switching the
|
||||
// first-person camera on or off has to repeat it.
|
||||
void RefreshVrHudVirtualScreen() noexcept;
|
||||
// Flips the first-person camera exactly as its F10 checkbox does, on the game
|
||||
// thread at the next frame. Callable from any thread (the VR controllers'
|
||||
// right-thumbstick click).
|
||||
void RequestFirstPersonToggle() noexcept;
|
||||
// Put host controllers back to a neutral state before the process ends.
|
||||
void ReleaseControllers() noexcept;
|
||||
} // namespace settings_overlay
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
// The right thumbstick click that toggles the first-person camera, on the VR
|
||||
// controllers and on any gamepad while VR runs (F10 > VR >
|
||||
// first_person_toggle_click). Kept free of OpenXR and SDL so it is tested
|
||||
// headlessly (tests/vr_camera_toggle_tests.cpp).
|
||||
|
||||
namespace mkw::vr {
|
||||
|
||||
// One clean click of a button: it fires on release, and only if its partner
|
||||
// (the other thumbstick, which with it opens the headset settings panel on a
|
||||
// gamepad) stayed up and nothing owned the controllers at any point during the
|
||||
// press. Firing on release is what lets a two-stick chord pass untouched.
|
||||
class ClickToggle {
|
||||
public:
|
||||
bool Update(bool held, bool partner_held, bool blocked) noexcept {
|
||||
if (held) {
|
||||
if (!held_) {
|
||||
held_ = true;
|
||||
spoiled_ = partner_held || blocked;
|
||||
} else if (partner_held || blocked) {
|
||||
spoiled_ = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const bool fire = held_ && !spoiled_ && !blocked;
|
||||
held_ = false;
|
||||
spoiled_ = false;
|
||||
return fire;
|
||||
}
|
||||
void Reset() noexcept {
|
||||
held_ = false;
|
||||
spoiled_ = false;
|
||||
}
|
||||
bool Held() const noexcept { return held_; }
|
||||
|
||||
private:
|
||||
bool held_ = false;
|
||||
bool spoiled_ = false;
|
||||
};
|
||||
|
||||
} // namespace mkw::vr
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#if defined(MKW_ENABLE_OPENXR)
|
||||
|
||||
#include "vr/camera_toggle.h"
|
||||
#include "vr/openxr_driving.h"
|
||||
#include "vr/openxr_runtime.h"
|
||||
#include "vr/openxr_settings_panel.h"
|
||||
@@ -64,6 +65,9 @@ struct OpenXRPointerScreen {
|
||||
// the left stick's X axis in both presentations and that grip no longer reaches
|
||||
// the game (C on the Nunchuk, a shoulder on the gamepad).
|
||||
//
|
||||
// A right-thumbstick click on its own toggles the first-person camera, as its
|
||||
// F10 checkbox does (first_person_toggle_click).
|
||||
//
|
||||
// Left Y (both thumbsticks clicked together as a gamepad) opens the in-headset
|
||||
// settings panel (openxr_settings_panel.h). While it is open, and until every
|
||||
// button has been released after it closes, the game sees idle controllers: the
|
||||
@@ -166,6 +170,7 @@ private:
|
||||
bool m_haptics_active[kHands]{};
|
||||
uint32_t m_joystick_id = 0; // SDL_JoystickID; 0 when detached
|
||||
void* m_joystick = nullptr; // SDL_Joystick*
|
||||
ClickToggle m_first_person_click;
|
||||
SteeringWheel m_wheel;
|
||||
WheelReferenceLatch m_wheel_reference;
|
||||
driving::WheelVisual m_wheel_visual;
|
||||
|
||||
@@ -48,6 +48,9 @@ OpenXRControllerMode OpenXRGetControllerMode() noexcept;
|
||||
// Guest side. True when `sdl_joystick_id` is the OpenXR virtual gamepad and the
|
||||
// controllers are currently presented as a Wii Remote.
|
||||
bool OpenXRWiiRemoteOwnsGamepad(uint32_t sdl_joystick_id) noexcept;
|
||||
// True when `sdl_joystick_id` is the VR controllers' virtual gamepad, in either
|
||||
// presentation.
|
||||
bool OpenXRIsControllerGamepad(uint32_t sdl_joystick_id) noexcept;
|
||||
// Latest published sample; false before the first one or after withdrawal.
|
||||
bool OpenXRReadWiiRemote(OpenXRWiiRemoteSample& sample) noexcept;
|
||||
// WPADControlMotor for the emulated remote.
|
||||
|
||||
Reference in new issue
Block a user