diff --git a/.gitignore b/.gitignore index 83a79083..2c6370b6 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ installer/*.exe build_scripts/win/__pycache__ build_scripts/win/current_build.bat AdvancedSettings_resource.rc +.qtc_clangd/ \ No newline at end of file diff --git a/build_scripts/compile_version_string.txt b/build_scripts/compile_version_string.txt index eab49e74..2cfbd000 100644 --- a/build_scripts/compile_version_string.txt +++ b/build_scripts/compile_version_string.txt @@ -1 +1 @@ -5.6.2-release \ No newline at end of file +5.7.0-release \ No newline at end of file diff --git a/build_scripts/linux/format.sh b/build_scripts/linux/format.sh index 8720bc75..421ff0f5 100755 --- a/build_scripts/linux/format.sh +++ b/build_scripts/linux/format.sh @@ -1,17 +1,28 @@ #!/usr/bin/env bash set -e -clang-format --version +if [ -x /usr/bin/clang-format-10 ]; then + CLANG_FORMAT_EXE=clang-format-10 +else + CLANG_FORMAT_EXE=clang-format +fi + +CLANG_VERSION="$($CLANG_FORMAT_EXE --version)" +echo $CLANG_VERSION +if [[ "$CLANG_VERSION" != *"clang-format version 10"* ]]; then + echo "Wrong clang-format version found! Install version 10" + exit 1 +fi if [ $? -eq 0 ]; then echo "Clang-format found." build_path="`dirname \"$0\"`" project_path=$build_path/../.. - find $project_path/src/ -regex '.*\.\(cpp\|h\)' -exec clang-format -style=file -i {} \; -exec echo "Iteration 1: {}" \; - find $project_path/src/ -regex '.*\.\(cpp\|h\)' -exec clang-format -style=file -i {} \; -exec echo "Iteration 2: {}" \; + find $project_path/src/ -regex '.*\.\(cpp\|h\)' -exec $CLANG_FORMAT_EXE -style=file -i {} \; -exec echo "Iteration 1: {}" \; + find $project_path/src/ -regex '.*\.\(cpp\|h\)' -exec $CLANG_FORMAT_EXE -style=file -i {} \; -exec echo "Iteration 2: {}" \; echo "DONE" else - echo "Could not find clang-format." + echo "Could not find clang-format-10." fi diff --git a/src/openvr/openvr_init.cpp b/src/openvr/openvr_init.cpp index 1df89e1c..73779ef2 100644 --- a/src/openvr/openvr_init.cpp +++ b/src/openvr/openvr_init.cpp @@ -26,15 +26,25 @@ void initializeProperly( const OpenVrInitializationType initType ) if ( initError == vr::VRInitError_Init_HmdNotFound || initError == vr::VRInitError_Init_HmdNotFoundPresenceFailed ) { - QMessageBox::critical( nullptr, - "OpenVR Advanced Settings Overlay", - "Could not find HMD!" ); + // In particular in some setups these errors are thrown while + // nothing is wrong with their setup presumably this is some sort of + // race condition + LOG( WARNING ) << "HMD not Found During Startup"; + LOG( WARNING ) << "steamvr error: " + + std::string( + vr::VR_GetVRInitErrorAsEnglishDescription( + initError ) ); + return; } LOG( ERROR ) << "Failed to initialize OpenVR: " + std::string( vr::VR_GetVRInitErrorAsEnglishDescription( initError ) ); - exit( EXIT_FAILURE ); + // Going to stop Exiting App, This may lead to crashes if OpenVR + // actually fails to start, HOWEVER based on the HMD errors we are + // probably pre-maturely killing ourselves from some sort of OpenVR race + // condition + // exit( EXIT_FAILURE ); } else { diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index 687e19b5..8d01cd8d 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -69,6 +69,7 @@ OverlayController::OverlayController( bool desktopMode, m_runtimePathUrl = QUrl::fromLocalFile( tempRuntimePath ); LOG( INFO ) << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile(); + const double initVol = soundVolume(); constexpr auto clickSoundURL = "res/sounds/click.wav"; const auto activationSoundFile = paths::binaryDirectoryFindFile( clickSoundURL ); @@ -77,7 +78,7 @@ OverlayController::OverlayController( bool desktopMode, { m_activationSoundEffect.setSource( QUrl::fromLocalFile( QString::fromStdString( ( *activationSoundFile ) ) ) ); - m_activationSoundEffect.setVolume( 0.7 ); + m_activationSoundEffect.setVolume( initVol ); } else { @@ -92,7 +93,7 @@ OverlayController::OverlayController( bool desktopMode, { m_focusChangedSoundEffect.setSource( QUrl::fromLocalFile( QString::fromStdString( ( *focusChangedSoundFile ) ) ) ); - m_focusChangedSoundEffect.setVolume( 0.7 ); + m_focusChangedSoundEffect.setVolume( initVol ); } else { @@ -1648,6 +1649,26 @@ void OverlayController::setKeyboardPos() vr::VROverlay()->SetKeyboardPositionForOverlay( m_ulOverlayHandle, empty ); } +void OverlayController::setSoundVolume( double value, bool notify ) +{ + m_activationSoundEffect.setVolume( value ); + m_focusChangedSoundEffect.setVolume( value ); + // leaving alarm sound alone for now as chaperone warning setting effects it + // m_alarm01SoundEffect.setVolume( value); + settings::setSetting( settings::DoubleSetting::APPLICATION_appVolume, + value ); + if ( notify ) + { + emit soundVolumeChanged( value ); + } +} + +double OverlayController::soundVolume() const +{ + return settings::getSetting( + settings::DoubleSetting::APPLICATION_appVolume ); +} + void OverlayController::playActivationSound() { if ( !m_noSound ) diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index 8312e9cd..ba98ba25 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -96,6 +96,8 @@ class OverlayController : public QObject Q_PROPERTY( bool autoApplyChaperoneEnabled READ autoApplyChaperoneEnabled WRITE setAutoApplyChaperoneEnabled NOTIFY autoApplyChaperoneEnabledChanged ) + Q_PROPERTY( double soundVolume READ soundVolume WRITE setSoundVolume NOTIFY + soundVolumeChanged ) private: vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid; @@ -252,6 +254,8 @@ class OverlayController : public QObject int debugState() const; std::string autoApplyChaperoneName(); + double soundVolume() const; + public slots: void renderOverlay(); void OnRenderRequest(); @@ -277,6 +281,7 @@ public slots: void setCustomTickRateMs( int value, bool notify = true ); void setDebugState( int value, bool notify = true ); void setAutoApplyChaperoneEnabled( bool value, bool notify = true ); + void setSoundVolume( double value, bool notify = true ); signals: void keyBoardInputSignal( QString input, unsigned long userValue = 0 ); @@ -290,6 +295,7 @@ public slots: void customTickRateMsChanged( int value ); void debugStateChanged( int value ); void autoApplyChaperoneEnabledChanged( bool value ); + void soundVolumeChanged( double value ); }; } // namespace advsettings diff --git a/src/res/qml/SettingsPage.qml b/src/res/qml/SettingsPage.qml index 2cf49a22..121958f1 100644 --- a/src/res/qml/SettingsPage.qml +++ b/src/res/qml/SettingsPage.qml @@ -18,6 +18,73 @@ MyStackViewPage { ColumnLayout { spacing: 18 + RowLayout{ + MyText { + text: "Application Volume:" + Layout.rightMargin: 12 + } + + MyPushButton2 { + text: "-" + Layout.preferredWidth: 40 + onClicked: { + volumeSlider.value -= 0.05 + } + } + + MySlider { + id: volumeSlider + from: 0.0 + to: 1.0 + stepSize: 0.01 + value: 0.7 + Layout.fillWidth: true + onPositionChanged: { + var val = (this.value * 100) + volumeText.text = Math.round(val) + "%" + } + onValueChanged: { + OverlayController.setSoundVolume(value, false) + } + } + + MyPushButton2 { + text: "+" + Layout.preferredWidth: 40 + onClicked: { + volumeSlider.value += 0.05 + } + } + + + MyTextField { + id: volumeText + text: "70%" + keyBoardUID: 503 + Layout.preferredWidth: 100 + Layout.leftMargin: 10 + horizontalAlignment: Text.AlignHCenter + function onInputEvent(input) { + var val = parseFloat(input) + if (!isNaN(val)) { + if (val < 0) { + val = 0 + } else if (val > 100.0) { + val = 100.0 + } + + var v = (val/100).toFixed(0) + if (v <= volumeSlider.to) { + chaperoneVisibilitySlider.value = v + } else { + ChaperoneTabController.setBoundsVisibility(v, false) + } + } + text = Math.round(ChaperoneTabController.boundsVisibility * 100) + "%" + } + } + } + MyToggleButton { id: settingsAutoStartToggle text: "Autostart" @@ -295,6 +362,7 @@ MyStackViewPage { seatedOldExternalWarning.visible = MoveCenterTabController.allowExternalEdits && MoveCenterTabController.oldStyleMotion reloadChaperoneProfiles() + volumeSlider.value = OverlayController.soundVolume } Connections { @@ -357,6 +425,9 @@ MyStackViewPage { onAutoApplyChaperoneEnabledChanged: { autoApplyChaperoneToggleButton.checked = OverlayController.autoApplyChaperoneEnabled } + onSoundVolumeChanged:{ + volumeSlider.value = OverlayController.soundVolume + } } Connections{ target: ChaperoneTabController diff --git a/src/res/qml/chaperone_page/ChaperonePage.qml b/src/res/qml/chaperone_page/ChaperonePage.qml index b09ecf6e..1adc8b10 100644 --- a/src/res/qml/chaperone_page/ChaperonePage.qml +++ b/src/res/qml/chaperone_page/ChaperonePage.qml @@ -244,6 +244,7 @@ MyStackViewPage { } MyPushButton2 { + id: chaperoneVisibilityMinus text: "-" Layout.preferredWidth: 40 onClicked: { @@ -268,6 +269,7 @@ MyStackViewPage { } MyPushButton2 { + id: chaperoneVisibilityPlus text: "+" Layout.preferredWidth: 40 onClicked: { @@ -561,7 +563,13 @@ MyStackViewPage { chaperonePlaySpaceToggle.checked = ChaperoneTabController.playSpaceMarker chaperoneForceBoundsToggle.checked = ChaperoneTabController.forceBounds chaperoneDisableChaperone.checked = ChaperoneTabController.disableChaperone - if(chaperoneDisableChaperone.checked){ + var dim = ChaperoneTabController.chaperoneDimHeight + if(dim > 0.0){ + chaperoneDisableChaperone.enabled = false; + }else{ + chaperoneDisableChaperone.enabled = true; + } + if(dim > 0.0 || chaperoneDisableChaperone.checked){ chaperoneFadeDistanceMinus.enabled = false; chaperoneFadeDistancePlus.enabled = false; chaperoneFadeDistanceSlider.enabled = false; @@ -597,7 +605,26 @@ MyStackViewPage { } chaperoneHeightText.text = h } + onChaperoneDimHeightChanged: { + var dim = ChaperoneTabController.chaperoneDimHeight + if(dim > 0.0){ + chaperoneDisableChaperone.enabled = false; + }else{ + chaperoneDisableChaperone.enabled = true; + } + if(dim > 0.0 || chaperoneDisableChaperone.checked){ + chaperoneFadeDistanceMinus.enabled = false; + chaperoneFadeDistancePlus.enabled = false; + chaperoneFadeDistanceSlider.enabled = false; + chaperoneFadeDistanceText.enabled = false; + }else{ + chaperoneFadeDistanceMinus.enabled = true; + chaperoneFadeDistancePlus.enabled = true; + chaperoneFadeDistanceSlider.enabled = true; + chaperoneFadeDistanceText.enabled = true; + } + } onCenterMarkerNewChanged: { chaperoneCenterMarkerToggle.checked = ChaperoneTabController.centerMarkerNew } diff --git a/src/res/qml/chaperone_page/chaperone_additional/ChaperoneAdditionalPage.qml b/src/res/qml/chaperone_page/chaperone_additional/ChaperoneAdditionalPage.qml index ce66c44d..8f18c33c 100644 --- a/src/res/qml/chaperone_page/chaperone_additional/ChaperoneAdditionalPage.qml +++ b/src/res/qml/chaperone_page/chaperone_additional/ChaperoneAdditionalPage.qml @@ -28,9 +28,100 @@ MyStackViewPage { Layout.fillHeight: true } - } + GridLayout { + columns: 5 + + MyText { + text: "Disable chaperone below height: " + Layout.preferredWidth: 400 + } + MyPushButton2 { + id: dimHeightMinusButton + Layout.preferredWidth: 40 + text: "-" + onClicked: { + var val = ChaperoneTabController.chaperoneDimHeight - 0.1 + if (val <= 0.0) { + val = 0.0; + } + ChaperoneTabController.chaperoneDimHeight = val.toFixed(2) + } + } + + MySlider { + id: dimHeightSlider + from: 0 + to: 2.0 + stepSize: 0.01 + value: 0.0 + Layout.fillWidth: true + onPositionChanged: { + var val = this.from + ( this.position * (this.to - this.from)) + dimHeightText.text = val.toFixed(2) + } + onValueChanged: { + var val = dimHeightSlider.value.toFixed(2) + if (val < 0.01) { + val = 0.00 + } + ChaperoneTabController.chaperoneDimHeight = val + dimHeightText.text = val + } + } + MyPushButton2 { + id: dimHeightPlusButton + Layout.preferredWidth: 40 + text: "+" + onClicked: { + var val = ChaperoneTabController.chaperoneDimHeight + 0.1 + if (val > 2.0) { + val = 2.0; + } + ChaperoneTabController.chaperoneDimHeight = val.toFixed(2) + } + } + + MyTextField { + id: dimHeightText + text: "0.00" + keyBoardUID: 802 + Layout.preferredWidth: 100 + Layout.leftMargin: 10 + horizontalAlignment: Text.AlignHCenter + function onInputEvent(input) { + var val = parseFloat(input) + if (!isNaN(val)) { + if (val <= 0.0) { + val = 0.0 + } + val = val.toFixed(2) + ChaperoneTabController.chaperoneDimHeight = val + text = val + } else { + text = ChaperoneTabController.chaperoneDimHeight.toFixed(2) + } + } + } + } + Component.onCompleted: { + var d = ChaperoneTabController.chaperoneDimHeight.toFixed(2) + dimHeightSlider.value = d + dimHeightText.text = d + } + + Connections { + target: ChaperoneTabController + onChaperoneDimHeightChanged: { + var d = ChaperoneTabController.chaperoneDimHeight.toFixed(2) + if (d <= dimHeightSlider.to && Math.abs(dimHeightSlider.value - d) > 0.0008) { + dimHeightSlider.value = d + } + dimHeightText.text = d + } + } + } } diff --git a/src/settings/internal/bool_setting_value.h b/src/settings/internal/bool_setting_value.h old mode 100644 new mode 100755 diff --git a/src/settings/internal/settings_controller.h b/src/settings/internal/settings_controller.h index 3567c356..a26b4945 100644 --- a/src/settings/internal/settings_controller.h +++ b/src/settings/internal/settings_controller.h @@ -446,6 +446,11 @@ class SettingsController QtInfo{ "dragMult" }, 1.0 }, + DoubleSettingValue{ DoubleSetting::APPLICATION_appVolume, + SettingCategory::Application, + QtInfo{ "appVolume" }, + 0.7 }, + DoubleSettingValue{ DoubleSetting::VIDEO_brightnessOpacityValue, SettingCategory::Video, QtInfo{ "brightnessOpacityValue" }, @@ -495,6 +500,10 @@ class SettingsController SettingCategory::Chaperone, QtInfo{ "fadeDistanceRemembered" }, 0.5 }, + DoubleSettingValue{ DoubleSetting::CHAPERONE_dimHeight, + SettingCategory::Chaperone, + QtInfo{ "dimHeight" }, + 0.0 }, DoubleSettingValue{ DoubleSetting::ROTATION_activationDistance, SettingCategory::Rotation, QtInfo{ "activationDistance" }, diff --git a/src/settings/settings.h b/src/settings/settings.h index 69593f04..71645909 100644 --- a/src/settings/settings.h +++ b/src/settings/settings.h @@ -74,6 +74,8 @@ enum class DoubleSetting PLAYSPACE_flingStrength, PLAYSPACE_dragMult, + APPLICATION_appVolume, + VIDEO_brightnessOpacityValue, VIDEO_colorOverlayOpacity, VIDEO_colorRed, @@ -85,6 +87,7 @@ enum class DoubleSetting CHAPERONE_alarmSoundDistance, CHAPERONE_showDashboardDistance, CHAPERONE_fadeDistanceRemembered, + CHAPERONE_dimHeight, ROTATION_activationDistance, ROTATION_deactivateDistance, diff --git a/src/tabcontrollers/ChaperoneTabController.cpp b/src/tabcontrollers/ChaperoneTabController.cpp index 200e3857..53aa925a 100644 --- a/src/tabcontrollers/ChaperoneTabController.cpp +++ b/src/tabcontrollers/ChaperoneTabController.cpp @@ -248,6 +248,27 @@ void ChaperoneTabController::eventLoopTick( checkCenterMarkerOverlayRotationCount(); } + if ( m_dimmingActive && m_dimNotificationTimestamp ) + { + auto count = std::chrono::duration_cast( + std::chrono::steady_clock::now() + - *m_dimNotificationTimestamp ) + .count(); + if ( count > 10000 ) + { + m_dimNotificationTimestamp.reset(); + setFadeDistance( 0.0f, true ); + } + else + { + float pct = std::min( + 1.0f, 2.0f - static_cast( count ) / 5000.0f ); + // Originally this used opacity, but steam will override that it + // seems + setFadeDistance( pct * 0.4f, true ); + } + } + if ( devicePoses ) { m_isHMDActive = false; @@ -277,6 +298,26 @@ void ChaperoneTabController::eventLoopTick( { minDistance = distanceHmd.distance; } + if ( chaperoneDimHeight() > 0.0f ) + { + // Both of these only activate on state changes (e.g. when first + // going above/below chaperoneDimHeight()) + if ( !m_dimmingActive + && poseHmd.mDeviceToAbsoluteTracking.m[1][3] + < chaperoneDimHeight() ) + { + m_dimmingActive = true; + m_dimNotificationTimestamp.emplace( + std::chrono::steady_clock::now() ); + } + else if ( m_dimmingActive + && poseHmd.mDeviceToAbsoluteTracking.m[1][3] + >= chaperoneDimHeight() ) + { + m_dimmingActive = false; + setFadeDistance( 0.4f, true ); + } + } } auto leftIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( vr::TrackedControllerRole_LeftHand ); @@ -556,6 +597,12 @@ bool ChaperoneTabController::disableChaperone() const settings::BoolSetting::CHAPERONE_disableChaperone ); } +float ChaperoneTabController::chaperoneDimHeight() const +{ + return static_cast( + settings::getSetting( settings::DoubleSetting::CHAPERONE_dimHeight ) ); +} + float ChaperoneTabController::chaperoneAlarmSoundDistance() const { return static_cast( settings::getSetting( @@ -1061,6 +1108,17 @@ void ChaperoneTabController::setChaperoneAlarmSoundAdjustVolume( bool value, } } +void ChaperoneTabController::setChaperoneDimHeight( float value, bool notify ) +{ + settings::setSetting( settings::DoubleSetting::CHAPERONE_dimHeight, + static_cast( value ) ); + + if ( notify ) + { + emit chaperoneDimHeightChanged( value ); + } +} + void ChaperoneTabController::setChaperoneAlarmSoundDistance( float value, bool notify ) { @@ -1221,6 +1279,7 @@ void ChaperoneTabController::addChaperoneProfile( if ( includeFadeDistance ) { profile->fadeDistance = m_fadeDistance; + profile->chaperoneDimHeight = chaperoneDimHeight(); } profile->includesCenterMarker = includeCenterMarker; if ( includeCenterMarker ) @@ -1312,6 +1371,7 @@ void ChaperoneTabController::applyChaperoneProfile( unsigned index ) if ( profile.includesFadeDistance ) { setFadeDistance( profile.fadeDistance ); + setChaperoneDimHeight( profile.chaperoneDimHeight ); } if ( profile.includesCenterMarker ) { diff --git a/src/tabcontrollers/ChaperoneTabController.h b/src/tabcontrollers/ChaperoneTabController.h index 10abc707..a28977e1 100644 --- a/src/tabcontrollers/ChaperoneTabController.h +++ b/src/tabcontrollers/ChaperoneTabController.h @@ -69,6 +69,7 @@ struct ChaperoneProfile : settings::ISettingsObject bool enableChaperoneShowDashboard = false; float chaperoneShowDashboardDistance = 0.0f; bool centerMarkerNew = false; + float chaperoneDimHeight = 0.0f; virtual settings::SettingsObjectData saveSettings() const override { @@ -147,6 +148,7 @@ struct ChaperoneProfile : settings::ISettingsObject o.addValue( enableChaperoneShowDashboard ); o.addValue( static_cast( chaperoneShowDashboardDistance ) ); o.addValue( centerMarkerNew ); + o.addValue( static_cast( chaperoneDimHeight ) ); return o; } @@ -238,6 +240,8 @@ struct ChaperoneProfile : settings::ISettingsObject chaperoneShowDashboardDistance = static_cast( obj.getNextValueOrDefault( 0.0 ) ); centerMarkerNew = obj.getNextValueOrDefault( false ); + chaperoneDimHeight + = static_cast( obj.getNextValueOrDefault( 0.0 ) ); } virtual std::string settingsName() const override @@ -298,6 +302,9 @@ class ChaperoneTabController : public QObject setChaperoneAlarmSoundDistance NOTIFY chaperoneAlarmSoundDistanceChanged ) + Q_PROPERTY( float chaperoneDimHeight READ chaperoneDimHeight WRITE + setChaperoneDimHeight NOTIFY chaperoneDimHeightChanged ) + Q_PROPERTY( bool chaperoneShowDashboardEnabled READ isChaperoneShowDashboardEnabled WRITE setChaperoneShowDashboardEnabled NOTIFY @@ -380,6 +387,10 @@ class ChaperoneTabController : public QObject int m_rotationCurrent = 0; bool m_centerMarkerOverlayIsInit = false; + bool m_dimmingActive = false; + std::optional + m_dimNotificationTimestamp; + vr::ETrackingUniverseOrigin m_trackingUniverse = vr::TrackingUniverseRawAndUncalibrated; @@ -417,6 +428,8 @@ class ChaperoneTabController : public QObject int collisionBoundStyle(); + float chaperoneDimHeight() const; + void setRightHapticActionHandle( vr::VRActionHandle_t handle ); void setLeftHapticActionHandle( vr::VRActionHandle_t handle ); void setRightInputHandle( vr::VRInputValueHandle_t handle ); @@ -477,6 +490,8 @@ public slots: void setChaperoneShowDashboardEnabled( bool value, bool notify = true ); void setChaperoneShowDashboardDistance( float value, bool notify = true ); + void setChaperoneDimHeight( float value, bool notify = true ); + void setChaperoneColorR( int value, bool notify = true ); void setChaperoneColorG( int value, bool notify = true ); void setChaperoneColorB( int value, bool notify = true ); @@ -515,6 +530,7 @@ public slots: void boundsVisibilityChanged( float value ); void fadeDistanceChanged( float value ); void heightChanged( float value ); + void chaperoneDimHeightChanged( float value ); void centerMarkerChanged( bool value ); void playSpaceMarkerChanged( bool value ); void forceBoundsChanged( bool value );