mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 02:00:14 +02:00
Add the cockpit seat and hand steering to the Quest launcher
The Quest launcher's Settings > VR gains a Seat choice (cockpit or custom, first_person_seat) and a Hand steering switch (hand_steering, off by default like the runtime), which is only enabled in the first-person cockpit because the wheel belongs to that seat. About credits heurazy for the turning steering wheel and hand steering. The runtime side was already shared with the Quest build. OPENXR.md records what one Quest 3 race showed: the kart's own wheel animated (228 draws a frame) with the race camera's view matching the scene's exactly, but the driver's eye was never calibrated and the fallback put the wheel centre about 13 cm above eye level. The Quest declares no hand-tracking permission, so hands are the procedural gloves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7c6a6da3d5
commit
8b01b47253
4 files changed
+38
-6
No files matched your search
@@ -417,7 +417,8 @@ copied array, those that bound one outside the window it was set for, the matche
|
|||||||
closest position matrix was from the expected one; the first such line with a bound draw also prints
|
closest position matrix was from the expected one; the first such line with a bound draw also prints
|
||||||
both matrices.
|
both matrices.
|
||||||
|
|
||||||
**Hand steering.** `hand_steering = true` (off by default; also in WheelWizard's OpenXR VR settings)
|
**Hand steering.** `hand_steering = true` (off by default; also in WheelWizard's OpenXR VR settings
|
||||||
|
and the Quest launcher's Settings > VR, beside the seat)
|
||||||
lets you take hold of the wheel or handlebar with the tracked controllers. Squeeze a grip near it:
|
lets you take hold of the wheel or handlebar with the tracked controllers. Squeeze a grip near it:
|
||||||
past 55 % squeeze, within `wheel_grab_distance` metres of its plane (default 0.35) and near the rim,
|
past 55 % squeeze, within `wheel_grab_distance` metres of its plane (default 0.35) and near the rim,
|
||||||
or near a bar end, scaled by `wheel_grab_assist`. Once taken, only letting go of the grip releases
|
or near a bar end, scaled by `wheel_grab_assist`. Once taken, only letting go of the grip releases
|
||||||
@@ -441,7 +442,8 @@ aside while it drives.
|
|||||||
|
|
||||||
**Hands and the separate wheel.** Hands are drawn while hand steering is on: the runtime's own hand
|
**Hands and the separate wheel.** Hands are drawn while hand steering is on: the runtime's own hand
|
||||||
mesh where it offers one (`XR_EXT_hand_tracking` and `XR_FB_hand_tracking_mesh`, requested only when
|
mesh where it offers one (`XR_EXT_hand_tracking` and `XR_FB_hand_tracking_mesh`, requested only when
|
||||||
hand steering is on at launch), otherwise procedural gloves that curl with the squeeze. They and the
|
hand steering is on at launch), otherwise procedural gloves that curl with the squeeze. The Quest
|
||||||
|
build declares no hand-tracking permission, so it always draws the gloves. They and the
|
||||||
separate VR wheel or handlebar travel with the stereo packet in metres in the seated frame, and each
|
separate VR wheel or handlebar travel with the stereo packet in metres in the seated frame, and each
|
||||||
eye draws them inside the scene's pass just before the first 2D-layer draw, depth-tested with the
|
eye draws them inside the scene's pass just before the first 2D-layer draw, depth-tested with the
|
||||||
world's own depth mapping, so the kart and the track hide them and the HUD cannot
|
world's own depth mapping, so the kart and the track hide them and the HUD cannot
|
||||||
@@ -764,9 +766,11 @@ ends, including mid-frame flushes, so live setting changes cannot invalidate pen
|
|||||||
Lifecycle events and performance (about 43 game FPS) are still open. Apple visionOS packaging
|
Lifecycle events and performance (about 43 game FPS) are still open. Apple visionOS packaging
|
||||||
is not implemented.
|
is not implemented.
|
||||||
- Scene-specific comfort options, culling fixes and replay/spectator classification are future work.
|
- Scene-specific comfort options, culling fixes and replay/spectator classification are future work.
|
||||||
- The cockpit seat, the turning wheel and hand steering have not yet been validated in a headset on
|
- The cockpit has only been seen in one kart race on a Quest 3 (2026-09-22): the race camera's view
|
||||||
this build: the native wheel's match against the race camera's view, bikes and Quacker, and the
|
matched the scene's exactly and the kart's own wheel animated (228 draws a frame), but the driver's
|
||||||
Quest. Hand steering needs analog grips (Touch); the simple controller profile cannot grab.
|
eye was never calibrated, and the fallback placed the wheel centre about 13 cm above eye level.
|
||||||
|
Bikes and Quacker, the PC, and hand steering itself are unvalidated. Hand steering needs analog
|
||||||
|
grips (Touch); the simple controller profile cannot grab.
|
||||||
- The headset settings panel has no laser beam, only the cursor on the panel itself, and text fields
|
- The headset settings panel has no laser beam, only the cursor on the panel itself, and text fields
|
||||||
cannot be typed into without a keyboard.
|
cannot be typed into without a keyboard.
|
||||||
- The desktop window remains available as a mirror/fallback.
|
- The desktop window remains available as a mirror/fallback.
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ class SettingsPage(
|
|||||||
|
|
||||||
private fun buildVr() {
|
private fun buildVr() {
|
||||||
val firstPerson = { c: TomlConfig -> c.bool("vr", "first_person") ?: false }
|
val firstPerson = { c: TomlConfig -> c.bool("vr", "first_person") ?: false }
|
||||||
|
// The steering wheel and hand steering belong to the cockpit seat.
|
||||||
|
val cockpit = { c: TomlConfig -> firstPerson(c) && stringIndex(c, "vr", "first_person_seat", SEATS) == 0 }
|
||||||
section(R.string.section_vr_camera) {
|
section(R.string.section_vr_camera) {
|
||||||
choice(
|
choice(
|
||||||
R.string.vr_camera, R.string.vr_camera_helper,
|
R.string.vr_camera, R.string.vr_camera_helper,
|
||||||
@@ -151,6 +153,20 @@ class SettingsPage(
|
|||||||
},
|
},
|
||||||
enabledIf = firstPerson,
|
enabledIf = firstPerson,
|
||||||
)
|
)
|
||||||
|
choice(
|
||||||
|
R.string.vr_seat, R.string.vr_seat_helper,
|
||||||
|
listOf(R.string.vr_seat_cockpit, R.string.vr_seat_custom),
|
||||||
|
read = { stringIndex(it, "vr", "first_person_seat", SEATS) },
|
||||||
|
write = { c, index -> c.setString("vr", "first_person_seat", SEATS[index]) },
|
||||||
|
enabledIf = firstPerson,
|
||||||
|
)
|
||||||
|
// heurazy's grab-and-turn wheel: runtime_config.h's kVrHandSteeringDefault is off.
|
||||||
|
toggle(
|
||||||
|
R.string.vr_hand_steering, R.string.vr_hand_steering_helper,
|
||||||
|
read = { it.bool("vr", "hand_steering") ?: false },
|
||||||
|
write = { c, value -> c.setBool("vr", "hand_steering", value) },
|
||||||
|
enabledIf = cockpit,
|
||||||
|
)
|
||||||
slider(
|
slider(
|
||||||
R.string.vr_lean_back, R.string.vr_lean_back_helper, -45.0, 45.0, 1.0,
|
R.string.vr_lean_back, R.string.vr_lean_back_helper, -45.0, 45.0, 1.0,
|
||||||
read = { number(it, "vr", "lean_back_degrees", -45.0, 45.0, 0.0) },
|
read = { number(it, "vr", "lean_back_degrees", -45.0, 45.0, 0.0) },
|
||||||
@@ -366,6 +382,7 @@ class SettingsPage(
|
|||||||
}
|
}
|
||||||
section(R.string.section_about_credits) {
|
section(R.string.section_about_credits) {
|
||||||
info(R.string.about_credit_title_vr, activity.getString(R.string.about_credit_vr), stacked = true)
|
info(R.string.about_credit_title_vr, activity.getString(R.string.about_credit_vr), stacked = true)
|
||||||
|
info(R.string.about_credit_title_hand_steering, activity.getString(R.string.about_credit_hand_steering), stacked = true)
|
||||||
info(R.string.about_credit_title_wiicompiled, activity.getString(R.string.about_credit_wiicompiled), stacked = true)
|
info(R.string.about_credit_title_wiicompiled, activity.getString(R.string.about_credit_wiicompiled), stacked = true)
|
||||||
info(R.string.about_credit_title_retro_rewind, activity.getString(R.string.about_credit_retro_rewind), stacked = true)
|
info(R.string.about_credit_title_retro_rewind, activity.getString(R.string.about_credit_retro_rewind), stacked = true)
|
||||||
info(R.string.about_credit_title_wheel_wizard, activity.getString(R.string.about_credit_wheel_wizard), stacked = true)
|
info(R.string.about_credit_title_wheel_wizard, activity.getString(R.string.about_credit_wheel_wizard), stacked = true)
|
||||||
@@ -686,6 +703,8 @@ class SettingsPage(
|
|||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val ROTATIONS = listOf("yaw", "yaw_pitch", "full")
|
val ROTATIONS = listOf("yaw", "yaw_pitch", "full")
|
||||||
|
// The runtime's default ("cockpit") first.
|
||||||
|
val SEATS = listOf("cockpit", "custom")
|
||||||
// The runtime's default ("boost") first: an absent key reads as index 0.
|
// The runtime's default ("boost") first: an absent key reads as index 0.
|
||||||
val PERFORMANCE_LEVELS = listOf("boost", "sustained_high", "sustained_low", "power_savings", "default")
|
val PERFORMANCE_LEVELS = listOf("boost", "sustained_high", "sustained_low", "power_savings", "default")
|
||||||
val CONTROLLER_MODES = listOf("wii_remote", "gamepad")
|
val CONTROLLER_MODES = listOf("wii_remote", "gamepad")
|
||||||
|
|||||||
@@ -141,6 +141,7 @@
|
|||||||
<string name="about_app_name">WiiCompiled OpenXR VR</string>
|
<string name="about_app_name">WiiCompiled OpenXR VR</string>
|
||||||
<string name="about_app_summary">Mario Kart Wii recompiled to native code, with an OpenXR renderer, running on this headset. No game code and no game data come with it: each game is built from the disc you own.</string>
|
<string name="about_app_summary">Mario Kart Wii recompiled to native code, with an OpenXR renderer, running on this headset. No game code and no game data come with it: each game is built from the disc you own.</string>
|
||||||
<string name="about_credit_vr">Meta Quest port and the OpenXR VR renderer by iChris4.</string>
|
<string name="about_credit_vr">Meta Quest port and the OpenXR VR renderer by iChris4.</string>
|
||||||
|
<string name="about_credit_hand_steering">The cockpit\'s turning steering wheel and hand steering by heurazy, from mario-kart-wii-VR-port (GPL v3).</string>
|
||||||
<string name="about_credit_wiicompiled">WiiCompiled, the static recompilation this is built on, by patchzyy and the static recompilation community.</string>
|
<string name="about_credit_wiicompiled">WiiCompiled, the static recompilation this is built on, by patchzyy and the static recompilation community.</string>
|
||||||
<string name="about_credit_retro_rewind">Retro Rewind by ZPL and team, the mod distribution this app can download and play.</string>
|
<string name="about_credit_retro_rewind">Retro Rewind by ZPL and team, the mod distribution this app can download and play.</string>
|
||||||
<string name="about_credit_wheel_wizard">Wheel Wizard by Patchzy and WantToBeeMe, the PC launcher this panel is modelled on.</string>
|
<string name="about_credit_wheel_wizard">Wheel Wizard by Patchzy and WantToBeeMe, the PC launcher this panel is modelled on.</string>
|
||||||
@@ -153,6 +154,7 @@
|
|||||||
<string name="about_licence_text">GNU General Public License v3. Not affiliated with, endorsed by, or associated with Nintendo. Mario Kart Wii is a trademark of Nintendo.</string>
|
<string name="about_licence_text">GNU General Public License v3. Not affiliated with, endorsed by, or associated with Nintendo. Mario Kart Wii is a trademark of Nintendo.</string>
|
||||||
<string name="about_kit">Game kit</string>
|
<string name="about_kit">Game kit</string>
|
||||||
<string name="about_credit_title_vr">Meta Quest and VR</string>
|
<string name="about_credit_title_vr">Meta Quest and VR</string>
|
||||||
|
<string name="about_credit_title_hand_steering">Steering wheel and hand steering</string>
|
||||||
<string name="about_credit_title_wiicompiled">WiiCompiled</string>
|
<string name="about_credit_title_wiicompiled">WiiCompiled</string>
|
||||||
<string name="about_credit_title_retro_rewind">Retro Rewind</string>
|
<string name="about_credit_title_retro_rewind">Retro Rewind</string>
|
||||||
<string name="about_credit_title_wheel_wizard">Wheel Wizard</string>
|
<string name="about_credit_title_wheel_wizard">Wheel Wizard</string>
|
||||||
@@ -184,6 +186,12 @@
|
|||||||
<string name="vr_hide_nothing">Nothing</string>
|
<string name="vr_hide_nothing">Nothing</string>
|
||||||
<string name="vr_hide_driver">Driver</string>
|
<string name="vr_hide_driver">Driver</string>
|
||||||
<string name="vr_hide_driver_and_kart">Driver and kart</string>
|
<string name="vr_hide_driver_and_kart">Driver and kart</string>
|
||||||
|
<string name="vr_seat">Seat</string>
|
||||||
|
<string name="vr_seat_helper">The cockpit puts you at the driver\'s eyes, life-size, with the steering wheel or handlebar turning within reach. Custom uses the head offsets from the in-headset settings.</string>
|
||||||
|
<string name="vr_seat_cockpit">Cockpit</string>
|
||||||
|
<string name="vr_seat_custom">Custom</string>
|
||||||
|
<string name="vr_hand_steering">Hand steering</string>
|
||||||
|
<string name="vr_hand_steering_helper">In the cockpit, squeeze a grip near the steering wheel or handlebar to grab it, and turn it to steer. Releasing both grips gives steering back to the stick. Hand steering by heurazy.</string>
|
||||||
<string name="vr_lean_back">Lean back angle</string>
|
<string name="vr_lean_back">Lean back angle</string>
|
||||||
<string name="vr_lean_back_helper">Tilts the race view back for playing reclined. 0 applies no tilt.</string>
|
<string name="vr_lean_back_helper">Tilts the race view back for playing reclined. 0 applies no tilt.</string>
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -183,7 +183,8 @@ a 2D Horizon OS panel modelled on the PC launcher, WheelWizard VR, and using its
|
|||||||
palette. **Home** has the Play button and reports a missing or incomplete `DATA`
|
palette. **Home** has the Play button and reports a missing or incomplete `DATA`
|
||||||
(the check is the runtime's own `IsDvdDataRoot`: `files/` and `sys/fst.bin`).
|
(the check is the runtime's own `IsDvdDataRoot`: `files/` and `sys/fst.bin`).
|
||||||
**Settings** edits `Config.toml` in tabs: VR (camera, rotation, driver hiding,
|
**Settings** edits `Config.toml` in tabs: VR (camera, rotation, driver hiding,
|
||||||
lean back, render scale, VR interpolation, virtual screen size and distance),
|
seat, hand steering, lean back, render scale, VR interpolation, virtual screen
|
||||||
|
size and distance),
|
||||||
Graphics (resolution, widescreen, bloom, shader stutter), Controls (controller
|
Graphics (resolution, widescreen, bloom, shader stutter), Controls (controller
|
||||||
mode, vibration, the Wii Remote mapping), Audio, and About (paths, OpenXR
|
mode, vibration, the Wii Remote mapping), Audio, and About (paths, OpenXR
|
||||||
logging). The launch-time geometry (`render_scale`, `hud_distance_meters`,
|
logging). The launch-time geometry (`render_scale`, `hud_distance_meters`,
|
||||||
|
|||||||
Reference in new issue
Block a user