diff --git a/Readme.md b/Readme.md index a3463cb..9fa6cda 100644 --- a/Readme.md +++ b/Readme.md @@ -15,9 +15,11 @@ Adds an overlay to the OpenVR dashboard that allows access to advanced settings * [Features](#features) * [Usage](#usage) * [Windows](#windows) + * [Steam](#steam) * [Installer](#installer) * [Standalone](#standalone) * [Linux](#linux) + * [Steam for Linux](#SteamLinux) * [AppImage](#appimage) * [Arch/Manjaro](#archmanjaro) * [Building from Source](#building-from-source) @@ -37,6 +39,7 @@ Adds an overlay to the OpenVR dashboard that allows access to advanced settings * [Command Line Arguments](#command-line-arguments) * [INI File Options](#ini-file-options) * [Preview builds](#preview-builds) + * [Un-Installing](#un-installing) * [Documentation](#documentation) * [Top Page](#top-page) * [- SteamVR Page](#--steamvr-page) @@ -88,6 +91,12 @@ Do all this without leaving VR: ## Windows +### Steam + +Get it on Steam at [OVR Advanced Settings](https://store.steampowered.com/app/1009850/OVR_Advanced_Settings/) + +**Note:** Please Un-install Other Versions Before Installing Via Steam. + ### Installer Download the newest installer from the [release section](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/releases) and run it. @@ -104,6 +113,12 @@ To upgrade an existing installation first stop SteamVR and delete the old applic ## Linux +### Steam for Linux + +Get it on Steam at [OVR Advanced Settings](https://store.steampowered.com/app/1009850/OVR_Advanced_Settings/) + +**Note:** Please Un-install Other Versions Before Installing Via Steam. + ### AppImage The AppImage can be found in the [release section](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/releases) and should run on most common Linux distributions. @@ -125,7 +140,7 @@ Detailed instructions are available [here](docs/building_for_linux.md). ### Overall Feature Overview Guides -- [Kung's 3.0 New Feature Guide (video/youtube)[https://youtu.be/2ZHdjOfnqOU] +- [Kung's 3.0 New Feature Guide (video/youtube)]( https://youtu.be/2ZHdjOfnqOU ) ### SteamVR Input System (keybinds for app) @@ -206,6 +221,7 @@ Actions That will stay active regardless of the situation. | Add Left Haptic Click | Binary/Button | simulates a "click" with controller haptics. (left hand) | Add Right Haptic Click | Binary/Button | simulates a "click" with controller haptics. (right hand) | Key Press System | Binary/Button | Sends the key press defined in the settings file. Defaults to F9 | +| Exclusive Input Toggle | Binary/Button | Switches between App and OVRAS keybinds, *note:* system Key-Binds remain active all the time ### Haptics. @@ -302,6 +318,21 @@ If you want to try latest and greatest unreleased features, you can download the These version are not stable and this should be considered for advanced users only. +## Un-Installing + +### Windows + +- Automatically + - Run the un-installer, It should be wherever you isntalled OVRAS +- Semi-Manually + - Run AdvancedSettings.exe with the command --force-remove-manifest + - delete install directory + - (optional) delete logs and settings `%appdata%/AdvancedSettings-Team` (`C:\Users\\AppData\Roaming\AdvancedSettings-Team`) +- Manually + - go to steam install/config directory (C:\Program Files (x86)\Steam\config by default) + - edit the appconfig.json to remove the path pointed to Advanced Settings (`C:\\Program Files\\OpenVR-AdvancedSettings\\manifest.vrmanifest` by default) + - delete install folder, settings and log files manually + # Documentation ## Top Page @@ -511,6 +542,7 @@ Allows users to temporarily move and rotate the center of the playspace. This al - **Disable Notification of Newer Version Availability**: This turns off the on start-up check for a new version. (You can refresh this to do a manual check.) - **Force Use SteamVR Chaperone**: This feature is currently experimental, when using third party headsets this will allow you to use SteamVR's chaperone, as if it was a native headset. - **Force Use SteamVR (Disable Oculus API)**: This feature is currently experimental, it should disable Oculus API preventing games with both SteamVR and Oculus API to only run as SteamVR +- ** Exclusive Input Toggle: This feature Enables Exclusive Input Mode, while in this mode you will only send OVRAS keybinds or App keybinds [with the exception of OVRAS system keybinds always working] - **Disable App Vsync:** Allows setting a custom base update rate for Advanced Settings. (Might be useful on HMDs with very high or very low refresh rates). - **Shutdown OVRAS** Shuts-Down Advanced Settings without closing out of VR. diff --git a/build_scripts/compile_version_string.txt b/build_scripts/compile_version_string.txt index db2c4f7..7da5062 100644 --- a/build_scripts/compile_version_string.txt +++ b/build_scripts/compile_version_string.txt @@ -1 +1 @@ -5.2.2-release \ No newline at end of file +5.2.2-dev \ No newline at end of file diff --git a/src/openvr/ivrinput.cpp b/src/openvr/ivrinput.cpp index 1358360..7a42b32 100644 --- a/src/openvr/ivrinput.cpp +++ b/src/openvr/ivrinput.cpp @@ -142,6 +142,7 @@ SteamIVRInput::SteamIVRInput() m_keyPressSystem( action_keys::keyPressSystem ), m_chaperoneToggle( action_keys::chaperoneToggle ), m_pushToTalk( action_keys::pushToTalk ), + m_exclusiveInputToggle( action_keys::exclusiveInputToggle ), m_leftHaptic( action_keys::hapticsLeft ), m_rightHaptic( action_keys::hapticsRight ), m_addLeftHapticClick( action_keys::addLeftHapticClick ), @@ -152,7 +153,9 @@ SteamIVRInput::SteamIVRInput() m_music.activeActionSet(), m_motion.activeActionSet(), m_misc.activeActionSet(), - m_system.activeActionSet() } ) + m_system.activeActionSet() } ), + m_systemActionSets( + { m_haptics.activeActionSet(), m_system.activeActionSet() } ) { } /*! @@ -359,6 +362,35 @@ bool SteamIVRInput::keyPressSystem() { return isDigitalActionActivatedConstant( m_keyPressSystem ); } +bool SteamIVRInput::exclusiveInputToggle() +{ + return isDigitalActionActivatedOnce( m_exclusiveInputToggle ); +} +// Controls which action Sets are active, false = all, true = system + haptics +// Adjusts in update state call. +void SteamIVRInput::systemActionSetOnlyEnabled( bool value ) +{ + m_exclusiveInputSetToggle = value; +} + +// Sets Action Set Priority +void SteamIVRInput::actionSetPriorityToggle( bool value ) +{ + if ( value ) + { + for ( unsigned int i = 0; i < action_sets::numberOfSets; i++ ) + { + m_sets.at( i ).nPriority = 0x01000001; + } + } + else + { + for ( unsigned int i = 0; i < action_sets::numberOfSets; i++ ) + { + m_sets.at( i ).nPriority = 0; + } + } +} /*! Returns the action handle of the Left Haptic Action @@ -400,10 +432,19 @@ update state. */ void SteamIVRInput::UpdateStates() { - const auto error - = vr::VRInput()->UpdateActionState( m_sets.data(), - sizeof( vr::VRActiveActionSet_t ), - action_sets::numberOfSets ); + vr::EVRInputError error; + if ( !m_exclusiveInputSetToggle ) + { + error = vr::VRInput()->UpdateActionState( + m_sets.data(), + sizeof( vr::VRActiveActionSet_t ), + action_sets::numberOfSets ); + } + else + { + error = vr::VRInput()->UpdateActionState( + m_systemActionSets.data(), sizeof( vr::VRActiveActionSet_t ), 2 ); + } if ( error != vr::EVRInputError::VRInputError_None ) { diff --git a/src/openvr/ivrinput.h b/src/openvr/ivrinput.h index 3f2d3d9..91289a8 100644 --- a/src/openvr/ivrinput.h +++ b/src/openvr/ivrinput.h @@ -6,6 +6,7 @@ #include "ivrinput_action_set.h" #include "ivrinput_input_source.h" #include +#include namespace input { @@ -58,6 +59,9 @@ namespace action_keys constexpr auto keyPressMisc = "/actions/misc/in/KeyPressMisc"; constexpr auto keyPressSystem = "/actions/system/in/KeyPressSystem"; + constexpr auto exclusiveInputToggle + = "/actions/system/in/ExclusiveInputToggle"; + constexpr auto hapticsLeft = "/actions/haptic/out/HapticsLeft"; constexpr auto hapticsRight = "/actions/haptic/out/HapticsRight"; constexpr auto proxSensor = "/actions/haptic/in/ProxSensor"; @@ -157,12 +161,20 @@ public: bool pushToTalk(); + bool exclusiveInputToggle(); + bool keyboardOne(); bool keyboardTwo(); bool keyboardThree(); bool keyPressMisc(); bool keyPressSystem(); + void systemActionSetOnlyEnabled( bool value ); + void actionSetPriorityToggle( bool value ); + + // false is all Sets, True IS System + haptics + std::atomic m_exclusiveInputSetToggle = false; + vr::VRActionHandle_t leftHapticActionHandle(); vr::VRActionHandle_t rightHapticActionHandle(); @@ -238,6 +250,9 @@ private: // Push To Talk DigitalAction m_pushToTalk; + // Exclusive Input Toggle + DigitalAction m_exclusiveInputToggle; + // haptic bindings DigitalAction m_leftHaptic; DigitalAction m_rightHaptic; @@ -253,6 +268,7 @@ private: // Initialize the set of actions after everything else. ActiveActionSets m_sets; + ActiveActionSets m_systemActionSets; }; } // namespace input diff --git a/src/openvr/ivrinput_action_set.h b/src/openvr/ivrinput_action_set.h index 33dae6d..4460332 100644 --- a/src/openvr/ivrinput_action_set.h +++ b/src/openvr/ivrinput_action_set.h @@ -25,6 +25,11 @@ public: = vr::k_ulInvalidInputValueHandle; m_activeActionSet.nPriority = 0; } + void setPriority( int32_t priority ) + { + m_activeActionSet.nPriority = priority; + } + vr::VRActiveActionSet_t activeActionSet() { return m_activeActionSet; diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index 419c748..bec9952 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -429,8 +429,9 @@ void OverlayController::SetWidget( QQuickItem* quickItem, << thumbiconFilename << "\""; } - // Too many render calls in too short time overwhelm Qt and an assertion - // gets thrown. Therefore we use an timer to delay render calls + // Too many render calls in too short time overwhelm Qt and an + // assertion gets thrown. Therefore we use an timer to delay render + // calls m_pRenderTimer.reset( new QTimer() ); m_pRenderTimer->setSingleShot( true ); m_pRenderTimer->setInterval( 5 ); @@ -520,8 +521,8 @@ void OverlayController::renderOverlay() if ( unTexture != 0 ) { #if defined _WIN64 || defined _LP64 - // To avoid any compiler warning because of cast to a larger pointer - // type (warning C4312 on VC) + // To avoid any compiler warning because of cast to a larger + // pointer type (warning C4312 on VC) vr::Texture_t texture = { reinterpret_cast( static_cast( unTexture ) ), vr::TextureType_OpenGL, @@ -584,9 +585,9 @@ void OverlayController::processMediaKeyBindings() void OverlayController::processMotionBindings() { - // Execution order for moveCenterTabController actions is important. Don't - // reorder these. Override actions must always come after normal because - // active priority is set based on which action is "newest" + // Execution order for moveCenterTabController actions is important. + // Don't reorder these. Override actions must always come after normal + // because active priority is set based on which action is "newest" // normal actions: m_moveCenterTabController.leftHandSpaceDrag( m_actions.leftHandSpaceDrag() ); @@ -653,8 +654,8 @@ void OverlayController::processPushToTalkBindings() m_audioTabController.setMicMuted( true ); return; } - // strictly speaking this is not the most elegant solution, but should - // work well enough. + // strictly speaking this is not the most elegant solution, but + // should work well enough. else if ( !pushToTalkEnabled ) { m_audioTabController.setMicMuted( false ); @@ -736,6 +737,17 @@ void OverlayController::processKeyboardBindings() m_keyPressTwoState = false; } } + +void OverlayController::processExclusiveInputBinding() +{ + if ( m_actions.exclusiveInputToggle() && exclusiveInputEnabled() ) + { + m_exclusiveState = !m_exclusiveState; + m_actions.systemActionSetOnlyEnabled( !m_exclusiveState ); + m_actions.actionSetPriorityToggle( m_exclusiveState ); + } +} + void OverlayController::processRotationBindings() { if ( m_actions.autoTurnToggle() ) @@ -745,11 +757,13 @@ void OverlayController::processRotationBindings() } } /*! -Checks if an action has been activated and dispatches the related action if it -has been. +Checks if an action has been activated and dispatches the related action if +it has been. */ void OverlayController::processInputBindings() { + processExclusiveInputBinding(); + processMediaKeyBindings(); processMotionBindings(); @@ -763,6 +777,47 @@ void OverlayController::processInputBindings() processRotationBindings(); } +bool OverlayController::exclusiveInputEnabled() const +{ + return settings::getSetting( + settings::BoolSetting::APPLICATION_enableExclusiveInput ); +} + +void OverlayController::setExclusiveInputEnabled( bool value, bool notify ) +{ + settings::setSetting( + settings::BoolSetting::APPLICATION_enableExclusiveInput, value ); + // Note: These Calls technically modify data that could be accessed + // elsewhere and cause threading issues. Since this should only be + // accessible in dashboard, and input is disabled while dashboard is up, + // there should be no reason to lock it. If it becomes an issue this needs + // to be locked with a mutex or similiar against the + // processexclusivebindings + if ( value ) + { + // Re-Enable Required SteamVR key every toggle just in case. + ovr_settings_wrapper::setBool( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowGlobalActionSetPriority, + value ); + + // To setup Exclusive Input OVRAS actions should be off besides System + // (+haptics) which are always on. + m_actions.systemActionSetOnlyEnabled( true ); + } + else + { + // Enable All Action Sets + m_actions.systemActionSetOnlyEnabled( false ); + // Remove All priority + m_actions.actionSetPriorityToggle( false ); + } + if ( notify ) + { + emit exclusiveInputEnabledChanged( value ); + } +} + bool OverlayController::crashRecoveryDisabled() const { return settings::getSetting( @@ -908,8 +963,8 @@ void OverlayController::setCustomTickRateMs( int value, bool notify ) // vsync implementation: // this function triggers every 1ms -// this function should remain lightweight and only check if it's time to run -// mainEventLoop() or not. +// this function should remain lightweight and only check if it's time to +// run mainEventLoop() or not. void OverlayController::OnTimeoutPumpEvents() { if ( vsyncDisabled() ) @@ -937,21 +992,22 @@ void OverlayController::OnTimeoutPumpEvents() if ( m_currentFrame > m_lastFrame ) { // If the frame has advanced since last check, it's time for our - // main event loop. (this function should trigger about every 11ms - // assuming 90fps compositor) + // main event loop. (this function should trigger about every + // 11ms assuming 90fps compositor) mainEventLoop(); updateRate.incrementCounter(); - // wait for the next frame after executing our main event loop once. + // wait for the next frame after executing our main event loop + // once. m_lastFrame = m_currentFrame; m_vsyncTooLateCounter = 0; } else if ( m_vsyncTooLateCounter >= k_nonVsyncTickRate ) { mainEventLoop(); - // m_lastFrame = m_currentFrame + 1 skips the next vsync frame in - // case it was just about to trigger, to prevent double updates - // faster than 11ms. + // m_lastFrame = m_currentFrame + 1 skips the next vsync frame + // in case it was just about to trigger, to prevent double + // updates faster than 11ms. m_lastFrame = m_currentFrame + 1; m_vsyncTooLateCounter = 0; } @@ -1352,11 +1408,12 @@ void OverlayController::AddOffsetToCollisionBounds( unsigned axisId, void OverlayController::AddOffsetToCollisionBounds( float offset[3], bool commit ) { - // Apparently Valve sanity-checks the y-coordinates of the collision bounds - // (and only the y-coordinates) I can move the bounds on the xz-plane, I can - // make the "ceiling" of the chaperone cage lower/higher, but when I dare to - // set one single lower corner to something non-zero, every corner gets its - // y-coordinates reset to the defaults. + // Apparently Valve sanity-checks the y-coordinates of the collision + // bounds (and only the y-coordinates) I can move the bounds on the + // xz-plane, I can make the "ceiling" of the chaperone cage + // lower/higher, but when I dare to set one single lower corner to + // something non-zero, every corner gets its y-coordinates reset to the + // defaults. if ( commit ) { vr::VRChaperoneSetup()->HideWorkingSetPreview(); @@ -1377,10 +1434,10 @@ void OverlayController::AddOffsetToCollisionBounds( float offset[3], { collisionBounds[b].vCorners[c].v[0] += offset[0]; - // keep the lower corners on the ground so it doesn't reset all - // y cooridinates. this causes the caperone to "grow" up instead - // of not moving up at all. note that Valve still forces a - // minimum height so we can't go into the ground + // keep the lower corners on the ground so it doesn't reset + // all y cooridinates. this causes the caperone to "grow" up + // instead of not moving up at all. note that Valve still + // forces a minimum height so we can't go into the ground if ( collisionBounds[b].vCorners[c].v[1] != 0 ) { collisionBounds[b].vCorners[c].v[1] += offset[1]; @@ -1563,8 +1620,8 @@ void OverlayController::OnNetworkReply( QNetworkReply* reply ) .toString(); // this is a little convoluted to ensure if our local version is - // somehow higher than remote, it doesn't detect an update from just - // higher remote "minor" or "patch" values. + // somehow higher than remote, it doesn't detect an update from + // just higher remote "minor" or "patch" values. if ( ( m_remoteVersionMajor > m_localVersionMajor ) || ( m_remoteVersionMajor == m_localVersionMajor && m_remoteVersionMinor > m_localVersionMinor ) @@ -1598,8 +1655,8 @@ void OverlayController::OnNetworkReply( QNetworkReply* reply ) setVersionCheckText( m_optionalMessage ); } setNewVersionDetected( false ); - LOG( INFO ) - << "Version Check: Installed version is latest release."; + LOG( INFO ) << "Version Check: Installed version is latest " + "release."; } } else diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index 4908f4f..b4cb5f9 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -90,6 +90,9 @@ class OverlayController : public QObject setCustomTickRateMs NOTIFY customTickRateMsChanged ) Q_PROPERTY( int debugState READ debugState WRITE setDebugState NOTIFY debugStateChanged ) + Q_PROPERTY( + bool exclusiveInputEnabled READ exclusiveInputEnabled WRITE + setExclusiveInputEnabled NOTIFY exclusiveInputEnabledChanged ) private: vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid; @@ -166,7 +169,9 @@ private: void processChaperoneBindings(); void processKeyboardBindings(); void processRotationBindings(); + void processExclusiveInputBinding(); + bool m_exclusiveState = false; bool m_keyPressOneState = false; bool m_keyPressTwoState = false; @@ -232,6 +237,7 @@ public: void mainEventLoop(); bool crashRecoveryDisabled() const; + bool exclusiveInputEnabled() const; bool enableDebug() const; bool disableVersionCheck() const; bool newVersionDetected() const; @@ -256,6 +262,7 @@ public slots: void cancelAlarm01Sound(); void setCrashRecoveryDisabled( bool value, bool notify = true ); + void setExclusiveInputEnabled( bool value, bool notify = true ); void setEnableDebug( bool value, bool notify = true ); void setDisableVersionCheck( bool value, bool notify = true ); void setNewVersionDetected( bool value, bool notify = true ); @@ -267,6 +274,7 @@ public slots: signals: void keyBoardInputSignal( QString input, unsigned long userValue = 0 ); void crashRecoveryDisabledChanged( bool value ); + void exclusiveInputEnabledChanged( bool value ); void enableDebugChanged( bool value ); void disableVersionCheckChanged( bool value ); void newVersionDetectedChanged( bool value ); diff --git a/src/package_files/action_manifest.json b/src/package_files/action_manifest.json index 63dcbde..66a5a4f 100644 --- a/src/package_files/action_manifest.json +++ b/src/package_files/action_manifest.json @@ -179,6 +179,11 @@ "name": "/actions/system/in/PushToTalk", "requirement": "optional", "type": "boolean" + }, + { + "name": "/actions/system/in/ExclusiveInputToggle", + "requirement": "optional", + "type": "boolean" }, { "name": "/actions/misc/in/ChaperoneToggle", @@ -284,6 +289,7 @@ "/actions/misc/in/YAxisLockToggle" : "Y-Axis Lock Toggle", "/actions/misc/in/ZAxisLockToggle" : "Z-Axis Lock Toggle", "/actions/system/in/PushToTalk" : "Push To Talk", + "/actions/system/in/ExclusiveInputToggle" : "Exclusive Input Toggle", "/actions/misc/in/ChaperoneToggle" : "Chaperone Toggle", "/actions/haptic/in/ProxSensor" : "Proximity Sensor", "/actions/misc/in/KeyboardOne" : "Keyboard Shortcut One", diff --git a/src/res/qml/SettingsPage.qml b/src/res/qml/SettingsPage.qml index 87fa145..0f8766f 100644 --- a/src/res/qml/SettingsPage.qml +++ b/src/res/qml/SettingsPage.qml @@ -90,6 +90,13 @@ MyStackViewPage { SettingsTabController.setOculusSdkToggle(this.checked, true) } } + MyToggleButton { + id: exclusiveInputToggleButton + text: "Exclusive Input Toggle (This enables Key Binding to Toggle state)" + onCheckedChanged: { + OverlayController.setExclusiveInputEnabled(this.checked, true) + } + } MyToggleButton { id: spaceAdjustChaperoneToggle text: "Adjust Chaperone" @@ -256,6 +263,7 @@ MyStackViewPage { disableVersionCheckToggle.checked = OverlayController.disableVersionCheck nativeChaperoneToggleButton.checked = SettingsTabController.nativeChaperoneToggle oculusSdkToggleButton.checked = SettingsTabController.oculusSdkToggle + exclusiveInputToggleButton.checked = OverlayController.exclusiveInputEnabled seatedOldExternalWarning.visible = MoveCenterTabController.allowExternalEdits && MoveCenterTabController.oldStyleMotion && MoveCenterTabController.enableSeatedMotion spaceAdjustChaperoneToggle.checked = MoveCenterTabController.adjustChaperone @@ -322,6 +330,9 @@ MyStackViewPage { onDisableVersionCheckChanged: { disableVersionCheckToggle.checked = OverlayController.disableVersionCheck } + onExclusiveInputEnabledChanged:{ + exclusiveInputToggleButton.checked = OverlayController.exclusiveInputEnabled + } } } // end scroll } diff --git a/src/settings/internal/settings_controller.h b/src/settings/internal/settings_controller.h index dccd8fa..fced11c 100644 --- a/src/settings/internal/settings_controller.h +++ b/src/settings/internal/settings_controller.h @@ -302,7 +302,10 @@ private: SettingCategory::Application, QtInfo{ "enableDebug" }, false }, - + BoolSettingValue{ BoolSetting::APPLICATION_enableExclusiveInput, + SettingCategory::Application, + QtInfo{ "enableExclusiveInput" }, + false }, BoolSettingValue{ BoolSetting::AUDIO_pttEnabled, SettingCategory::Audio, QtInfo{ "pttEnabled" }, diff --git a/src/settings/settings.h b/src/settings/settings.h index b61f6c2..f36b096 100644 --- a/src/settings/settings.h +++ b/src/settings/settings.h @@ -29,6 +29,7 @@ enum class BoolSetting APPLICATION_vsyncDisabled, APPLICATION_crashRecoveryDisabled, APPLICATION_enableDebug, + APPLICATION_enableExclusiveInput, AUDIO_pttEnabled, AUDIO_pttShowNotification,