diff --git a/src/main.cpp b/src/main.cpp index 65eb57a..cbc85c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ constexpr auto kNoSound = "-nosound"; constexpr auto kNoManifest = "-nomanifest"; constexpr auto kInstallManifest = "-installmanifest"; constexpr auto kRemoveManifest = "-removemanifest"; +constexpr auto kEnableBindingsInterface = "-bindingsinterface"; } // namespace argument namespace manifest @@ -357,6 +358,8 @@ int main( int argc, char* argv[] ) argc, argv, argument::kInstallManifest ); const bool removeManifest = argument::CheckCommandLineArgument( argc, argv, argument::kRemoveManifest ); + const bool bindingsInterface = argument::CheckCommandLineArgument( + argc, argv, argument::kEnableBindingsInterface ); // If a command line arg is set, make sure the logs reflect that. LOG_IF( desktopMode, INFO ) << "Desktop mode enabled."; @@ -364,6 +367,15 @@ int main( int argc, char* argv[] ) LOG_IF( noManifest, INFO ) << "vrmanifest disabled."; LOG_IF( installManifest, INFO ) << "Install manifest enabled."; LOG_IF( removeManifest, INFO ) << "Remove manifest enabled."; + LOG_IF( bindingsInterface, INFO ) << "Bindings interface enabled."; + + if ( bindingsInterface ) + { + // This is a temporary solution until Valve fixes overlays not + // showing up in the bindings interface. See function description for + // more info. + openvr_init::openBindingsMenu(); + } // It is important that either install_manifest or remove_manifest are true, // otherwise the handleManifests function will not behave properly. diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index 89addf0..7f34462 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -88,7 +88,7 @@ private: // OpenVR_Init must be declared before any other class that uses OpenVR // function calls since objects are initialized in order of declaration in // the class. - OpenVR_Init m_openVrInit; + openvr_init::OpenVR_Init m_openVrInit; public: // I know it's an ugly hack to make them public to enable external // access, but I am too lazy to implement getters. diff --git a/src/overlaycontroller/openvr_init.cpp b/src/overlaycontroller/openvr_init.cpp index b63ba1a..558d372 100644 --- a/src/overlaycontroller/openvr_init.cpp +++ b/src/overlaycontroller/openvr_init.cpp @@ -2,10 +2,13 @@ #include #include #include "openvr_init.h" +#include +#include "../ivrinput/ivrinput_manifest.h" -OpenVR_Init::OpenVR_Init() +namespace openvr_init +{ +void initializeProperly() { - // Loading the OpenVR Runtime auto initError = vr::VRInitError_None; vr::VR_Init( &initError, vr::VRApplication_Overlay ); if ( initError != vr::VRInitError_None ) @@ -22,6 +25,66 @@ OpenVR_Init::OpenVR_Init() + std::string( vr::VR_GetVRInitErrorAsEnglishDescription( initError ) ) ); } + else + { + LOG( INFO ) << "OpenVR initialized successfully."; + } +} + +/*! +Initializes OpenVR to be in the bindings menu and then exits. +This is needed because all applications initialized with OpenVR that aren't of +type vr::VRApplication_Scene do not show up the in bindings menu. + +This is obviously an ugly hack and should be done away with as soon as Valve +fixes this issue. + +Official Issues for this: +https://github.com/ValveSoftware/openvr/issues/914 +https://github.com/ValveSoftware/openvr/issues/926 +https://github.com/ValveSoftware/openvr/issues/879 + +You can also make it appear by changing the +C:\Program Files (x86)\Steam\config\vrappconfig\*.vrappconfig file for your +project to have a "last_launch_time" of something greater than zero. +From experimentation it seems that there's a cutoff time around 2 weeks before +the current time. Setting it to the day before seems to be a good bet. (In unix +time). +*/ +[[noreturn]] void openBindingsMenu() +{ + // Prefix the logs with this to visibly document that this isn't how things + // are supposed to be. Hopefully someone reads the logs and comes here after + // Valve has fixed it. + constexpr auto logPrefix = "[HACK]::openBindingsMenu "; + + auto initError = vr::VRInitError_None; + LOG( INFO ) << logPrefix << "Initializing application as scene."; + + vr::VR_Init( &initError, vr::VRApplication_Scene ); + + if ( initError != vr::VRInitError_None ) + { + LOG( ERROR ) << logPrefix << "Error initializing application as scene."; + exit( 2 ); + } + else + { + LOG( INFO ) << logPrefix << "Application initialized as scene."; + } + + input::Manifest manifest; + + // SteamVR just needs a good enough time to start up comfortably and for the + // user to get into the bindings menu. + while ( true ) + { + } +} + +OpenVR_Init::OpenVR_Init() +{ + initializeProperly(); // The function call and error message was the same for all version checks. // Specific error messages are unlikely to be necessary since both the type @@ -80,3 +143,4 @@ OpenVR_Init::~OpenVR_Init() { vr::VR_Shutdown(); } +} // namespace openvr_init diff --git a/src/overlaycontroller/openvr_init.h b/src/overlaycontroller/openvr_init.h index bdec289..d150dcd 100644 --- a/src/overlaycontroller/openvr_init.h +++ b/src/overlaycontroller/openvr_init.h @@ -1,5 +1,9 @@ #pragma once +namespace openvr_init +{ +[[noreturn]] void openBindingsMenu(); + /*! Initializes OpenVR and checks validity of interface versions. Shuts down OpenVR when destroyed. @@ -33,3 +37,4 @@ public: // Move assignment const OpenVR_Init operator=( OpenVR_Init&& ) = delete; }; +} // namespace openvr_init