mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 10:00:27 +02:00
SteamVR on the Steam Frame ran the game at half the 120 Hz display rate, since render-first pacing submits only when a game frame is sealed, and filled every other refresh itself even with Motion Smoothing off, which doubled the HUD and the menu screen while the head turned. With the new [vr] repeat_frames (default on for the Frame, off elsewhere, live), the pacing thread waits a millisecond for the eyes and otherwise spends the refresh on a keep-alive cycle that resubmits the retained layer with its rendered poses, paced by xrWaitFrame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019HBRGKTE1GnN2ah8gcZKr3
139 lines
7.3 KiB
C++
139 lines
7.3 KiB
C++
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
#include "runtime_config.h"
|
|
#include <cstdlib>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <string_view>
|
|
|
|
static void Require(bool condition) {
|
|
if (!condition) std::abort();
|
|
}
|
|
|
|
static RuntimeUserConfig Parse(const std::string& text) {
|
|
std::istringstream input(text);
|
|
return RuntimeConfigFile::ParseConfig(input);
|
|
}
|
|
|
|
int main() {
|
|
for (std::string_view hand : {"left", "right", "off"}) {
|
|
Require(Parse("[vr]\ncockpit_item_hand = \"" + std::string(hand) + "\"\n")
|
|
.vrCockpitItemHand == std::string(hand));
|
|
}
|
|
Require(std::string_view(RuntimeConfigFile::kVrCockpitItemHandDefault) == "left");
|
|
Require(!Parse("[vr]\n").vrCockpitItemHand.has_value());
|
|
Require(!Parse("[vr]\ncockpit_item_hand = 1\n").vrCockpitItemHand.has_value());
|
|
Require(RuntimeConfigFile::kVrCockpitItemThrowDefault);
|
|
Require(Parse("[vr]\ncockpit_item_throw = false\n").vrCockpitItemThrow == false);
|
|
Require(Parse("[vr]\ncockpit_item_throw = true\n").vrCockpitItemThrow == true);
|
|
Require(!Parse("[vr]\n").vrCockpitItemThrow.has_value());
|
|
// [vr] placeholder_steering_wheel: the separate VR wheel or handlebar is opt-in.
|
|
Require(!RuntimeConfigFile::kVrPlaceholderSteeringWheelDefault);
|
|
Require(Parse("[vr]\nplaceholder_steering_wheel = true\n").vrPlaceholderSteeringWheel == true);
|
|
Require(Parse("[vr]\nplaceholder_steering_wheel = false\n").vrPlaceholderSteeringWheel == false);
|
|
Require(!Parse("[vr]\n").vrPlaceholderSteeringWheel.has_value());
|
|
// [vr] foveation: the Quest's foveated rendering level, index-matched to
|
|
// aurora_set_stereo_foveation.
|
|
for (std::string_view level : RuntimeConfigFile::kVrFoveationLevels) {
|
|
Require(Parse("[vr]\nfoveation = \"" + std::string(level) + "\"\n").vrFoveation == std::string(level));
|
|
}
|
|
Require(!Parse("[vr]\nfoveation = \"ultra\"\n").vrFoveation.has_value());
|
|
Require(!Parse("[vr]\nfoveation = 2\n").vrFoveation.has_value());
|
|
Require(!Parse("[vr]\n").vrFoveation.has_value());
|
|
#if defined(MKW_VR_STANDALONE)
|
|
Require(std::string_view(RuntimeConfigFile::kVrFoveationDefault) == "medium");
|
|
#else
|
|
Require(std::string_view(RuntimeConfigFile::kVrFoveationDefault) == "off");
|
|
#endif
|
|
Require(RuntimeConfigFile::VrFoveationLevelIndex("off") == 0);
|
|
Require(RuntimeConfigFile::VrFoveationLevelIndex("low") == 1);
|
|
Require(RuntimeConfigFile::VrFoveationLevelIndex("medium") == 2);
|
|
Require(RuntimeConfigFile::VrFoveationLevelIndex("high") == 3);
|
|
Require(RuntimeConfigFile::VrFoveationLevelIndex("ultra") == 0);
|
|
|
|
// [vr] refresh_rate: Hz asked of the runtime, 0 leaving its own. The Steam Frame
|
|
// starts at 120, twice the game's 60.
|
|
Require(Parse("[vr]\nrefresh_rate = 120\n").vrRefreshRate == 120u);
|
|
Require(Parse("[vr]\nrefresh_rate = 0\n").vrRefreshRate == 0u);
|
|
Require(Parse("[vr]\nrefresh_rate = 144\n").vrRefreshRate == 144u);
|
|
Require(!Parse("[vr]\nrefresh_rate = 30\n").vrRefreshRate.has_value());
|
|
Require(!Parse("[vr]\nrefresh_rate = 500\n").vrRefreshRate.has_value());
|
|
Require(!Parse("[vr]\nrefresh_rate = -1\n").vrRefreshRate.has_value());
|
|
Require(!Parse("[vr]\nrefresh_rate = \"120\"\n").vrRefreshRate.has_value());
|
|
Require(!Parse("[vr]\n").vrRefreshRate.has_value());
|
|
#if defined(MKW_HEADSET_STEAM_FRAME)
|
|
Require(RuntimeConfigFile::kVrRefreshRateDefault == 120u);
|
|
Require(std::string_view(MKW_VR_REFRESH_RATE_DEFAULT_TEXT) == "120");
|
|
#else
|
|
Require(RuntimeConfigFile::kVrRefreshRateDefault == 0u);
|
|
Require(std::string_view(MKW_VR_REFRESH_RATE_DEFAULT_TEXT) == "0");
|
|
#endif
|
|
|
|
// [vr] eye_tracked_foveation: the foveation centre follows the gaze, on the Steam Frame by default.
|
|
Require(Parse("[vr]\neye_tracked_foveation = true\n").vrEyeTrackedFoveation == true);
|
|
Require(Parse("[vr]\neye_tracked_foveation = false\n").vrEyeTrackedFoveation == false);
|
|
Require(!Parse("[vr]\neye_tracked_foveation = 1\n").vrEyeTrackedFoveation.has_value());
|
|
Require(!Parse("[vr]\n").vrEyeTrackedFoveation.has_value());
|
|
#if defined(MKW_HEADSET_STEAM_FRAME)
|
|
Require(RuntimeConfigFile::kVrEyeTrackedFoveationDefault);
|
|
#else
|
|
Require(!RuntimeConfigFile::kVrEyeTrackedFoveationDefault);
|
|
#endif
|
|
|
|
// [vr] repeat_frames: the retained layer fills the refreshes the game has no frame for.
|
|
Require(Parse("[vr]\nrepeat_frames = true\n").vrRepeatFrames == true);
|
|
Require(Parse("[vr]\nrepeat_frames = false\n").vrRepeatFrames == false);
|
|
Require(!Parse("[vr]\nrepeat_frames = 1\n").vrRepeatFrames.has_value());
|
|
Require(!Parse("[vr]\n").vrRepeatFrames.has_value());
|
|
#if defined(MKW_HEADSET_STEAM_FRAME)
|
|
Require(RuntimeConfigFile::kVrRepeatFramesDefault);
|
|
Require(std::string_view(MKW_VR_REPEAT_FRAMES_DEFAULT_TOML) == "true");
|
|
#else
|
|
Require(!RuntimeConfigFile::kVrRepeatFramesDefault);
|
|
Require(std::string_view(MKW_VR_REPEAT_FRAMES_DEFAULT_TOML) == "false");
|
|
#endif
|
|
|
|
// [vr] passthrough: Horizon OS's room view, which the Steam Frame build does not offer.
|
|
Require(Parse("[vr]\npassthrough = false\n").vrPassthrough == false);
|
|
Require(!Parse("[vr]\n").vrPassthrough.has_value());
|
|
#if defined(MKW_HEADSET_STEAM_FRAME)
|
|
Require(!RuntimeConfigFile::kVrPassthroughDefault);
|
|
#else
|
|
Require(RuntimeConfigFile::kVrPassthroughDefault);
|
|
#endif
|
|
|
|
// [vr] hand_tracking: the cockpit hands follow the headset's hand tracking.
|
|
Require(Parse("[vr]\nhand_tracking = true\n").vrHandTracking == true);
|
|
Require(Parse("[vr]\nhand_tracking = false\n").vrHandTracking == false);
|
|
Require(!Parse("[vr]\n").vrHandTracking.has_value());
|
|
Require(!Parse("[vr]\nhand_tracking = 1\n").vrHandTracking.has_value());
|
|
Require(!RuntimeConfigFile::kVrHandTrackingDefault);
|
|
|
|
// [vr] object_culling: false draws what the game camera culls. The PC
|
|
// defaults to that; the Quest keeps the game's culling.
|
|
Require(Parse("[vr]\nobject_culling = true\n").vrObjectCulling == true);
|
|
Require(Parse("[vr]\nobject_culling = false\n").vrObjectCulling == false);
|
|
Require(!Parse("[vr]\n").vrObjectCulling.has_value());
|
|
Require(!Parse("[vr]\nobject_culling = 0\n").vrObjectCulling.has_value());
|
|
#if defined(MKW_VR_STANDALONE)
|
|
Require(RuntimeConfigFile::kVrObjectCullingDefault);
|
|
Require(std::string_view(MKW_VR_OBJECT_CULLING_DEFAULT_TOML) == "true");
|
|
#else
|
|
Require(!RuntimeConfigFile::kVrObjectCullingDefault);
|
|
Require(std::string_view(MKW_VR_OBJECT_CULLING_DEFAULT_TOML) == "false");
|
|
#endif
|
|
|
|
// [vr] immersive_window and flat_screen: one race view in two keys, Flat
|
|
// Screen mode winning, so a file that predates the window reads as before.
|
|
using RuntimeConfigFile::VrRaceView;
|
|
using RuntimeConfigFile::VrRaceViewOf;
|
|
Require(Parse("[vr]\nimmersive_window = true\n").vrImmersiveWindow == true);
|
|
Require(!Parse("[vr]\n").vrImmersiveWindow.has_value());
|
|
Require(VrRaceViewOf(Parse("[vr]\n")) == VrRaceView::Immersive);
|
|
Require(VrRaceViewOf(Parse("[vr]\nflat_screen = false\n")) == VrRaceView::Immersive);
|
|
Require(VrRaceViewOf(Parse("[vr]\nflat_screen = true\n")) == VrRaceView::FlatScreen);
|
|
Require(VrRaceViewOf(Parse("[vr]\nimmersive_window = true\n")) == VrRaceView::ImmersiveWindow);
|
|
Require(VrRaceViewOf(Parse("[vr]\nflat_screen = true\nimmersive_window = true\n")) == VrRaceView::FlatScreen);
|
|
Require(VrRaceViewOf(Parse("[vr]\nflat_screen = false\nimmersive_window = false\n")) == VrRaceView::Immersive);
|
|
return 0;
|
|
}
|