* perf graph overlay/checkbox added * added toggle Chaperone action * toggle chaperone non-functional * fixed chaperone toggle action const to once * Added Proximity Sensor Action back-end, not implemented via logic Until fixed by valve * added default WMR controller profile * formated * formated steamvrtabcontroller.h * fixed un-intended change * fixed audio profile Bug w/ changed devices * fixed name being used as param instead of ID * fixed loop logic in saveAudioProfile * audio profile fix WIP defaults OVR integration * fixed profile Saves, delete logic and mirror logic needed * fixed QML format, added TODO message * Fixed Audio Profile Behavior * fixed qml reference error * audiodeviceselector changed qml * Removed some comments * changed Visibility slider Minimum to 30% (steamVR minimum allowed) * fixed mirror/playback same issue * fixed Audio device refresh bug, removed currently un-used proximity logic (commented out) * removed dead code * fixed Manifest install/un-install behavior * removed un-used param * color overlay in prog * video overlay basic functions added * fixed qml errors * fixed init order error and chaperone min init error * fixed duplicate button id issue, init issue * fixed log call w/ manifest * removed commented log lines
341 lines
12 KiB
C++
341 lines
12 KiB
C++
#include "setup.h"
|
|
|
|
// The default Qt message handler prints to stdout on X11 and to the debugger on
|
|
// Windows. That is borderline useless for us, therefore we create our own
|
|
// message handler.
|
|
void mainQtMessageHandler( QtMsgType type,
|
|
const QMessageLogContext& context,
|
|
const QString& msg )
|
|
{
|
|
// context contains null pointers on release builds. Cast to get rid of
|
|
// unreferenced formal parameter warnings.
|
|
static_cast<void>( context );
|
|
|
|
QByteArray localMsg = msg.toLocal8Bit();
|
|
switch ( type )
|
|
{
|
|
case QtDebugMsg:
|
|
LOG( DEBUG ) << "QTMSGH: " << localMsg.constData();
|
|
break;
|
|
case QtInfoMsg:
|
|
LOG( INFO ) << "QTMSGH: " << localMsg.constData();
|
|
break;
|
|
case QtWarningMsg:
|
|
LOG( WARNING ) << "QTMSGH: " << localMsg.constData();
|
|
break;
|
|
case QtCriticalMsg:
|
|
LOG( ERROR ) << "QTMSGH: " << localMsg.constData();
|
|
break;
|
|
case QtFatalMsg:
|
|
LOG( FATAL ) << "QTMSGH: " << localMsg.constData();
|
|
break;
|
|
}
|
|
}
|
|
|
|
namespace argument
|
|
{
|
|
CommandLineOptions returnCommandLineParser( const MyQApplication& application )
|
|
{
|
|
QCommandLineParser parser;
|
|
|
|
parser.setApplicationDescription(
|
|
"Advanced Settings overlay for SteamVR." );
|
|
parser.addHelpOption();
|
|
parser.addVersionOption();
|
|
|
|
QCommandLineOption desktopMode( k_desktopMode, k_desktopModeDescription );
|
|
parser.addOption( desktopMode );
|
|
|
|
QCommandLineOption forceNoSound( k_forceNoSound,
|
|
k_forceNoSoundDescription );
|
|
parser.addOption( forceNoSound );
|
|
|
|
QCommandLineOption forceNoManifest( k_forceNoManifest,
|
|
k_forceNoManifestDescription );
|
|
parser.addOption( forceNoManifest );
|
|
|
|
QCommandLineOption forceInstallManifest(
|
|
k_forceInstallManifest, k_forceInstallManifestDescription );
|
|
parser.addOption( forceInstallManifest );
|
|
|
|
QCommandLineOption forceRemoveManifest( k_forceRemoveManifest,
|
|
k_forceRemoveManifestDescription );
|
|
parser.addOption( forceRemoveManifest );
|
|
|
|
parser.process( application );
|
|
|
|
const bool desktopModeEnabled = parser.isSet( desktopMode );
|
|
LOG_IF( desktopModeEnabled, INFO ) << "Desktop mode enabled.";
|
|
|
|
const bool forceNoSoundEnabled = parser.isSet( forceNoSound );
|
|
LOG_IF( forceNoSoundEnabled, INFO ) << "Sound effects disabled.";
|
|
|
|
const bool forceNoManifestEnabled = parser.isSet( forceNoManifest );
|
|
LOG_IF( forceNoManifestEnabled, INFO )
|
|
<< "Running without applications manifest.";
|
|
|
|
const bool forceInstallManifestEnabled
|
|
= parser.isSet( forceInstallManifest );
|
|
LOG_IF( forceInstallManifestEnabled, INFO )
|
|
<< "Forcing install of applications manifest.";
|
|
|
|
const bool forceRemoveManifestEnabled = parser.isSet( forceRemoveManifest );
|
|
LOG_IF( forceRemoveManifestEnabled, INFO )
|
|
<< "Forcing removal of applications manifest.";
|
|
|
|
const CommandLineOptions commandLineArgs{ desktopModeEnabled,
|
|
forceNoSoundEnabled,
|
|
forceNoManifestEnabled,
|
|
forceInstallManifestEnabled,
|
|
forceRemoveManifestEnabled };
|
|
|
|
LOG( INFO ) << "Command line arguments processed.";
|
|
|
|
return commandLineArgs;
|
|
}
|
|
} // namespace argument
|
|
|
|
namespace manifest
|
|
{
|
|
// Enables autostart of OpenVR Advanced Settings.
|
|
void enableApplicationAutostart()
|
|
{
|
|
const auto app_error = vr::VRApplications()->SetApplicationAutoLaunch(
|
|
application_strings::applicationKey, true );
|
|
if ( app_error != vr::VRApplicationError_None )
|
|
{
|
|
throw std::runtime_error(
|
|
std::string( "Could not set auto start: " )
|
|
+ std::string(
|
|
vr::VRApplications()->GetApplicationsErrorNameFromEnum(
|
|
app_error ) ) );
|
|
}
|
|
}
|
|
|
|
// Installs the application manifest. If a manifest with the same application
|
|
// key is already installed, nothing will happen.
|
|
// OpenVR must be initialized before calling this function.
|
|
void installApplicationManifest( const std::string manifestPath )
|
|
{
|
|
if ( vr::VRApplications()->IsApplicationInstalled(
|
|
application_strings::applicationKey ) )
|
|
{
|
|
LOG( INFO ) << "Manifest Is already Installed for Key "
|
|
<< application_strings::applicationKey;
|
|
}
|
|
else
|
|
{
|
|
const auto app_error = vr::VRApplications()->AddApplicationManifest(
|
|
manifestPath.c_str() );
|
|
LOG( INFO ) << "Manifest Installed at: " << manifestPath;
|
|
if ( app_error != vr::VRApplicationError_None )
|
|
{
|
|
throw std::runtime_error(
|
|
std::string( "Could not add application manifest: " )
|
|
+ std::string(
|
|
vr::VRApplications()->GetApplicationsErrorNameFromEnum(
|
|
app_error ) ) );
|
|
}
|
|
vr::VRSettings()->Sync( true );
|
|
}
|
|
}
|
|
|
|
// Removes the application manifest.
|
|
void removeApplicationManifest( const std::string manifestPath )
|
|
{
|
|
if ( vr::VRApplications()->IsApplicationInstalled(
|
|
application_strings::applicationKey ) )
|
|
{
|
|
vr::VRApplications()->RemoveApplicationManifest( manifestPath.c_str() );
|
|
LOG( INFO ) << "Attempting to Remove Manifest At: " << manifestPath;
|
|
vr::VRSettings()->Sync( true );
|
|
}
|
|
if ( vr::VRApplications()->IsApplicationInstalled(
|
|
application_strings::applicationKey ) )
|
|
{
|
|
LOG( ERROR ) << "Removal Failed, run Advanced Settings from previous "
|
|
"install directory OR manually delete it in Steam "
|
|
"install at Steam\\config\\appconfig.json";
|
|
}
|
|
else
|
|
{
|
|
LOG( INFO ) << "Manifest Removed Successfully";
|
|
}
|
|
}
|
|
|
|
// Removes and then installs the application manifest.
|
|
void reinstallApplicationManifest( const std::string manifestPath )
|
|
{
|
|
if ( vr::VRApplications()->IsApplicationInstalled(
|
|
application_strings::applicationKey ) )
|
|
{
|
|
LOG( INFO ) << "Manifest Previously Installed";
|
|
// String size was arbitrarily chosen by original author.
|
|
constexpr auto kStringSize = 1024;
|
|
char oldApplicationWorkingDir[kStringSize] = { 0 };
|
|
auto app_error = vr::VRApplicationError_None;
|
|
vr::VRApplications()->GetApplicationPropertyString(
|
|
application_strings::applicationKey,
|
|
vr::VRApplicationProperty_WorkingDirectory_String,
|
|
oldApplicationWorkingDir,
|
|
kStringSize,
|
|
&app_error );
|
|
|
|
if ( app_error != vr::VRApplicationError_None )
|
|
{
|
|
throw std::runtime_error(
|
|
"Could not find working directory of already "
|
|
"installed application: "
|
|
+ std::string(
|
|
vr::VRApplications()->GetApplicationsErrorNameFromEnum(
|
|
app_error ) ) );
|
|
}
|
|
|
|
const auto oldManifestPath
|
|
= QDir::toNativeSeparators(
|
|
QDir::cleanPath( QDir( oldApplicationWorkingDir )
|
|
.absoluteFilePath( kVRManifestName ) ) )
|
|
.toStdString();
|
|
removeApplicationManifest( oldManifestPath );
|
|
}
|
|
|
|
installApplicationManifest( manifestPath );
|
|
}
|
|
|
|
void forceRemoveApplicationManifest()
|
|
{
|
|
if ( vr::VRApplications()->IsApplicationInstalled(
|
|
application_strings::applicationKey ) )
|
|
{
|
|
// String size was arbitrarily chosen by original author.
|
|
constexpr auto kStringSize = 1024;
|
|
char oldApplicationWorkingDir[kStringSize] = { 0 };
|
|
auto app_error = vr::VRApplicationError_None;
|
|
vr::VRApplications()->GetApplicationPropertyString(
|
|
application_strings::applicationKey,
|
|
vr::VRApplicationProperty_WorkingDirectory_String,
|
|
oldApplicationWorkingDir,
|
|
kStringSize,
|
|
&app_error );
|
|
|
|
if ( app_error != vr::VRApplicationError_None )
|
|
{
|
|
throw std::runtime_error(
|
|
"Could not find working directory of already "
|
|
"installed application: "
|
|
+ std::string(
|
|
vr::VRApplications()->GetApplicationsErrorNameFromEnum(
|
|
app_error ) ) );
|
|
}
|
|
|
|
const auto oldManifestPath
|
|
= QDir::toNativeSeparators(
|
|
QDir::cleanPath( QDir( oldApplicationWorkingDir )
|
|
.absoluteFilePath( kVRManifestName ) ) )
|
|
.toStdString();
|
|
removeApplicationManifest( oldManifestPath );
|
|
}
|
|
else
|
|
{
|
|
LOG( INFO ) << "No Manifest Installed";
|
|
}
|
|
}
|
|
|
|
// Initializes OpenVR and calls the relevant manifest functions.
|
|
// The .vrmanifest is used by SteamVR however the exact functiontionality is not
|
|
// documented in the official documentation.
|
|
// The manifest is installed upon using the NSIS installer for windows (this
|
|
// program is called with "--force-install-manifest" by the installer) and every
|
|
// time the program is launched without both "--desktop-mode" and
|
|
// "--force-no-manifest". The OpenVR initialization is necessary for both
|
|
// removing and installing manifests.
|
|
[[noreturn]] void handleManifests( const bool installManifest,
|
|
const bool removeManifest )
|
|
{
|
|
openvr_init::initializeOpenVR(
|
|
openvr_init::OpenVrInitializationType::Utility );
|
|
|
|
int exit_code = ReturnErrorCode::SUCCESS;
|
|
try
|
|
{
|
|
const auto manifestPath
|
|
= paths::binaryDirectoryFindFile( manifest::kVRManifestName );
|
|
|
|
if ( !manifestPath.has_value() )
|
|
{
|
|
throw std::runtime_error( "Could not find application manifest." );
|
|
}
|
|
// Keep Settings Clean
|
|
vr::VRSettings()->Sync( true );
|
|
if ( installManifest )
|
|
{
|
|
reinstallApplicationManifest( *manifestPath );
|
|
enableApplicationAutostart();
|
|
LOG( INFO ) << "Manifest reinstalled.";
|
|
}
|
|
else if ( removeManifest )
|
|
{
|
|
forceRemoveApplicationManifest();
|
|
LOG( INFO ) << "Manifest removed.";
|
|
}
|
|
}
|
|
catch ( std::exception& e )
|
|
{
|
|
exit_code = ReturnErrorCode::GENERAL_FAILURE;
|
|
LOG( ERROR ) << e.what();
|
|
}
|
|
|
|
vr::VR_Shutdown();
|
|
exit( exit_code );
|
|
}
|
|
} // namespace manifest
|
|
|
|
void setUpLogging()
|
|
{
|
|
el::Loggers::addFlag( el::LoggingFlag::DisableApplicationAbortOnFatalLog );
|
|
|
|
el::Configurations conf;
|
|
conf.setToDefault();
|
|
|
|
using el::ConfigurationType;
|
|
using el::Level;
|
|
|
|
conf.set( Level::Global,
|
|
ConfigurationType::Format,
|
|
"[%level] %datetime{%Y-%M-%d %H:%m:%s}: %msg" );
|
|
constexpr auto logFileName = "AdvancedSettings.log";
|
|
conf.set( Level::Global, ConfigurationType::Filename, logFileName );
|
|
|
|
constexpr auto confEnabled = "true";
|
|
conf.set( Level::Global, ConfigurationType::Enabled, confEnabled );
|
|
conf.set( Level::Global, ConfigurationType::ToFile, confEnabled );
|
|
conf.set( Level::Global, ConfigurationType::ToStandardOutput, confEnabled );
|
|
|
|
constexpr auto TwoMegabytesInBytes = "2097152";
|
|
conf.set(
|
|
Level::Global, ConfigurationType::MaxLogFileSize, TwoMegabytesInBytes );
|
|
|
|
constexpr auto confDisabled = "false";
|
|
conf.set( Level::Trace, ConfigurationType::Enabled, confDisabled );
|
|
conf.set( Level::Debug, ConfigurationType::Enabled, confDisabled );
|
|
|
|
const auto appDataLocation
|
|
= std::string( "/" ) + application_strings::applicationOrganizationName
|
|
+ "/";
|
|
const auto logFilePath
|
|
= QDir( QString::fromStdString( *paths::settingsDirectory() )
|
|
+ appDataLocation.c_str() )
|
|
.absoluteFilePath( logFileName );
|
|
conf.set( el::Level::Global,
|
|
el::ConfigurationType::Filename,
|
|
QDir::toNativeSeparators( logFilePath ).toStdString() );
|
|
|
|
conf.setRemainingToDefault();
|
|
|
|
el::Loggers::reconfigureAllLoggers( conf );
|
|
|
|
LOG( INFO ) << "Application started (Version "
|
|
<< application_strings::applicationVersionString << ")";
|
|
LOG( INFO ) << "Log File: " << logFilePath;
|
|
}
|