diff --git a/bin/win64/res/qml/MyComboBox.qml b/bin/win64/res/qml/MyComboBox.qml index 30cf6c5..f008add 100644 --- a/bin/win64/res/qml/MyComboBox.qml +++ b/bin/win64/res/qml/MyComboBox.qml @@ -64,7 +64,7 @@ ComboBox { onActivated: { if (activeFocus) { - MyResources.activationSound.play() + MyResources.playActivationSound() } } diff --git a/bin/win64/res/qml/MyPushButton.qml b/bin/win64/res/qml/MyPushButton.qml index a070053..cd55ad8 100644 --- a/bin/win64/res/qml/MyPushButton.qml +++ b/bin/win64/res/qml/MyPushButton.qml @@ -25,7 +25,7 @@ Button { onClicked: { if (activationSoundEnabled) { - MyResources.activationSound.play() + MyResources.playActivationSound() } } } diff --git a/bin/win64/res/qml/MyPushButton2.qml b/bin/win64/res/qml/MyPushButton2.qml index b819b5d..31da025 100644 --- a/bin/win64/res/qml/MyPushButton2.qml +++ b/bin/win64/res/qml/MyPushButton2.qml @@ -24,6 +24,6 @@ Button { } onClicked: { - MyResources.activationSound.play() + MyResources.playActivationSound() } } diff --git a/bin/win64/res/qml/MyResources.qml b/bin/win64/res/qml/MyResources.qml index bae3c94..cb51420 100644 --- a/bin/win64/res/qml/MyResources.qml +++ b/bin/win64/res/qml/MyResources.qml @@ -1,8 +1,19 @@ pragma Singleton import QtQuick 2.7 import QtMultimedia 5.6 +import matzman666.advsettings 1.0 QtObject { + function playActivationSound() { + if (!OverlayController.soundDisabled()) { + activationSound.play() + } + } + function playFocusChangedSound() { + if (!OverlayController.soundDisabled()) { + focusChangedSound.play() + } + } property SoundEffect activationSound: SoundEffect { source: vrRuntimePath + "tools/content/panorama/sounds/activation.wav" } diff --git a/bin/win64/res/qml/MySlider.qml b/bin/win64/res/qml/MySlider.qml index e3d5808..344cc39 100644 --- a/bin/win64/res/qml/MySlider.qml +++ b/bin/win64/res/qml/MySlider.qml @@ -46,7 +46,7 @@ Slider { onValueChanged: { if (activeFocus) { - MyResources.activationSound.play() + MyResources.playActivationSound() } } } diff --git a/bin/win64/res/qml/MyStackViewPage.qml b/bin/win64/res/qml/MyStackViewPage.qml index 8ad1242..71f39be 100644 --- a/bin/win64/res/qml/MyStackViewPage.qml +++ b/bin/win64/res/qml/MyStackViewPage.qml @@ -43,7 +43,7 @@ Rectangle { } } onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() stackView.pop() } } diff --git a/bin/win64/res/qml/MyToggleButton.qml b/bin/win64/res/qml/MyToggleButton.qml index f6930d6..85629b6 100644 --- a/bin/win64/res/qml/MyToggleButton.qml +++ b/bin/win64/res/qml/MyToggleButton.qml @@ -48,6 +48,6 @@ CheckBox { } onClicked: { - MyResources.activationSound.play() + MyResources.playActivationSound() } } diff --git a/bin/win64/res/qml/RootPage.qml b/bin/win64/res/qml/RootPage.qml index ddc126e..e87a616 100644 --- a/bin/win64/res/qml/RootPage.qml +++ b/bin/win64/res/qml/RootPage.qml @@ -27,7 +27,7 @@ MyStackViewPage { text: "SteamVR" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(steamVRPage) } } @@ -38,7 +38,7 @@ MyStackViewPage { text: "Chaperone" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(chaperonePage) } } @@ -49,7 +49,7 @@ MyStackViewPage { text: "Play Space" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(playspacePage) } } @@ -60,7 +60,7 @@ MyStackViewPage { text: "Floor Fix" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(fixFloorPage) } } @@ -71,7 +71,7 @@ MyStackViewPage { text: "Audio" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(audioPage) } } @@ -82,7 +82,7 @@ MyStackViewPage { text: "Statistics" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(statisticsPage) } } @@ -98,7 +98,7 @@ MyStackViewPage { text: "Settings" Layout.fillWidth: true onClicked: { - MyResources.focusChangedSound.play() + MyResources.playFocusChangedSound() mainView.push(settingsPage) } } diff --git a/src/main.cpp b/src/main.cpp index a261467..787254f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,7 @@ void myQtMessageHandler(QtMsgType type, const QMessageLogContext &context, const int main(int argc, char *argv[]) { + // Configure logger START_EASYLOGGINGPP(argc, argv); el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog); @@ -55,6 +56,19 @@ int main(int argc, char *argv[]) { conf.parseFromText(logConfigDefault); el::Loggers::reconfigureAllLoggers(conf); } + + bool desktopMode = false; + bool noSound = false; + + // Parse command line arguments + for (int i = 1; i < argc; i++) { + if (std::string(argv[i]).compare("-desktop") == 0) { + LOG(INFO) << "Desktop mode enabled."; + desktopMode = true; + } else if (std::string(argv[i]).compare("-nosound") == 0) { + noSound = true; + } + } LOG(INFO) << "Starting Application."; try { @@ -67,7 +81,7 @@ int main(int argc, char *argv[]) { QQmlEngine qmlEngine; - advsettings::OverlayController* controller = advsettings::OverlayController::getInstance(); + advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktopMode, noSound); controller->Init(&qmlEngine); QQmlComponent component(&qmlEngine, QUrl::fromLocalFile("res/qml/mainwidget.qml")); @@ -78,31 +92,33 @@ int main(int argc, char *argv[]) { auto quickObj = component.create(); controller->SetWidget(qobject_cast(quickObj), advsettings::OverlayController::applicationName, advsettings::OverlayController::applicationKey); - std::string manifestPath = QApplication::applicationDirPath().toStdString() + "\\advancedsettings.vrmanifest"; - if (QFile::exists(QString::fromStdString(manifestPath))) { - bool firstTime = false; - if (!vr::VRApplications()->IsApplicationInstalled(advsettings::OverlayController::applicationKey)) { - firstTime; - } - auto apperror = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); - if (apperror != vr::VRApplicationError_None) { - LOG(ERROR) << "Could not add application manifest: " << vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror); - } else if (firstTime) { - auto apperror = vr::VRApplications()->SetApplicationAutoLaunch(advsettings::OverlayController::applicationKey, true); - if (apperror != vr::VRApplicationError_None) { - LOG(ERROR) << "Could not set auto start: " << vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror); + if (!desktopMode) { + std::string manifestPath = QApplication::applicationDirPath().toStdString() + "\\advancedsettings.vrmanifest"; + if (QFile::exists(QString::fromStdString(manifestPath))) { + bool firstTime = false; + if (!vr::VRApplications()->IsApplicationInstalled(advsettings::OverlayController::applicationKey)) { + firstTime; } + auto apperror = vr::VRApplications()->AddApplicationManifest(manifestPath.c_str()); + if (apperror != vr::VRApplicationError_None) { + LOG(ERROR) << "Could not add application manifest: " << vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror); + } else if (firstTime) { + auto apperror = vr::VRApplications()->SetApplicationAutoLaunch(advsettings::OverlayController::applicationKey, true); + if (apperror != vr::VRApplicationError_None) { + LOG(ERROR) << "Could not set auto start: " << vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror); + } + } + } else { + LOG(ERROR) << "Could not find application manifest: " << manifestPath; } - } else { - LOG(ERROR) << "Could not find application manifest: " << manifestPath; } -#ifdef DEBUG_DESKTOP_WINDOW - auto m_pWindow = new QQuickWindow(); - qobject_cast(quickObj)->setParentItem(m_pWindow->contentItem()); - m_pWindow->setGeometry(0, 0, qobject_cast(quickObj)->width(), qobject_cast(quickObj)->height()); - m_pWindow->show(); -#endif + if (desktopMode) { + auto m_pWindow = new QQuickWindow(); + qobject_cast(quickObj)->setParentItem(m_pWindow->contentItem()); + m_pWindow->setGeometry(0, 0, qobject_cast(quickObj)->width(), qobject_cast(quickObj)->height()); + m_pWindow->show(); + } return a.exec(); diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index ba0699f..647d52a 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -130,21 +130,51 @@ void OverlayController::Init(QQmlEngine* qmlEngine) { void OverlayController::SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key) { - vr::VROverlayError overlayError = vr::VROverlay()->CreateDashboardOverlay(key.c_str(), name.c_str(), &m_ulOverlayHandle, &m_ulOverlayThumbnailHandle); - if (overlayError != vr::VROverlayError_None) { - if (overlayError == vr::VROverlayError_KeyInUse) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "Another instance is already running."); + if (!desktopMode) { + vr::VROverlayError overlayError = vr::VROverlay()->CreateDashboardOverlay(key.c_str(), name.c_str(), &m_ulOverlayHandle, &m_ulOverlayThumbnailHandle); + if (overlayError != vr::VROverlayError_None) { + if (overlayError == vr::VROverlayError_KeyInUse) { + QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "Another instance is already running."); + } + throw std::runtime_error(std::string("Failed to create Overlay: " + std::string(vr::VROverlay()->GetOverlayErrorNameFromEnum(overlayError)))); } - throw std::runtime_error(std::string("Failed to create Overlay: " + std::string(vr::VROverlay()->GetOverlayErrorNameFromEnum(overlayError)))); - } - vr::VROverlay()->SetOverlayWidthInMeters(m_ulOverlayHandle, 2.5f); - vr::VROverlay()->SetOverlayInputMethod(m_ulOverlayHandle, vr::VROverlayInputMethod_Mouse); - vr::VROverlay()->SetOverlayFlag(m_ulOverlayHandle, vr::VROverlayFlags_SendVRScrollEvents, true); - std::string thumbIconPath = QApplication::applicationDirPath().toStdString() + "\\res\\thumbicon.png"; - if (QFile::exists(QString::fromStdString(thumbIconPath))) { - vr::VROverlay()->SetOverlayFromFile(m_ulOverlayThumbnailHandle, thumbIconPath.c_str()); - } else { - LOG(ERROR) << "Could not find thumbnail icon \"" << thumbIconPath << "\""; + vr::VROverlay()->SetOverlayWidthInMeters(m_ulOverlayHandle, 2.5f); + vr::VROverlay()->SetOverlayInputMethod(m_ulOverlayHandle, vr::VROverlayInputMethod_Mouse); + vr::VROverlay()->SetOverlayFlag(m_ulOverlayHandle, vr::VROverlayFlags_SendVRScrollEvents, true); + std::string thumbIconPath = QApplication::applicationDirPath().toStdString() + "\\res\\thumbicon.png"; + if (QFile::exists(QString::fromStdString(thumbIconPath))) { + vr::VROverlay()->SetOverlayFromFile(m_ulOverlayThumbnailHandle, thumbIconPath.c_str()); + } else { + LOG(ERROR) << "Could not find thumbnail icon \"" << thumbIconPath << "\""; + } + + // 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); + connect(m_pRenderTimer.get(), SIGNAL(timeout()), this, SLOT(renderOverlay())); + + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + fboFormat.setTextureTarget(GL_TEXTURE_2D); + m_pFbo.reset(new QOpenGLFramebufferObject(quickItem->width(), quickItem->height(), fboFormat)); + + m_pRenderControl.reset(new QQuickRenderControl()); + m_pWindow.reset(new QQuickWindow(m_pRenderControl.get())); + m_pWindow->setRenderTarget(m_pFbo.get()); + quickItem->setParentItem(m_pWindow->contentItem()); + m_pWindow->setGeometry(0, 0, quickItem->width(), quickItem->height()); + m_pRenderControl->initialize(m_pOpenGLContext.get()); + + vr::HmdVector2_t vecWindowSize = { + (float)quickItem->width(), + (float)quickItem->height() + }; + vr::VROverlay()->SetOverlayMouseScale(m_ulOverlayHandle, &vecWindowSize); + + connect(m_pRenderControl.get(), SIGNAL(renderRequested()), this, SLOT(OnRenderRequest())); + connect(m_pRenderControl.get(), SIGNAL(sceneChanged()), this, SLOT(OnRenderRequest())); } m_pPumpEventsTimer.reset(new QTimer()); @@ -152,36 +182,6 @@ void OverlayController::SetWidget(QQuickItem* quickItem, const std::string& name m_pPumpEventsTimer->setInterval(20); m_pPumpEventsTimer->start(); - // 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); - connect(m_pRenderTimer.get(), SIGNAL(timeout()), this, SLOT(renderOverlay())); - - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - fboFormat.setTextureTarget(GL_TEXTURE_2D); - m_pFbo.reset(new QOpenGLFramebufferObject(quickItem->width(), quickItem->height(), fboFormat)); - -#ifndef DEBUG_DESKTOP_WINDOW - m_pRenderControl.reset(new QQuickRenderControl()); - m_pWindow.reset(new QQuickWindow(m_pRenderControl.get())); - m_pWindow->setRenderTarget(m_pFbo.get()); - quickItem->setParentItem(m_pWindow->contentItem()); - m_pWindow->setGeometry(0, 0, quickItem->width(), quickItem->height()); - m_pRenderControl->initialize(m_pOpenGLContext.get()); - - vr::HmdVector2_t vecWindowSize = { - (float)quickItem->width(), - (float)quickItem->height() - }; - vr::VROverlay()->SetOverlayMouseScale(m_ulOverlayHandle, &vecWindowSize); - - connect(m_pRenderControl.get(), SIGNAL(renderRequested()), this, SLOT(OnRenderRequest())); - connect(m_pRenderControl.get(), SIGNAL(sceneChanged()), this, SLOT(OnRenderRequest())); -#endif - steamVRTabController.initStage2(this, m_pWindow.get()); chaperoneTabController.initStage2(this, m_pWindow.get()); moveCenterTabController.initStage2(this, m_pWindow.get()); @@ -199,27 +199,26 @@ void OverlayController::OnRenderRequest() { } void OverlayController::renderOverlay() { - // skip rendering if the overlay isn't visible - if (!vr::VROverlay() || !vr::VROverlay()->IsOverlayVisible(m_ulOverlayHandle) && !vr::VROverlay()->IsOverlayVisible(m_ulOverlayThumbnailHandle)) - return; + if (!desktopMode) { + // skip rendering if the overlay isn't visible + if (!vr::VROverlay() || !vr::VROverlay()->IsOverlayVisible(m_ulOverlayHandle) && !vr::VROverlay()->IsOverlayVisible(m_ulOverlayThumbnailHandle)) + return; + m_pRenderControl->polishItems(); + m_pRenderControl->sync(); + m_pRenderControl->render(); -#ifndef DEBUG_DESKTOP_WINDOW - m_pRenderControl->polishItems(); - m_pRenderControl->sync(); - m_pRenderControl->render(); - - GLuint unTexture = m_pFbo->texture(); - if (unTexture != 0) { + GLuint unTexture = m_pFbo->texture(); + 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) - vr::Texture_t texture = { (void*)((uint64_t)unTexture), vr::API_OpenGL, vr::ColorSpace_Auto }; + // To avoid any compiler warning because of cast to a larger pointer type (warning C4312 on VC) + vr::Texture_t texture = { (void*)((uint64_t)unTexture), vr::API_OpenGL, vr::ColorSpace_Auto }; #else - vr::Texture_t texture = { (void*)unTexture, vr::API_OpenGL, vr::ColorSpace_Auto }; + vr::Texture_t texture = { (void*)unTexture, vr::API_OpenGL, vr::ColorSpace_Auto }; #endif - vr::VROverlay()->SetOverlayTexture(m_ulOverlayHandle, &texture); + vr::VROverlay()->SetOverlayTexture(m_ulOverlayHandle, &texture); + } + m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise the texture may be empty.*/ } - m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise the texture may be empty.*/ -#endif } @@ -472,6 +471,11 @@ QUrl OverlayController::getVRRuntimePathUrl() { } +bool OverlayController::soundDisabled() { + return noSound; +} + + void OverlayController::showKeyboard(QString existingText, unsigned long userValue) { vr::VROverlay()->ShowKeyboardForOverlay(m_ulOverlayHandle, vr::k_EGamepadTextInputModeNormal, vr::k_EGamepadTextInputLineModeSingleLine, "Advanced Settings Overlay", 1024, existingText.toStdString().c_str(), false, userValue); } diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index 7d4545d..4ab142f 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -31,9 +31,6 @@ #include "tabcontrollers/SettingsTabController.h" -// Show a window on the desktop instead of an overlay in vr -//#define DEBUG_DESKTOP_WINDOW - // application namespace namespace advsettings { @@ -63,6 +60,9 @@ private: QPoint m_ptLastMouse; Qt::MouseButtons m_lastMouseButtons = 0; + bool desktopMode; + bool noSound; + QUrl m_runtimePathUrl; SteamVRTabController steamVRTabController; @@ -74,7 +74,7 @@ private: SettingsTabController settingsTabController; private: - OverlayController() : QObject() {} + OverlayController(bool desktopMode, bool noSound) : QObject(), desktopMode(desktopMode), noSound(noSound) {} public: virtual ~OverlayController(); @@ -95,6 +95,8 @@ public: Q_INVOKABLE QString getVersionString(); Q_INVOKABLE QUrl getVRRuntimePathUrl(); + Q_INVOKABLE bool soundDisabled(); + public slots: void renderOverlay(); void OnRenderRequest(); @@ -111,9 +113,11 @@ private: public: static OverlayController* getInstance() { - if (!singleton) { - singleton.reset(new advsettings::OverlayController()); - } + return singleton.get(); + } + + static OverlayController* createInstance(bool desktopMode, bool noSound) { + singleton.reset(new advsettings::OverlayController(desktopMode, noSound)); return singleton.get(); }