Files
OpenVR-AdvancedSettings-frame/src/main.cpp
T
Matthias JanetschekandClaude Opus 5.5 b22c35ae29 Manifest for Linux; connect as Background app where Utility is refused
- manifest.vrmanifest: binary_path_linux and binary_path_linux_arm. The
  Steam Frame's SteamVR reads only binary_path_linux_arm.
- handleManifests(): connect as Utility app first (works without a running
  SteamVR, e.g. from the Windows installer); if SteamVR refuses Utility apps,
  as on the Steam Frame, connect as Background app. Fail right away on other
  errors instead of going through initializeOpenVR()'s retry loop.
- main(): check --graphics-api before connecting to OpenVR, so a wrong value
  fails right away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:42:16 +02:00

169 lines
6.2 KiB
C++

#include "utils/setup.h"
#include "settings/settings.h"
#include "openvr/ovr_settings_wrapper.h"
#include "render/RenderBackend.h"
#include <QtLogging>
#include <QtDebug>
#include <memory>
#ifdef _WIN64
# include <windows.h>
extern "C" __declspec( dllexport ) DWORD NvOptimusEnablement = 0x00000001;
extern "C" __declspec( dllexport ) DWORD AmdPowerXpressRequestHighPerformance
= 0x00000001;
#endif
int main( int argc, char* argv[] )
{
setUpLogging();
qInfo() << "Settings File: " << settings::initializeAndGetSettingsPath();
qInfo() << settings::getSettingsAndValues();
QCoreApplication::setAttribute( Qt::AA_Use96Dpi );
QCoreApplication::setAttribute( Qt::AA_UseDesktopOpenGL );
MyQApplication mainEventLoop( argc, argv );
mainEventLoop.setOrganizationName(
application_strings::applicationOrganizationName );
mainEventLoop.setApplicationName( application_strings::applicationName );
mainEventLoop.setApplicationDisplayName(
application_strings::applicationDisplayName );
mainEventLoop.setApplicationVersion(
application_strings::applicationVersionString );
const auto commandLineArgs
= argument::returnCommandLineParser( mainEventLoop );
// It is important that either install_manifest or remove_manifest are true,
// otherwise the handleManifests function will not behave properly.
if ( commandLineArgs.forceInstallManifest
|| commandLineArgs.forceRemoveManifest )
{
manifest::handleManifests( commandLineArgs.forceInstallManifest,
commandLineArgs.forceRemoveManifest );
}
// Render backend (render/RenderBackend.h). Chosen before connecting to
// OpenVR, so a wrong --graphics-api fails right away.
GraphicsApi graphicsApi = GraphicsApi::OpenGL;
if ( !parseGraphicsApi( commandLineArgs.graphicsApi, &graphicsApi ) )
{
qCritical() << "Unknown graphics API:" << commandLineArgs.graphicsApi
<< "(expected opengl or vulkan)";
return ReturnErrorCode::GENERAL_FAILURE;
}
std::unique_ptr<RenderBackend> renderBackend
= createRenderBackend( graphicsApi );
if ( !renderBackend )
{
qCritical() << "Graphics API" << commandLineArgs.graphicsApi
<< "is not compiled into this build";
return ReturnErrorCode::GENERAL_FAILURE;
}
openvr_init::initializeOpenVR(
openvr_init::OpenVrInitializationType::Overlay );
// Initialized after OpenVR, because the Vulkan backend needs SteamVR's
// device requirements (openvr_init::renderInterop()), and before
// OverlayController, because QQuickWindow::setGraphicsApi() must run
// before any QQuickWindow exists (OverlayController owns one).
QString renderBackendError;
if ( !renderBackend->initialize( openvr_init::renderInterop(),
&renderBackendError ) )
{
qCritical() << renderBackend->name()
<< "initialization failed:" << renderBackendError;
return ReturnErrorCode::GENERAL_FAILURE;
}
QQuickWindow::setGraphicsApi( renderBackend->graphicsApi() );
try
{
QQmlEngine qmlEngine;
// Just error checking to ensure QRC works properly
qDebug() << "list of qmldirs";
QDirIterator it( ":", QDirIterator::Subdirectories );
while ( it.hasNext() )
{
qDebug() << it.next();
}
std::unique_ptr<advsettings::OverlayController> controller(
new advsettings::OverlayController( commandLineArgs.desktopMode,
commandLineArgs.forceNoSound,
qmlEngine,
std::move( renderBackend ) ) );
//const auto url
// = QUrl( ":/qt/qml/AdvancedSettings/src/res/qml/common/mainwidget.qml" );
QQmlComponent component( &qmlEngine, ":/qt/qml/AdvancedSettings/src/res/qml/common/mainwidget.qml" );
auto errors = component.errors();
for ( auto& e : errors )
{
qCritical() << "QML Error: "
<< e.toString().toStdString(); //<< std::endl;
}
auto quickObj = component.create();
controller->SetWidget( qobject_cast<QQuickItem*>( quickObj ),
application_strings::applicationDisplayName,
application_strings::applicationKey );
// Attempts to install the application manifest on all "regular" starts.
if ( !commandLineArgs.forceNoManifest )
{
try
{
const auto manifestPath = paths::binaryDirectoryFindFile(
manifest::kVRManifestName );
if ( !manifestPath.has_value() )
{
throw std::runtime_error(
"Could not find applications manifest." );
}
else
{
manifest::installApplicationManifest( *manifestPath );
}
}
catch ( std::exception& e )
{
qCritical() << e.what();
}
}
if ( commandLineArgs.desktopMode
|| settings::getSetting(
settings::BoolSetting::APPLICATION_desktopModeToggle ) )
{
//TODO TEMP
//qDebug() << "Desktop MODE!";
//auto m_pWindow = new QQuickWindow();
//qobject_cast<QQuickItem*>( quickObj )
// ->setParentItem( m_pWindow->contentItem() );
//m_pWindow->setGeometry(
// 0,
// 0,
// static_cast<int>(
// qobject_cast<QQuickItem*>( quickObj )->width() ),
// static_cast<int>(
// qobject_cast<QQuickItem*>( quickObj )->height() ) );
//m_pWindow->show();
}
if ( commandLineArgs.resetSettings )
{
// resets all settings if called
ovr_settings_wrapper::resetAllSettings();
}
return mainEventLoop.exec();
}
catch ( const std::exception& e )
{
qFatal() << e.what();
return ReturnErrorCode::GENERAL_FAILURE;
}
}