diff --git a/appveyor.yml b/.appveyor.yml similarity index 76% rename from appveyor.yml rename to .appveyor.yml index 2f9978d..be21d1e 100644 --- a/appveyor.yml +++ b/.appveyor.yml @@ -7,6 +7,7 @@ environment: JOM_LOC: '"C:\Qt\Tools\QtCreator\bin\jom.exe"' NSIS_LOC: '"C:\Program Files (x86)\NSIS\"' ZIP_LOC: 7z + CLANG_FORMAT_LOC: '"C:\Program Files\LLVM\bin\clang-format.exe"' COMPILER: msvc VSVER: 14 @@ -17,6 +18,7 @@ init: - set TAG_NAME=%APPVEYOR_REPO_TAG_NAME% build_script: + - python ./build_scripts/run-clang-format.py ./src -r --clang-format-executable %CLANG_FORMAT_LOC% --color always - call "build_windows.cmd" artifacts: diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..b0ce293 --- /dev/null +++ b/.clang-format @@ -0,0 +1,105 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Allman +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 1 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 2 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: true +SpacesInParentheses: true +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... + diff --git a/.travis.yml b/.travis.yml index 98504bb..1223fc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ install: - sudo apt-get install build-essential qtbase5-dev qttools5-dev qtdeclarative5-dev qtmultimedia5-dev qt5-default qttools5-dev-tools script: + - python ./build_scripts/run-clang-format.py ./src -r --color always - mkdir build && cd build - qmake .. - make diff --git a/Readme.md b/Readme.md index eb5a805..49e6c7b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,7 @@ - -![language](https://img.shields.io/badge/Language-C%2B%2B11%2C%20QML-green.svg) ![dependencies](https://img.shields.io/badge/Dependencies-OpenVR%2C%20Qt5-green.svg) ![license_gpl3](https://img.shields.io/badge/License-GPL%203.0-green.svg) [![Build status](https://ci.appveyor.com/api/projects/status/8oivf5xws6vsq2x3/branch/master?svg=true)](https://ci.appveyor.com/project/icewind1991/openvr-advancedsettings/branch/master) +![language](https://img.shields.io/badge/Language-C%2B%2B11%2C%20QML-green.svg) ![dependencies](https://img.shields.io/badge/Dependencies-OpenVR%2C%20Qt5-green.svg) +![license_gpl3](https://img.shields.io/badge/License-GPL%203.0-green.svg) +[![Build status](https://ci.appveyor.com/api/projects/status/8oivf5xws6vsq2x3/branch/master?svg=true)](https://ci.appveyor.com/project/icewind1991/openvr-advancedsettings/branch/master) +[![Build Status](https://travis-ci.org/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings.svg?branch=master)](https://travis-ci.org/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings) > * [Features](#features) > * [Usage](#usage) @@ -272,6 +274,8 @@ Full build instructions can be found [here](docs/building_for_windows.md). If you want to run Advanced Settings on linux you can build it yourself using `qmake` and `make` or using Qt Creator, you'll have to copy the `res` folder from the `src` folder into folder that contains the binary and copy `third-party/openvr/lib/linux64/libopenvr_api.so` into your systems library path. +If you want to contribute changes running `clang-format` is necessary. More details are in the [CONTRIBUTING.md](docs/CONTRIBUTING.md) file. + # Notes: diff --git a/build_scripts/linux/format b/build_scripts/linux/format new file mode 100755 index 0000000..36f978c --- /dev/null +++ b/build_scripts/linux/format @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +clang-format --version + +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: {}" \; + echo "DONE" +else + echo "Could not find clang-format." +fi + diff --git a/build_scripts/linux/verify_formatting b/build_scripts/linux/verify_formatting new file mode 100755 index 0000000..8ddd177 --- /dev/null +++ b/build_scripts/linux/verify_formatting @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +clang-format --version; + +if [ $? -eq 0 ]; then + echo "Clang-format found." + build_path="`dirname \"$0\"`" + project_path=$build_path/../.. + + python $project_path/build_scripts/run-clang-format.py $project_path/src -r --color always; + if [ $? -eq 0 ]; then + echo "FORMATTED CORRECTLY." + else + echo "NOT FORMATTED CORRECTLY." + fi +else + echo "Could not find clang-format." +fi + diff --git a/build_scripts/run-clang-format.py b/build_scripts/run-clang-format.py new file mode 100644 index 0000000..3d0cca0 --- /dev/null +++ b/build_scripts/run-clang-format.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python +"""A wrapper script around clang-format, suitable for linting multiple files +and to use for continuous integration. + +This is an alternative API for the clang-format command line. +It runs over multiple files and directories in parallel. +A diff output is produced and a sensible exit code is returned. + +""" + +from __future__ import print_function, unicode_literals + +import argparse +import codecs +import difflib +import fnmatch +import io +import multiprocessing +import os +import signal +import subprocess +import sys +import traceback + +from functools import partial + +DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx' + + +class ExitStatus: + SUCCESS = 0 + DIFF = 1 + TROUBLE = 2 + + +def list_files(files, recursive=False, extensions=None, exclude=None): + if extensions is None: + extensions = [] + if exclude is None: + exclude = [] + + out = [] + for file in files: + if recursive and os.path.isdir(file): + for dirpath, dnames, fnames in os.walk(file): + fpaths = [os.path.join(dirpath, fname) for fname in fnames] + for pattern in exclude: + # os.walk() supports trimming down the dnames list + # by modifying it in-place, + # to avoid unnecessary directory listings. + dnames[:] = [ + x for x in dnames + if + not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) + ] + fpaths = [ + x for x in fpaths if not fnmatch.fnmatch(x, pattern) + ] + for f in fpaths: + ext = os.path.splitext(f)[1][1:] + if ext in extensions: + out.append(f) + else: + out.append(file) + return out + + +def make_diff(file, original, reformatted): + return list( + difflib.unified_diff( + original, + reformatted, + fromfile='{}\t(original)'.format(file), + tofile='{}\t(reformatted)'.format(file), + n=3)) + + +class DiffError(Exception): + def __init__(self, message, errs=None): + super(DiffError, self).__init__(message) + self.errs = errs or [] + + +class UnexpectedError(Exception): + def __init__(self, message, exc=None): + super(UnexpectedError, self).__init__(message) + self.formatted_traceback = traceback.format_exc() + self.exc = exc + + +def run_clang_format_diff_wrapper(args, file): + try: + ret = run_clang_format_diff(args, file) + return ret + except DiffError: + raise + except Exception as e: + raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__, + e), e) + + +def run_clang_format_diff(args, file): + try: + with io.open(file, 'r', encoding='utf-8') as f: + original = f.readlines() + except IOError as exc: + raise DiffError(str(exc)) + invocation = [args.clang_format_executable, file] + + # Use of utf-8 to decode the process output. + # + # Hopefully, this is the correct thing to do. + # + # It's done due to the following assumptions (which may be incorrect): + # - clang-format will returns the bytes read from the files as-is, + # without conversion, and it is already assumed that the files use utf-8. + # - if the diagnostics were internationalized, they would use utf-8: + # > Adding Translations to Clang + # > + # > Not possible yet! + # > Diagnostic strings should be written in UTF-8, + # > the client can translate to the relevant code page if needed. + # > Each translation completely replaces the format string + # > for the diagnostic. + # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation + # + # It's not pretty, due to Python 2 & 3 compatibility. + encoding_py3 = {} + if sys.version_info[0] >= 3: + encoding_py3['encoding'] = 'utf-8' + + try: + proc = subprocess.Popen( + invocation, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + **encoding_py3) + except OSError as exc: + raise DiffError(str(exc)) + proc_stdout = proc.stdout + proc_stderr = proc.stderr + if sys.version_info[0] < 3: + # make the pipes compatible with Python 3, + # reading lines should output unicode + encoding = 'utf-8' + proc_stdout = codecs.getreader(encoding)(proc_stdout) + proc_stderr = codecs.getreader(encoding)(proc_stderr) + # hopefully the stderr pipe won't get full and block the process + outs = list(proc_stdout.readlines()) + errs = list(proc_stderr.readlines()) + proc.wait() + if proc.returncode: + raise DiffError("clang-format exited with status {}: '{}'".format( + proc.returncode, file), errs) + return make_diff(file, original, outs), errs + + +def bold_red(s): + return '\x1b[1m\x1b[31m' + s + '\x1b[0m' + + +def colorize(diff_lines): + def bold(s): + return '\x1b[1m' + s + '\x1b[0m' + + def cyan(s): + return '\x1b[36m' + s + '\x1b[0m' + + def green(s): + return '\x1b[32m' + s + '\x1b[0m' + + def red(s): + return '\x1b[31m' + s + '\x1b[0m' + + for line in diff_lines: + if line[:4] in ['--- ', '+++ ']: + yield bold(line) + elif line.startswith('@@ '): + yield cyan(line) + elif line.startswith('+'): + yield green(line) + elif line.startswith('-'): + yield red(line) + else: + yield line + + +def print_diff(diff_lines, use_color): + if use_color: + diff_lines = colorize(diff_lines) + if sys.version_info[0] < 3: + sys.stdout.writelines((l.encode('utf-8') for l in diff_lines)) + else: + sys.stdout.writelines(diff_lines) + + +def print_trouble(prog, message, use_colors): + error_text = 'error:' + if use_colors: + error_text = bold_red(error_text) + print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--clang-format-executable', + metavar='EXECUTABLE', + help='path to the clang-format executable', + default='clang-format') + parser.add_argument( + '--extensions', + help='comma separated list of file extensions (default: {})'.format( + DEFAULT_EXTENSIONS), + default=DEFAULT_EXTENSIONS) + parser.add_argument( + '-r', + '--recursive', + action='store_true', + help='run recursively over directories') + parser.add_argument('files', metavar='file', nargs='+') + parser.add_argument( + '-q', + '--quiet', + action='store_true') + parser.add_argument( + '-j', + metavar='N', + type=int, + default=0, + help='run N clang-format jobs in parallel' + ' (default number of cpus + 1)') + parser.add_argument( + '--color', + default='auto', + choices=['auto', 'always', 'never'], + help='show colored diff (default: auto)') + parser.add_argument( + '-e', + '--exclude', + metavar='PATTERN', + action='append', + default=[], + help='exclude paths matching the given glob-like pattern(s)' + ' from recursive search') + + args = parser.parse_args() + + # use default signal handling, like diff return SIGINT value on ^C + # https://bugs.python.org/issue14229#msg156446 + signal.signal(signal.SIGINT, signal.SIG_DFL) + try: + signal.SIGPIPE + except AttributeError: + # compatibility, SIGPIPE does not exist on Windows + pass + else: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + colored_stdout = False + colored_stderr = False + if args.color == 'always': + colored_stdout = True + colored_stderr = True + elif args.color == 'auto': + colored_stdout = sys.stdout.isatty() + colored_stderr = sys.stderr.isatty() + + retcode = ExitStatus.SUCCESS + files = list_files( + args.files, + recursive=args.recursive, + exclude=args.exclude, + extensions=args.extensions.split(',')) + + if not files: + return + + njobs = args.j + if njobs == 0: + njobs = multiprocessing.cpu_count() + 1 + njobs = min(len(files), njobs) + + if njobs == 1: + # execute directly instead of in a pool, + # less overhead, simpler stacktraces + it = (run_clang_format_diff_wrapper(args, file) for file in files) + pool = None + else: + pool = multiprocessing.Pool(njobs) + it = pool.imap_unordered( + partial(run_clang_format_diff_wrapper, args), files) + while True: + try: + outs, errs = next(it) + except StopIteration: + break + except DiffError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + retcode = ExitStatus.TROUBLE + sys.stderr.writelines(e.errs) + except UnexpectedError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + sys.stderr.write(e.formatted_traceback) + retcode = ExitStatus.TROUBLE + # stop at the first unexpected error, + # something could be very wrong, + # don't process all files unnecessarily + if pool: + pool.terminate() + break + else: + sys.stderr.writelines(errs) + if outs == []: + continue + if not args.quiet: + print_diff(outs, use_color=colored_stdout) + if retcode == ExitStatus.SUCCESS: + retcode = ExitStatus.DIFF + return retcode + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/build_scripts/win/format.cmd b/build_scripts/win/format.cmd new file mode 100644 index 0000000..ac87b88 --- /dev/null +++ b/build_scripts/win/format.cmd @@ -0,0 +1,60 @@ +@echo off +REM Echo off to avoid spam. + +REM Non zero is failure, 0 is success. +SET exit_code_success=0 +SET exit_code_failure_build_apps=1 +SET exit_code_failure_build_locations=2 + +REM Used for echos. +SET current_activity=FORMAT + +REM If scripts are chain called the original dirs should not be overwritten. +IF NOT DEFINED original_dir ( + SET original_dir=%CD% +) +IF NOT DEFINED project_dir ( + REM Arg 0 (called %0) is the full path to the file. + REM https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/call#batch-parameters + REM As per above link, %~dp0 expands the zeroth arg to a drive letter and path only. + REM Project dir is up two dirs from the file. + SET project_dir=%~dp0\..\..\ +) + +ECHO %current_activity%: Testing if clang-format can be located: + +IF NOT DEFINED CLANG_FORMAT_LOC ( + ECHO %current_activity%: CLANG_FORMAT_LOC not defined. Using default value. + SET CLANG_FORMAT_LOC="C:\Program Files\LLVM\bin\clang-format.exe" +) +ECHO %current_activity%: CLANG_FORMAT_LOC set to '%CLANG_FORMAT_LOC%'. + +REM EXIST won't find items in the PATH. WHERE will. +SET CLANG_FORMAT_VALID=0 +IF EXIST %CLANG_FORMAT_LOC% SET CLANG_FORMAT_VALID=1 +IF %CLANG_FORMAT_VALID% EQU 0 ( + WHERE /Q %CLANG_FORMAT_LOC% + IF NOT ERRORLEVEL 1 SET CLANG_FORMAT_VALID=1 +) + +IF %CLANG_FORMAT_VALID% EQU 1 ( + ECHO %current_activity%: CLANG_FORMAT_LOC exists. +) ELSE ( + ECHO %current_activity%: CLANG_FORMAT_LOC directory does not exist. Exiting. + EXIT /B %exit_code_failure_build_locations% +) + +ECHO %current_activity%: Clang-format located. + +%CLANG_FORMAT_LOC% --version + +REM First iteration. +FOR /R %project_dir%\src\ %%F IN (*.cpp *.h) DO (%CLANG_FORMAT_LOC% --style=file -i %%F & ECHO Iteration 1. %%F) + +REM Clang-format is sometimes indecisive about which exact rules to apply, +REM leading to differences between first and second iteration. +REM Do it twice, just to be sure. + +FOR /R %project_dir%\src\ %%F IN (*.cpp *.h) DO (%CLANG_FORMAT_LOC% --style=file -i %%F & ECHO Iteration 2. %%F) + +ECHO %current_activity%: %current_activity% DONE. diff --git a/build_scripts/win/verify_formatting.cmd b/build_scripts/win/verify_formatting.cmd new file mode 100644 index 0000000..997643d --- /dev/null +++ b/build_scripts/win/verify_formatting.cmd @@ -0,0 +1,40 @@ +@echo off +REM Arg 0 (called %0) is the full path to the file. +REM https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/call#batch-parameters +REM As per above link, %~dp0 expands the zeroth arg to a drive letter and path only. +REM Project dir is up two dirs from the file. +SET project_dir=%~dp0\..\..\ + +ECHO %current_activity%: Testing if clang-format can be located: + +IF NOT DEFINED CLANG_FORMAT_LOC ( + ECHO %current_activity%: CLANG_FORMAT_LOC not defined. Using default value. + SET CLANG_FORMAT_LOC="C:\Program Files\LLVM\bin\clang-format.exe" +) +ECHO %current_activity%: CLANG_FORMAT_LOC set to '%CLANG_FORMAT_LOC%'. + +REM EXIST won't find items in the PATH. WHERE will. +SET CLANG_FORMAT_VALID=0 +IF EXIST %CLANG_FORMAT_LOC% SET CLANG_FORMAT_VALID=1 +IF %CLANG_FORMAT_VALID% EQU 0 ( + WHERE /Q %CLANG_FORMAT_LOC% + IF NOT ERRORLEVEL 1 SET CLANG_FORMAT_VALID=1 +) + +IF %CLANG_FORMAT_VALID% EQU 1 ( + ECHO %current_activity%: CLANG_FORMAT_LOC exists. +) ELSE ( + ECHO %current_activity%: CLANG_FORMAT_LOC directory does not exist. Exiting. + EXIT /B %exit_code_failure_build_locations% +) + +ECHO %current_activity%: Clang-format located. + +%CLANG_FORMAT_LOC% --version + +python %project_dir%/build_scripts/run-clang-format.py %project_dir%/src -r --color never --clang-format-executable %CLANG_FORMAT_LOC% +IF NOT ERRORLEVEL 1 ( + ECHO FORMATTED CORRECTLY. +) ELSE ( + ECHO NOT FORMATTED CORRECTLY. +) \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000..07bc064 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,49 @@ + +# How to contribute to OpenVR Advanced Settings + + > * [You found a bug or have a suggestion for improvement](#bug_improvement) + > * [You wrote a patch](#patch) + > * [Building](#building) + > * [Formatting](#formatting) + > * [Style guide](#style) + + +## You found a bug or have a suggestion for improvement + +First, look through the [issues page](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/issues) and see if there are any open issues relevant to yours. If there are, describe your issue in detail and why you think it's relevant to the already open issue. + +If there aren't any open issues relevant to yours, create a new issue and give as much detail as possible. + +For bug reports include what you expect to happen, what happened, version number of the application, operating system, SteamVR version number (if possible) and any other information you find relevant. + +For improvement requests include what you're expecting to do, why you want the feature this way, the problem that you're solving and any other information that you find relevant. + +Include logs if possible. Logs can be found in `%APPDATA%\matzman666\OpenVRAdvancedSettings\AdvancedSettings.log` on Windows. + + +## You want to submit changes + + +### Building + +If you haven't already, read the instructions for how to build on [Windows](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/tree/master#building_on_windows) or [Linux](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/tree/master#building_on_linux). Your patch must build on all platforms without errors (warnings are treated as errors). Notice that different compilers have different warning messages, being able to successfully compile on one does not mean that all of them will pass. The pull request will be built on both Windows (msvc) and Linux (gcc and clang) CI servers. + + +### Formatting + +This project uses `clang-format` (part of the [LLVM collection](https://releases.llvm.org/download.html)) on all `*.cpp`and `*.h` files in the `src` directory, using the supplied `.clang-format` file in the root of the repository. Correct formatting is checked by the CI servers. + +The `.\build_scripts\win\format.cmd` (for Windows) and `./build_scripts/linux/format` (for Linux) scripts will automatically run `clang-format` on all required files. + +The Windows script requires that either your `clang-format.exe` is in `C:\Program Files\LLVM\bin\clang-format.exe` or the `CLANG_FORMAT_LOC` environment variable is set to the location of the `.exe`. + +The Linux script requires that `clang-format` is in your `path`. + +There are `clang-format` plugins for many IDEs, including [Qt Creator](https://doc.qt.io/qtcreator/creator-beautifier.html) and [Visual Studio](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat). + +To verify that your patch has been formatted correctly, run `.\build_scripts\win\verify_formatting.cmd` on Windows or `./build_scripts/linux/verify_formatting` on Linux. If there are formatting changes needed the script will output a diff showing which changes are needed, otherwise it will output `FORMATTED CORRECTLY.`. The verification script requires `python` in the `path` for Linux and Windows. On Windows the verification script will either use the `CLANG_FORMAT_LOC` environment variable or the default location. + + +### Style guide + +Currently, there are no directives for style other than `clang-format`. \ No newline at end of file diff --git a/docs/building_for_windows.md b/docs/building_for_windows.md index 960d5ba..09db855 100644 --- a/docs/building_for_windows.md +++ b/docs/building_for_windows.md @@ -4,6 +4,7 @@ > * [Requirements](#requirements) > * [Locations and Environment Variables](#locs_and_envs) > * [Building](#features) + > * [Contributing](#contributing) > * [Using with QtCreator](#qt_creator) > * [Using with Visual Studio](#visual_studio) @@ -12,12 +13,18 @@ For compiling: -1. Microsoft Visual Studio (tested on 2017 Community) -2. Qt Framework (tested on 5.10 and 5.11) +1. [Microsoft Visual Studio](https://visualstudio.microsoft.com/downloads/) (tested on 2017 Community) +2. [Qt Framework](https://www.qt.io/download) version later than 5.6 (tested on 5.10 and 5.11) + +For pushing changes to the repo: + +1. [Python 3](https://www.python.org/downloads/) (must be in `PATH` environment variable) + +2. Clang format. Part of the [LLVM collection](https://releases.llvm.org/download.html). Additionally, for fully building portable and installer release versions: -3. 7zip -4. Nullsoft Scriptable Install System (NSIS) +3. [7zip](https://www.7-zip.org/download.html) +4. [Nullsoft Scriptable Install System (NSIS)](https://sourceforge.net/projects/nsis/) ## Locations and Environment Variables @@ -28,9 +35,10 @@ The following environmental variables are relevant for building the project. | -------------------- | ------------- | | `QT_LOC` | Path to your Qt `\bin\` folder. | | `VS_LOC` | Path to your Visual Studio `vcvarsall.bat` file. | -| `JOM_LOC` | Path to an `.exe` of `jom.exe`. Usually installed with Qt. `jom` is a wrapper around `nmake` allowing more threads to be used. It is not required, but using `nmake`is slower. If `JOM_LOC` isn't defined, or the `.exe` can't be found `nmake` will be used by default. | +| `JOM_LOC` | Path to an `.exe` of `jom.exe`. Usually installed with Qt. `jom` is a wrapper around `nmake` allowing more threads to be used. It is not required, but using `nmake`is slower. If `JOM_LOC` isn't defined, or the `.exe` can't be found `nmake` will be used by default. To force using `nmake`, set `JOM_LOC` to a non-valid path like `1`. | | `ZIP_LOC` | Path to your 7zip `.exe`. Both portable and installer will work. | | `NSIS_LOC` | Path to your installation of NSIS containing the `makensis` file. Both portable and installer will work. | +| `CLANG_FORMAT_LOC` | Path to your `clang-format.exe`. Not necessary for building, but necessary for pushing changes to the repo. | If an environment variable isn't set a default value will be provided. The default values are shown in the table below. @@ -41,6 +49,7 @@ If an environment variable isn't set a default value will be provided. The defau | `JOM_LOC` | `"C:\Qt\Tools\QtCreator\bin\jom.exe"`| | `ZIP_LOC` | `"C:\Program Files\7-Zip\7z.exe"` | | `NSIS_LOC` | `"C:\Program Files (x86)\NSIS\"` | +| `CLANG_FORMAT_LOC` | `"C:\Program Files\LLVM\bin\clang-format.exe"` | Additionally, these optional environment variables are supported. @@ -58,6 +67,11 @@ The `.dll` files necessary for a release build differ from those needed by a deb With the programs above installed and environment variables set, go into the root folder of the repository and run `build_windows.cmd`. Compiled binaries along with everything needed to run portable will output to `.\bin\win64\AdvancedSettings\`. + +## Contributing + +For full details, see [CONTRIBUTING.md](CONTRIBUTING.md). + ## Using with QtCreator diff --git a/src/logging.h b/src/logging.h index 6c50c49..5a8dd38 100644 --- a/src/logging.h +++ b/src/logging.h @@ -2,15 +2,15 @@ // easylogging includes #ifndef _DEBUG - #define _DEBUG - #define ELPP_THREAD_SAFE - #define ELPP_QT_LOGGING - #define ELPP_NO_DEFAULT_LOG_FILE - #include - #undef _DEBUG +# define _DEBUG +# define ELPP_THREAD_SAFE +# define ELPP_QT_LOGGING +# define ELPP_NO_DEFAULT_LOG_FILE +# include +# undef _DEBUG #else - #define ELPP_THREAD_SAFE - #define ELPP_QT_LOGGING - #define ELPP_NO_DEFAULT_LOG_FILE - #include +# define ELPP_THREAD_SAFE +# define ELPP_QT_LOGGING +# define ELPP_NO_DEFAULT_LOG_FILE +# include #endif diff --git a/src/main.cpp b/src/main.cpp index 96bfff1..3a6ef7c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,248 +12,382 @@ INITIALIZE_EASYLOGGINGPP -void myQtMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - QByteArray localMsg = msg.toLocal8Bit(); - switch (type) { - case QtDebugMsg: - LOG(DEBUG) << localMsg.constData() << " (" << context.file << ":" << context.line << ")"; - break; - case QtInfoMsg: - LOG(INFO) << localMsg.constData() << " (" << context.file << ":" << context.line << ")"; - break; - case QtWarningMsg: - LOG(WARNING) << localMsg.constData() << " (" << context.file << ":" << context.line << ")"; - break; - case QtCriticalMsg: - LOG(ERROR) << localMsg.constData() << " (" << context.file << ":" << context.line << ")"; - break; - case QtFatalMsg: - LOG(FATAL) << localMsg.constData() << " (" << context.file << ":" << context.line << ")"; - break; - } +void myQtMessageHandler( QtMsgType type, + const QMessageLogContext& context, + const QString& msg ) +{ + QByteArray localMsg = msg.toLocal8Bit(); + switch ( type ) + { + case QtDebugMsg: + LOG( DEBUG ) << localMsg.constData() << " (" << context.file << ":" + << context.line << ")"; + break; + case QtInfoMsg: + LOG( INFO ) << localMsg.constData() << " (" << context.file << ":" + << context.line << ")"; + break; + case QtWarningMsg: + LOG( WARNING ) << localMsg.constData() << " (" << context.file << ":" + << context.line << ")"; + break; + case QtCriticalMsg: + LOG( ERROR ) << localMsg.constData() << " (" << context.file << ":" + << context.line << ")"; + break; + case QtFatalMsg: + LOG( FATAL ) << localMsg.constData() << " (" << context.file << ":" + << context.line << ")"; + break; + } } -void installManifest(bool cleaninstall = false) { - auto manifestQPath = QDir::cleanPath(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("manifest.vrmanifest")); - if (QFile::exists(manifestQPath)) { - bool alreadyInstalled = false; - if (vr::VRApplications()->IsApplicationInstalled(advsettings::OverlayController::applicationKey)) { - if (cleaninstall) { - char buffer[1024]; - auto appError = vr::VRApplicationError_None; - vr::VRApplications()->GetApplicationPropertyString(advsettings::OverlayController::applicationKey, vr::VRApplicationProperty_WorkingDirectory_String, buffer, 1024, &appError); - if (appError == vr::VRApplicationError_None) { - auto oldManifestQPath = QDir::cleanPath(QDir(buffer).absoluteFilePath("manifest.vrmanifest")); - if (oldManifestQPath.compare(manifestQPath, Qt::CaseInsensitive) != 0) { - vr::VRApplications()->RemoveApplicationManifest(QDir::toNativeSeparators(oldManifestQPath).toStdString().c_str()); - } else { - alreadyInstalled = true; - } - } - } else { - alreadyInstalled = true; - } - } - auto apperror = vr::VRApplications()->AddApplicationManifest(QDir::toNativeSeparators(manifestQPath).toStdString().c_str()); - if (apperror != vr::VRApplicationError_None) { - throw std::runtime_error(std::string("Could not add application manifest: ") + std::string(vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror))); - } else if (!alreadyInstalled || cleaninstall) { - auto app_error = vr::VRApplications()->SetApplicationAutoLaunch(advsettings::OverlayController::applicationKey, true); - if (app_error != vr::VRApplicationError_None) { - throw std::runtime_error(std::string("Could not set auto start: ") + std::string(vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror))); - } - } - } else { - throw std::runtime_error(std::string("Could not find application manifest: ") + manifestQPath.toStdString()); - } -} - -void removeManifest() { - auto manifestQPath = QDir::cleanPath(QDir(QCoreApplication::applicationDirPath()).absoluteFilePath("manifest.vrmanifest")); - if (QFile::exists(manifestQPath)) { - if (vr::VRApplications()->IsApplicationInstalled(advsettings::OverlayController::applicationKey)) { - vr::VRApplications()->RemoveApplicationManifest(QDir::toNativeSeparators(manifestQPath).toStdString().c_str()); - } - } else { - throw std::runtime_error(std::string("Could not find application manifest: ") + manifestQPath.toStdString()); - } -} - - -class MyQApplication : public QApplication { -public: - using QApplication::QApplication; - - virtual bool notify(QObject * receiver, QEvent * event) override { - try { - return QApplication::notify(receiver, event); - } catch (std::exception& e) { - LOG(ERROR) << "Exception thrown from an event handler: " << e.what(); - } - return false; - } -}; - - - -namespace argument { - // Checks whether a specific string was passed as a launch argument. - bool CheckCommandLineArgument(int argc, char *argv[], const std::string parameter) { - // The old way was one giant loop that tested every single parameter. - // Having an individual loop for all args most likely has a very small performance - // penalty compared to the original solution, - // but the gains in readability and ease of extension of not having a hundred line+ for loop are worth it. - for (int i = 0; i < argc; i++) { - if (std::string(argv[i]) == parameter) { - return true; +void installManifest( bool cleaninstall = false ) +{ + auto manifestQPath + = QDir::cleanPath( QDir( QCoreApplication::applicationDirPath() ) + .absoluteFilePath( "manifest.vrmanifest" ) ); + if ( QFile::exists( manifestQPath ) ) + { + bool alreadyInstalled = false; + if ( vr::VRApplications()->IsApplicationInstalled( + advsettings::OverlayController::applicationKey ) ) + { + if ( cleaninstall ) + { + char buffer[1024]; + auto appError = vr::VRApplicationError_None; + vr::VRApplications()->GetApplicationPropertyString( + advsettings::OverlayController::applicationKey, + vr::VRApplicationProperty_WorkingDirectory_String, + buffer, + 1024, + &appError ); + if ( appError == vr::VRApplicationError_None ) + { + auto oldManifestQPath + = QDir::cleanPath( QDir( buffer ).absoluteFilePath( + "manifest.vrmanifest" ) ); + if ( oldManifestQPath.compare( manifestQPath, + Qt::CaseInsensitive ) + != 0 ) + { + vr::VRApplications()->RemoveApplicationManifest( + QDir::toNativeSeparators( oldManifestQPath ) + .toStdString() + .c_str() ); + } + else + { + alreadyInstalled = true; + } + } } + else + { + alreadyInstalled = true; + } + } + auto apperror = vr::VRApplications()->AddApplicationManifest( + QDir::toNativeSeparators( manifestQPath ).toStdString().c_str() ); + if ( apperror != vr::VRApplicationError_None ) + { + throw std::runtime_error( + std::string( "Could not add application manifest: " ) + + std::string( + vr::VRApplications()->GetApplicationsErrorNameFromEnum( + apperror ) ) ); + } + else if ( !alreadyInstalled || cleaninstall ) + { + auto app_error = vr::VRApplications()->SetApplicationAutoLaunch( + advsettings::OverlayController::applicationKey, true ); + if ( app_error != vr::VRApplicationError_None ) + { + throw std::runtime_error( + std::string( "Could not set auto start: " ) + + std::string( vr::VRApplications() + ->GetApplicationsErrorNameFromEnum( + apperror ) ) ); + } + } + } + else + { + throw std::runtime_error( + std::string( "Could not find application manifest: " ) + + manifestQPath.toStdString() ); + } +} + +void removeManifest() +{ + auto manifestQPath + = QDir::cleanPath( QDir( QCoreApplication::applicationDirPath() ) + .absoluteFilePath( "manifest.vrmanifest" ) ); + if ( QFile::exists( manifestQPath ) ) + { + if ( vr::VRApplications()->IsApplicationInstalled( + advsettings::OverlayController::applicationKey ) ) + { + vr::VRApplications()->RemoveApplicationManifest( + QDir::toNativeSeparators( manifestQPath ) + .toStdString() + .c_str() ); + } + } + else + { + throw std::runtime_error( + std::string( "Could not find application manifest: " ) + + manifestQPath.toStdString() ); + } +} + +class MyQApplication : public QApplication +{ +public: + using QApplication::QApplication; + + virtual bool notify( QObject* receiver, QEvent* event ) override + { + try + { + return QApplication::notify( receiver, event ); + } + catch ( std::exception& e ) + { + LOG( ERROR ) << "Exception thrown from an event handler: " + << e.what(); } return false; } +}; - constexpr auto DESKTOP_MODE = "-desktop"; - constexpr auto NO_SOUND = "-nosound"; - constexpr auto NO_MANIFEST = "-nomanifest"; - constexpr auto INSTALL_MANIFEST= "-installmanifest"; - constexpr auto REMOVE_MANIFEST= "-removemanifest"; +namespace argument +{ +// Checks whether a specific string was passed as a launch argument. +bool CheckCommandLineArgument( int argc, + char* argv[], + const std::string parameter ) +{ + // The old way was one giant loop that tested every single parameter. + // Having an individual loop for all args most likely has a very small + // performance penalty compared to the original solution, but the gains in + // readability and ease of extension of not having a hundred line+ for loop + // are worth it. + for ( int i = 0; i < argc; i++ ) + { + if ( std::string( argv[i] ) == parameter ) + { + return true; + } + } + return false; } -enum ReturnErrorCode { +constexpr auto DESKTOP_MODE = "-desktop"; +constexpr auto NO_SOUND = "-nosound"; +constexpr auto NO_MANIFEST = "-nomanifest"; +constexpr auto INSTALL_MANIFEST = "-installmanifest"; +constexpr auto REMOVE_MANIFEST = "-removemanifest"; +} // namespace argument + +enum ReturnErrorCode +{ SUCCESS = 0, GENERAL_FAILURE = -1, OPENVR_INIT_ERROR = -2, }; -int main(int argc, char *argv[]) { - +int main( int argc, char* argv[] ) +{ const char* logConfigFileName = "logging.conf"; - const char* logConfigDefault = - "* GLOBAL:\n" - " FORMAT = \"[%level] %datetime{%Y-%M-%d %H:%m:%s}: %msg\"\n" - " FILENAME = \"AdvancedSettings.log\"\n" - " ENABLED = true\n" - " TO_FILE = true\n" - " TO_STANDARD_OUTPUT = true\n" - " MAX_LOG_FILE_SIZE = 2097152 ## 2MB\n" - "* TRACE:\n" - " ENABLED = false\n" - "* DEBUG:\n" - " ENABLED = false\n"; + const char* logConfigDefault + = "* GLOBAL:\n" + " FORMAT = \"[%level] %datetime{%Y-%M-%d %H:%m:%s}: %msg\"\n" + " FILENAME = \"AdvancedSettings.log\"\n" + " ENABLED = true\n" + " TO_FILE = true\n" + " TO_STANDARD_OUTPUT = true\n" + " MAX_LOG_FILE_SIZE = 2097152 ## 2MB\n" + "* TRACE:\n" + " ENABLED = false\n" + "* DEBUG:\n" + " ENABLED = false\n"; - const bool desktop_mode = argument::CheckCommandLineArgument(argc, argv, argument::DESKTOP_MODE); - const bool no_sound = argument::CheckCommandLineArgument(argc, argv, argument::NO_SOUND); - const bool no_manifest = argument::CheckCommandLineArgument(argc, argv, argument::NO_MANIFEST); - const bool install_manifest = argument::CheckCommandLineArgument(argc, argv, argument::INSTALL_MANIFEST); - const bool remove_manifest = argument::CheckCommandLineArgument(argc, argv, argument::REMOVE_MANIFEST); + const bool desktop_mode = argument::CheckCommandLineArgument( + argc, argv, argument::DESKTOP_MODE ); + const bool no_sound + = argument::CheckCommandLineArgument( argc, argv, argument::NO_SOUND ); + const bool no_manifest = argument::CheckCommandLineArgument( + argc, argv, argument::NO_MANIFEST ); + const bool install_manifest = argument::CheckCommandLineArgument( + argc, argv, argument::INSTALL_MANIFEST ); + const bool remove_manifest = argument::CheckCommandLineArgument( + argc, argv, argument::REMOVE_MANIFEST ); - if (install_manifest || remove_manifest) { + if ( install_manifest || remove_manifest ) + { int exit_code = ReturnErrorCode::SUCCESS; - QCoreApplication coreApp(argc, argv); + QCoreApplication coreApp( argc, argv ); auto openvr_init_status = vr::VRInitError_None; - vr::VR_Init(&openvr_init_status, vr::VRApplication_Utility); + vr::VR_Init( &openvr_init_status, vr::VRApplication_Utility ); - if (openvr_init_status == vr::VRInitError_None) { - try { - if (install_manifest) { - installManifest(true); + if ( openvr_init_status == vr::VRInitError_None ) + { + try + { + if ( install_manifest ) + { + installManifest( true ); } - else if (remove_manifest) { + else if ( remove_manifest ) + { removeManifest(); } } - catch (std::exception& e) { + catch ( std::exception& e ) + { exit_code = ReturnErrorCode::GENERAL_FAILURE; std::cerr << e.what() << std::endl; } } - else { + else + { exit_code = ReturnErrorCode::OPENVR_INIT_ERROR; - std::cerr << std::string("Failed to initialize OpenVR: " + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(openvr_init_status))) << std::endl; + std::cerr << std::string( + "Failed to initialize OpenVR: " + + std::string( + vr::VR_GetVRInitErrorAsEnglishDescription( + openvr_init_status ) ) ) + << std::endl; } vr::VR_Shutdown(); - exit(exit_code); + exit( exit_code ); } - try { - MyQApplication a(argc, argv); - a.setOrganizationName("matzman666"); - a.setApplicationName("OpenVRAdvancedSettings"); - a.setApplicationDisplayName(advsettings::OverlayController::applicationName); - a.setApplicationVersion(advsettings::OverlayController::applicationVersionString); + try + { + MyQApplication a( argc, argv ); + a.setOrganizationName( "matzman666" ); + a.setApplicationName( "OpenVRAdvancedSettings" ); + a.setApplicationDisplayName( + advsettings::OverlayController::applicationName ); + a.setApplicationVersion( + advsettings::OverlayController::applicationVersionString ); - qInstallMessageHandler(myQtMessageHandler); + qInstallMessageHandler( myQtMessageHandler ); - // Configure logger - QString logFilePath; - START_EASYLOGGINGPP(argc, argv); - el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog); - auto logconfigfile = QFileInfo(logConfigFileName).absoluteFilePath(); - el::Configurations conf; - if (QFile::exists(logconfigfile)) { - conf.parseFromFile(logconfigfile.toStdString()); - } else { - conf.parseFromText(logConfigDefault); - } - if (!conf.get(el::Level::Global, el::ConfigurationType::Filename)) { - logFilePath = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)).absoluteFilePath("AdvancedSettings.log"); - conf.set(el::Level::Global, el::ConfigurationType::Filename, QDir::toNativeSeparators(logFilePath).toStdString()); - } - conf.setRemainingToDefault(); - el::Loggers::reconfigureAllLoggers(conf); - LOG(INFO) << "Application started (Version " << advsettings::OverlayController::applicationVersionString << ")"; - LOG(INFO) << "Log Config: " << QDir::toNativeSeparators(logconfigfile).toStdString(); - if (!logFilePath.isEmpty()) { - LOG(INFO) << "Log File: " << logFilePath; - } - - if (desktop_mode) { - LOG(INFO) << "Desktop mode enabled."; - } - if (no_sound) { - LOG(INFO) << "Sound effects disabled."; - } - if (no_manifest) { - LOG(INFO) << "vrmanifest disabled."; - } + // Configure logger + QString logFilePath; + START_EASYLOGGINGPP( argc, argv ); + el::Loggers::addFlag( + el::LoggingFlag::DisableApplicationAbortOnFatalLog ); + auto logconfigfile = QFileInfo( logConfigFileName ).absoluteFilePath(); + el::Configurations conf; + if ( QFile::exists( logconfigfile ) ) + { + conf.parseFromFile( logconfigfile.toStdString() ); + } + else + { + conf.parseFromText( logConfigDefault ); + } + if ( !conf.get( el::Level::Global, el::ConfigurationType::Filename ) ) + { + logFilePath = QDir( QStandardPaths::writableLocation( + QStandardPaths::AppDataLocation ) ) + .absoluteFilePath( "AdvancedSettings.log" ); + conf.set( el::Level::Global, + el::ConfigurationType::Filename, + QDir::toNativeSeparators( logFilePath ).toStdString() ); + } + conf.setRemainingToDefault(); + el::Loggers::reconfigureAllLoggers( conf ); + LOG( INFO ) << "Application started (Version " + << advsettings::OverlayController::applicationVersionString + << ")"; + LOG( INFO ) << "Log Config: " + << QDir::toNativeSeparators( logconfigfile ).toStdString(); + if ( !logFilePath.isEmpty() ) + { + LOG( INFO ) << "Log File: " << logFilePath; + } - QSettings appSettings(QSettings::IniFormat, QSettings::UserScope, a.organizationName(), a.applicationName()); - advsettings::OverlayController::setAppSettings(&appSettings); - LOG(INFO) << "Settings File: " << appSettings.fileName().toStdString(); + if ( desktop_mode ) + { + LOG( INFO ) << "Desktop mode enabled."; + } + if ( no_sound ) + { + LOG( INFO ) << "Sound effects disabled."; + } + if ( no_manifest ) + { + LOG( INFO ) << "vrmanifest disabled."; + } - QQmlEngine qmlEngine; + QSettings appSettings( QSettings::IniFormat, + QSettings::UserScope, + a.organizationName(), + a.applicationName() ); + advsettings::OverlayController::setAppSettings( &appSettings ); + LOG( INFO ) << "Settings File: " + << appSettings.fileName().toStdString(); - advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktop_mode, no_sound); - controller->Init(&qmlEngine); + QQmlEngine qmlEngine; - QQmlComponent component(&qmlEngine, QUrl::fromLocalFile("res/qml/mainwidget.qml")); - auto errors = component.errors(); - for (auto& e : errors) { - LOG(ERROR) << "QML Error: " << e.toString().toStdString() << std::endl; - } - auto quickObj = component.create(); - controller->SetWidget(qobject_cast(quickObj), advsettings::OverlayController::applicationName, advsettings::OverlayController::applicationKey); + advsettings::OverlayController* controller + = advsettings::OverlayController::createInstance( desktop_mode, + no_sound ); + controller->Init( &qmlEngine ); - if (!desktop_mode && !no_manifest) { - try { - installManifest(); - } catch (std::exception& e) { - LOG(ERROR) << e.what(); - } - } + QQmlComponent component( + &qmlEngine, QUrl::fromLocalFile( "res/qml/mainwidget.qml" ) ); + auto errors = component.errors(); + for ( auto& e : errors ) + { + LOG( ERROR ) << "QML Error: " << e.toString().toStdString() + << std::endl; + } + auto quickObj = component.create(); + controller->SetWidget( qobject_cast( quickObj ), + advsettings::OverlayController::applicationName, + advsettings::OverlayController::applicationKey ); - if (desktop_mode) { - 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(); - } + if ( !desktop_mode && !no_manifest ) + { + try + { + installManifest(); + } + catch ( std::exception& e ) + { + LOG( ERROR ) << e.what(); + } + } - return a.exec(); + if ( desktop_mode ) + { + 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(); + } - } catch (const std::exception& e) { - LOG(FATAL) << e.what(); - return ReturnErrorCode::GENERAL_FAILURE; - } + return a.exec(); + } + catch ( const std::exception& e ) + { + LOG( FATAL ) << e.what(); + return ReturnErrorCode::GENERAL_FAILURE; + } } diff --git a/src/overlaycontroller.cpp b/src/overlaycontroller.cpp index c0195dc..7d0bece 100644 --- a/src/overlaycontroller.cpp +++ b/src/overlaycontroller.cpp @@ -21,674 +21,1062 @@ #include "logging.h" #include "utils/Matrix.h" - - // application namespace -namespace advsettings { - +namespace advsettings +{ std::unique_ptr OverlayController::singleton; constexpr const char* OverlayController::applicationVersionString; QSettings* OverlayController::_appSettings = nullptr; -OverlayController::~OverlayController() { - Shutdown(); +OverlayController::~OverlayController() +{ + Shutdown(); } -void OverlayController::Init(QQmlEngine* qmlEngine) { - // Loading the OpenVR Runtime - auto initError = vr::VRInitError_None; - vr::VR_Init(&initError, vr::VRApplication_Overlay); - if (initError != vr::VRInitError_None) { - if (initError == vr::VRInitError_Init_HmdNotFound || initError == vr::VRInitError_Init_HmdNotFoundPresenceFailed) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "Could not find HMD!"); - } - throw std::runtime_error(std::string("Failed to initialize OpenVR: ") + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(initError))); - } +void OverlayController::Init( QQmlEngine* qmlEngine ) +{ + // Loading the OpenVR Runtime + auto initError = vr::VRInitError_None; + vr::VR_Init( &initError, vr::VRApplication_Overlay ); + if ( initError != vr::VRInitError_None ) + { + if ( initError == vr::VRInitError_Init_HmdNotFound + || initError == vr::VRInitError_Init_HmdNotFoundPresenceFailed ) + { + QMessageBox::critical( nullptr, + "OpenVR Advanced Settings Overlay", + "Could not find HMD!" ); + } + throw std::runtime_error( + std::string( "Failed to initialize OpenVR: " ) + + std::string( + vr::VR_GetVRInitErrorAsEnglishDescription( initError ) ) ); + } - m_runtimePathUrl = QUrl::fromLocalFile(vr::VR_RuntimePath()); - LOG(INFO) << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile(); + m_runtimePathUrl = QUrl::fromLocalFile( vr::VR_RuntimePath() ); + LOG( INFO ) << "VR Runtime Path: " << m_runtimePathUrl.toLocalFile(); - QString activationSoundFile = m_runtimePathUrl.toLocalFile().append("/content/panorama/sounds/activation.wav"); - QFileInfo activationSoundFileInfo(activationSoundFile); - if (activationSoundFileInfo.exists() && activationSoundFileInfo.isFile()) { - activationSoundEffect.setSource(QUrl::fromLocalFile(activationSoundFile)); - activationSoundEffect.setVolume(1.0); - } else { - LOG(ERROR) << "Could not find activation sound file " << activationSoundFile; - } + QString activationSoundFile = m_runtimePathUrl.toLocalFile().append( + "/content/panorama/sounds/activation.wav" ); + QFileInfo activationSoundFileInfo( activationSoundFile ); + if ( activationSoundFileInfo.exists() && activationSoundFileInfo.isFile() ) + { + activationSoundEffect.setSource( + QUrl::fromLocalFile( activationSoundFile ) ); + activationSoundEffect.setVolume( 1.0 ); + } + else + { + LOG( ERROR ) << "Could not find activation sound file " + << activationSoundFile; + } - QString focusChangedSoundFile = m_runtimePathUrl.toLocalFile().append("/content/panorama/sounds/focus_change.wav"); - QFileInfo focusChangedSoundFileInfo(focusChangedSoundFile); - if (focusChangedSoundFileInfo.exists() && focusChangedSoundFileInfo.isFile()) { - focusChangedSoundEffect.setSource(QUrl::fromLocalFile(focusChangedSoundFile)); - focusChangedSoundEffect.setVolume(1.0); - } else { - LOG(ERROR) << "Could not find focus changed sound file " << focusChangedSoundFile; - } + QString focusChangedSoundFile = m_runtimePathUrl.toLocalFile().append( + "/content/panorama/sounds/focus_change.wav" ); + QFileInfo focusChangedSoundFileInfo( focusChangedSoundFile ); + if ( focusChangedSoundFileInfo.exists() + && focusChangedSoundFileInfo.isFile() ) + { + focusChangedSoundEffect.setSource( + QUrl::fromLocalFile( focusChangedSoundFile ) ); + focusChangedSoundEffect.setVolume( 1.0 ); + } + else + { + LOG( ERROR ) << "Could not find focus changed sound file " + << focusChangedSoundFile; + } - QString alarm01SoundFile = QApplication::applicationDirPath().append("/res/sounds/alarm01.wav"); - QFileInfo alarm01SoundFileInfo(alarm01SoundFile); - if (alarm01SoundFileInfo.exists() && alarm01SoundFileInfo.isFile()) { - alarm01SoundEffect.setSource(QUrl::fromLocalFile(alarm01SoundFile)); - alarm01SoundEffect.setVolume(1.0); - } else { - LOG(ERROR) << "Could not find alarm01 sound file " << alarm01SoundFile; - } + QString alarm01SoundFile = QApplication::applicationDirPath().append( + "/res/sounds/alarm01.wav" ); + QFileInfo alarm01SoundFileInfo( alarm01SoundFile ); + if ( alarm01SoundFileInfo.exists() && alarm01SoundFileInfo.isFile() ) + { + alarm01SoundEffect.setSource( QUrl::fromLocalFile( alarm01SoundFile ) ); + alarm01SoundEffect.setVolume( 1.0 ); + } + else + { + LOG( ERROR ) << "Could not find alarm01 sound file " + << alarm01SoundFile; + } - // Check whether OpenVR is too outdated - if (!vr::VR_IsInterfaceVersionValid(vr::IVRSystem_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRSystem_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRSettings_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRSettings_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVROverlay_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVROverlay_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRApplications_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRApplications_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRChaperone_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRChaperone_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRChaperoneSetup_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRChaperoneSetup_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRCompositor_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRCompositor_Version) + std::string(" not found.")); - } else if (!vr::VR_IsInterfaceVersionValid(vr::IVRNotifications_Version)) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "OpenVR version is too outdated. Please update OpenVR."); - throw std::runtime_error(std::string("OpenVR version is too outdated: Interface version ") + std::string(vr::IVRNotifications_Version) + std::string(" not found.")); - } + // Check whether OpenVR is too outdated + if ( !vr::VR_IsInterfaceVersionValid( vr::IVRSystem_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRSystem_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRSettings_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRSettings_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVROverlay_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVROverlay_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRApplications_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRApplications_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRChaperone_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRChaperone_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRChaperoneSetup_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRChaperoneSetup_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRCompositor_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRCompositor_Version ) + + std::string( " not found." ) ); + } + else if ( !vr::VR_IsInterfaceVersionValid( vr::IVRNotifications_Version ) ) + { + QMessageBox::critical( + nullptr, + "OpenVR Advanced Settings Overlay", + "OpenVR version is too outdated. Please update OpenVR." ); + throw std::runtime_error( + std::string( "OpenVR version is too outdated: Interface version " ) + + std::string( vr::IVRNotifications_Version ) + + std::string( " not found." ) ); + } - QSurfaceFormat format; - // Qt's QOpenGLPaintDevice is not compatible with OpenGL versions >= 3.0 - // NVIDIA does not care, but unfortunately AMD does - // Are subtle changes to the semantics of OpenGL functions actually covered by the compatibility profile, - // and this is an AMD bug? - format.setVersion(2, 1); - //format.setProfile( QSurfaceFormat::CompatibilityProfile ); - format.setDepthBufferSize(16); - format.setStencilBufferSize(8); - format.setSamples(16); + QSurfaceFormat format; + // Qt's QOpenGLPaintDevice is not compatible with OpenGL versions >= 3.0 + // NVIDIA does not care, but unfortunately AMD does + // Are subtle changes to the semantics of OpenGL functions actually covered + // by the compatibility profile, and this is an AMD bug? + format.setVersion( 2, 1 ); + // format.setProfile( QSurfaceFormat::CompatibilityProfile ); + format.setDepthBufferSize( 16 ); + format.setStencilBufferSize( 8 ); + format.setSamples( 16 ); - m_pOpenGLContext.reset(new QOpenGLContext()); - m_pOpenGLContext->setFormat(format); - if (!m_pOpenGLContext->create()) { - throw std::runtime_error("Could not create OpenGL context"); - } + m_pOpenGLContext.reset( new QOpenGLContext() ); + m_pOpenGLContext->setFormat( format ); + if ( !m_pOpenGLContext->create() ) + { + throw std::runtime_error( "Could not create OpenGL context" ); + } - // create an offscreen surface to attach the context and FBO to - m_pOffscreenSurface.reset(new QOffscreenSurface()); - m_pOffscreenSurface->setFormat(m_pOpenGLContext->format()); - m_pOffscreenSurface->create(); - m_pOpenGLContext->makeCurrent(m_pOffscreenSurface.get()); + // create an offscreen surface to attach the context and FBO to + m_pOffscreenSurface.reset( new QOffscreenSurface() ); + m_pOffscreenSurface->setFormat( m_pOpenGLContext->format() ); + m_pOffscreenSurface->create(); + m_pOpenGLContext->makeCurrent( m_pOffscreenSurface.get() ); - if (!vr::VROverlay()) { - QMessageBox::critical(nullptr, "OpenVR Advanced Settings Overlay", "Is OpenVR running?"); - throw std::runtime_error(std::string("No Overlay interface")); - } + if ( !vr::VROverlay() ) + { + QMessageBox::critical( + nullptr, "OpenVR Advanced Settings Overlay", "Is OpenVR running?" ); + throw std::runtime_error( std::string( "No Overlay interface" ) ); + } - // Init controllers - steamVRTabController.initStage1(); - chaperoneTabController.initStage1(); - moveCenterTabController.initStage1(); - fixFloorTabController.initStage1(); - audioTabController.initStage1(); - statisticsTabController.initStage1(); - settingsTabController.initStage1(); - reviveTabController.initStage1(settingsTabController.forceRevivePage()); - utilitiesTabController.initStage1(); - accessibilityTabController.initStage1(); + // Init controllers + steamVRTabController.initStage1(); + chaperoneTabController.initStage1(); + moveCenterTabController.initStage1(); + fixFloorTabController.initStage1(); + audioTabController.initStage1(); + statisticsTabController.initStage1(); + settingsTabController.initStage1(); + reviveTabController.initStage1( settingsTabController.forceRevivePage() ); + utilitiesTabController.initStage1(); + accessibilityTabController.initStage1(); - // Set qml context - qmlEngine->rootContext()->setContextProperty("applicationVersion", getVersionString()); - qmlEngine->rootContext()->setContextProperty("vrRuntimePath", getVRRuntimePathUrl()); + // Set qml context + qmlEngine->rootContext()->setContextProperty( "applicationVersion", + getVersionString() ); + qmlEngine->rootContext()->setContextProperty( "vrRuntimePath", + getVRRuntimePathUrl() ); - // Register qml singletons - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "OverlayController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = getInstance(); - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "SteamVRTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->steamVRTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "ChaperoneTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->chaperoneTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "MoveCenterTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->moveCenterTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "FixFloorTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->fixFloorTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "AudioTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->audioTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "StatisticsTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->statisticsTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "SettingsTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->settingsTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "ReviveTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->reviveTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "UtilitiesTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->utilitiesTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); - qmlRegisterSingletonType("matzman666.advsettings", 1, 0, "AccessibilityTabController", [](QQmlEngine*, QJSEngine*) { - QObject* obj = &getInstance()->accessibilityTabController; - QQmlEngine::setObjectOwnership(obj, QQmlEngine::CppOwnership); - return obj; - }); + // Register qml singletons + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "OverlayController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = getInstance(); + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "SteamVRTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->steamVRTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "ChaperoneTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->chaperoneTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "MoveCenterTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->moveCenterTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "FixFloorTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->fixFloorTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "AudioTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->audioTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "StatisticsTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->statisticsTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "SettingsTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->settingsTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "ReviveTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->reviveTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "UtilitiesTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->utilitiesTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); + qmlRegisterSingletonType( + "matzman666.advsettings", + 1, + 0, + "AccessibilityTabController", + []( QQmlEngine*, QJSEngine* ) { + QObject* obj = &getInstance()->accessibilityTabController; + QQmlEngine::setObjectOwnership( obj, QQmlEngine::CppOwnership ); + return obj; + } ); } -void OverlayController::Shutdown() { - if (m_pPumpEventsTimer) { - disconnect(m_pPumpEventsTimer.get(), SIGNAL(timeout()), this, SLOT(OnTimeoutPumpEvents())); - m_pPumpEventsTimer->stop(); - m_pPumpEventsTimer.reset(); - } - if (m_pRenderTimer) { - disconnect(m_pRenderControl.get(), SIGNAL(renderRequested()), this, SLOT(OnRenderRequest())); - disconnect(m_pRenderControl.get(), SIGNAL(sceneChanged()), this, SLOT(OnRenderRequest())); - disconnect(m_pRenderTimer.get(), SIGNAL(timeout()), this, SLOT(renderOverlay())); - m_pRenderTimer->stop(); - m_pRenderTimer.reset(); - } - m_pWindow.reset(); - m_pRenderControl.reset(); - m_pFbo.reset(); - m_pOpenGLContext.reset(); - m_pOffscreenSurface.reset(); +void OverlayController::Shutdown() +{ + if ( m_pPumpEventsTimer ) + { + disconnect( m_pPumpEventsTimer.get(), + SIGNAL( timeout() ), + this, + SLOT( OnTimeoutPumpEvents() ) ); + m_pPumpEventsTimer->stop(); + m_pPumpEventsTimer.reset(); + } + if ( m_pRenderTimer ) + { + disconnect( m_pRenderControl.get(), + SIGNAL( renderRequested() ), + this, + SLOT( OnRenderRequest() ) ); + disconnect( m_pRenderControl.get(), + SIGNAL( sceneChanged() ), + this, + SLOT( OnRenderRequest() ) ); + disconnect( m_pRenderTimer.get(), + SIGNAL( timeout() ), + this, + SLOT( renderOverlay() ) ); + m_pRenderTimer->stop(); + m_pRenderTimer.reset(); + } + m_pWindow.reset(); + m_pRenderControl.reset(); + m_pFbo.reset(); + m_pOpenGLContext.reset(); + m_pOffscreenSurface.reset(); } +void OverlayController::SetWidget( QQuickItem* quickItem, + const std::string& name, + const std::string& key ) +{ + 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 ) ) ) ); + } + 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 + << "\""; + } -void OverlayController::SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key) { - 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)))); - } - 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() ) ); - // 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 ) ); - 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() ); - 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 ); - 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() ) ); + } - connect(m_pRenderControl.get(), SIGNAL(renderRequested()), this, SLOT(OnRenderRequest())); - connect(m_pRenderControl.get(), SIGNAL(sceneChanged()), this, SLOT(OnRenderRequest())); - } + m_pPumpEventsTimer.reset( new QTimer() ); + connect( m_pPumpEventsTimer.get(), + SIGNAL( timeout() ), + this, + SLOT( OnTimeoutPumpEvents() ) ); + m_pPumpEventsTimer->setInterval( 20 ); + m_pPumpEventsTimer->start(); - m_pPumpEventsTimer.reset(new QTimer()); - connect(m_pPumpEventsTimer.get(), SIGNAL(timeout()), this, SLOT(OnTimeoutPumpEvents())); - m_pPumpEventsTimer->setInterval(20); - m_pPumpEventsTimer->start(); - - steamVRTabController.initStage2(this, m_pWindow.get()); - chaperoneTabController.initStage2(this, m_pWindow.get()); - moveCenterTabController.initStage2(this, m_pWindow.get()); - fixFloorTabController.initStage2(this, m_pWindow.get()); - audioTabController.initStage2(this, m_pWindow.get()); - statisticsTabController.initStage2(this, m_pWindow.get()); - settingsTabController.initStage2(this, m_pWindow.get()); - reviveTabController.initStage2(this, m_pWindow.get()); - utilitiesTabController.initStage2(this, m_pWindow.get()); - accessibilityTabController.initStage2(this, m_pWindow.get()); + steamVRTabController.initStage2( this, m_pWindow.get() ); + chaperoneTabController.initStage2( this, m_pWindow.get() ); + moveCenterTabController.initStage2( this, m_pWindow.get() ); + fixFloorTabController.initStage2( this, m_pWindow.get() ); + audioTabController.initStage2( this, m_pWindow.get() ); + statisticsTabController.initStage2( this, m_pWindow.get() ); + settingsTabController.initStage2( this, m_pWindow.get() ); + reviveTabController.initStage2( this, m_pWindow.get() ); + utilitiesTabController.initStage2( this, m_pWindow.get() ); + accessibilityTabController.initStage2( this, m_pWindow.get() ); } - -void OverlayController::OnRenderRequest() { - if (m_pRenderTimer && !m_pRenderTimer->isActive()) { - m_pRenderTimer->start(); - } +void OverlayController::OnRenderRequest() +{ + if ( m_pRenderTimer && !m_pRenderTimer->isActive() ) + { + m_pRenderTimer->start(); + } } -void OverlayController::renderOverlay() { - 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(); +void OverlayController::renderOverlay() +{ + 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(); - 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::TextureType_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::TextureType_OpenGL, + vr::ColorSpace_Auto }; #else - vr::Texture_t texture = { (void*)unTexture, vr::TextureType_OpenGL, vr::ColorSpace_Auto }; + vr::Texture_t texture = { ( void* ) unTexture, + vr::TextureType_OpenGL, + vr::ColorSpace_Auto }; #endif - vr::VROverlay()->SetOverlayTexture(m_ulOverlayHandle, &texture); - } - m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise the texture may be empty.*/ - } + vr::VROverlay()->SetOverlayTexture( m_ulOverlayHandle, &texture ); + } + m_pOpenGLContext->functions()->glFlush(); // We need to flush otherwise + // the texture may be empty.*/ + } } -bool OverlayController::pollNextEvent(vr::VROverlayHandle_t ulOverlayHandle, vr::VREvent_t* pEvent) { - if (isDesktopMode()) { - return vr::VRSystem()->PollNextEvent(pEvent, sizeof(vr::VREvent_t)); - } else { - return vr::VROverlay()->PollNextOverlayEvent(ulOverlayHandle, pEvent, sizeof(vr::VREvent_t)); - } +bool OverlayController::pollNextEvent( vr::VROverlayHandle_t ulOverlayHandle, + vr::VREvent_t* pEvent ) +{ + if ( isDesktopMode() ) + { + return vr::VRSystem()->PollNextEvent( pEvent, sizeof( vr::VREvent_t ) ); + } + else + { + return vr::VROverlay()->PollNextOverlayEvent( + ulOverlayHandle, pEvent, sizeof( vr::VREvent_t ) ); + } } -QPoint OverlayController::getMousePositionForEvent(vr::VREvent_Mouse_t mouse) { +QPoint OverlayController::getMousePositionForEvent( vr::VREvent_Mouse_t mouse ) +{ float y = mouse.y; #ifdef __linux__ - float h = (float) m_pWindow->height(); + float h = ( float ) m_pWindow->height(); y = h - y; #endif - return QPoint(mouse.x, y); + return QPoint( mouse.x, y ); } -void OverlayController::OnTimeoutPumpEvents() { - if (!vr::VRSystem()) - return; +void OverlayController::OnTimeoutPumpEvents() +{ + if ( !vr::VRSystem() ) + return; - vr::VREvent_t vrEvent; - bool chaperoneDataAlreadyUpdated = false; - while (pollNextEvent(m_ulOverlayHandle, &vrEvent)) { - switch (vrEvent.eventType) { - case vr::VREvent_MouseMove: { - QPoint ptNewMouse = getMousePositionForEvent(vrEvent.data.mouse); - if (ptNewMouse != m_ptLastMouse) { - QMouseEvent mouseEvent( QEvent::MouseMove, ptNewMouse, m_pWindow->mapToGlobal(ptNewMouse), Qt::NoButton, m_lastMouseButtons, 0 ); - m_ptLastMouse = ptNewMouse; - QCoreApplication::sendEvent(m_pWindow.get(), &mouseEvent); - OnRenderRequest(); - } - } - break; + vr::VREvent_t vrEvent; + bool chaperoneDataAlreadyUpdated = false; + while ( pollNextEvent( m_ulOverlayHandle, &vrEvent ) ) + { + switch ( vrEvent.eventType ) + { + case vr::VREvent_MouseMove: + { + QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse ); + if ( ptNewMouse != m_ptLastMouse ) + { + QMouseEvent mouseEvent( QEvent::MouseMove, + ptNewMouse, + m_pWindow->mapToGlobal( ptNewMouse ), + Qt::NoButton, + m_lastMouseButtons, + 0 ); + m_ptLastMouse = ptNewMouse; + QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent ); + OnRenderRequest(); + } + } + break; - case vr::VREvent_MouseButtonDown: { - QPoint ptNewMouse = getMousePositionForEvent(vrEvent.data.mouse); - Qt::MouseButton button = vrEvent.data.mouse.button == vr::VRMouseButton_Right ? Qt::RightButton : Qt::LeftButton; - m_lastMouseButtons |= button; - QMouseEvent mouseEvent(QEvent::MouseButtonPress, ptNewMouse, m_pWindow->mapToGlobal(ptNewMouse), button, m_lastMouseButtons, 0); - QCoreApplication::sendEvent(m_pWindow.get(), &mouseEvent); - } - break; + case vr::VREvent_MouseButtonDown: + { + QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse ); + Qt::MouseButton button + = vrEvent.data.mouse.button == vr::VRMouseButton_Right + ? Qt::RightButton + : Qt::LeftButton; + m_lastMouseButtons |= button; + QMouseEvent mouseEvent( QEvent::MouseButtonPress, + ptNewMouse, + m_pWindow->mapToGlobal( ptNewMouse ), + button, + m_lastMouseButtons, + 0 ); + QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent ); + } + break; - case vr::VREvent_MouseButtonUp: { - QPoint ptNewMouse = getMousePositionForEvent(vrEvent.data.mouse); - Qt::MouseButton button = vrEvent.data.mouse.button == vr::VRMouseButton_Right ? Qt::RightButton : Qt::LeftButton; - m_lastMouseButtons &= ~button; - QMouseEvent mouseEvent(QEvent::MouseButtonRelease, ptNewMouse, m_pWindow->mapToGlobal(ptNewMouse), button, m_lastMouseButtons, 0); - QCoreApplication::sendEvent(m_pWindow.get(), &mouseEvent); - } - break; + case vr::VREvent_MouseButtonUp: + { + QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse ); + Qt::MouseButton button + = vrEvent.data.mouse.button == vr::VRMouseButton_Right + ? Qt::RightButton + : Qt::LeftButton; + m_lastMouseButtons &= ~button; + QMouseEvent mouseEvent( QEvent::MouseButtonRelease, + ptNewMouse, + m_pWindow->mapToGlobal( ptNewMouse ), + button, + m_lastMouseButtons, + 0 ); + QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent ); + } + break; - case vr::VREvent_Scroll: { - // Wheel speed is defined as 1/8 of a degree - QWheelEvent wheelEvent(m_ptLastMouse, m_pWindow->mapToGlobal(m_ptLastMouse), QPoint(), - QPoint(vrEvent.data.scroll.xdelta * 360.0f * 8.0f, vrEvent.data.scroll.ydelta * 360.0f * 8.0f), - 0, Qt::Vertical, m_lastMouseButtons, 0); - QCoreApplication::sendEvent(m_pWindow.get(), &wheelEvent); - } - break; + case vr::VREvent_Scroll: + { + // Wheel speed is defined as 1/8 of a degree + QWheelEvent wheelEvent( + m_ptLastMouse, + m_pWindow->mapToGlobal( m_ptLastMouse ), + QPoint(), + QPoint( vrEvent.data.scroll.xdelta * 360.0f * 8.0f, + vrEvent.data.scroll.ydelta * 360.0f * 8.0f ), + 0, + Qt::Vertical, + m_lastMouseButtons, + 0 ); + QCoreApplication::sendEvent( m_pWindow.get(), &wheelEvent ); + } + break; - case vr::VREvent_OverlayShown: { - m_pWindow->update(); - } - break; + case vr::VREvent_OverlayShown: + { + m_pWindow->update(); + } + break; - case vr::VREvent_Quit: { - LOG(INFO) << "Received quit request."; - vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some time just in case - moveCenterTabController.reset(); - chaperoneTabController.shutdown(); - Shutdown(); - QApplication::exit(); - return; - } - break; + case vr::VREvent_Quit: + { + LOG( INFO ) << "Received quit request."; + vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some time + // just in case + moveCenterTabController.reset(); + chaperoneTabController.shutdown(); + Shutdown(); + QApplication::exit(); + return; + } + break; - case vr::VREvent_DashboardActivated: { - LOG(DEBUG) << "Dashboard activated"; - dashboardVisible = true; - } - break; + case vr::VREvent_DashboardActivated: + { + LOG( DEBUG ) << "Dashboard activated"; + dashboardVisible = true; + } + break; - case vr::VREvent_DashboardDeactivated: { - LOG(DEBUG) << "Dashboard deactivated"; - dashboardVisible = false; - } - break; + case vr::VREvent_DashboardDeactivated: + { + LOG( DEBUG ) << "Dashboard deactivated"; + dashboardVisible = false; + } + break; - case vr::VREvent_KeyboardDone: { - char keyboardBuffer[1024]; - vr::VROverlay()->GetKeyboardText(keyboardBuffer, 1024); - emit keyBoardInputSignal(QString(keyboardBuffer), vrEvent.data.keyboard.uUserValue); - } - break; + case vr::VREvent_KeyboardDone: + { + char keyboardBuffer[1024]; + vr::VROverlay()->GetKeyboardText( keyboardBuffer, 1024 ); + emit keyBoardInputSignal( QString( keyboardBuffer ), + vrEvent.data.keyboard.uUserValue ); + } + break; - // Multiple ChaperoneUniverseHasChanged are often emitted at the same time (some with a little bit of delay) - // There is no sure way to recognize redundant events, we can only exclude redundant events during the same call of OnTimeoutPumpEvents() - //INFO Removed logging on play space mover for possible crashing issues. - case vr::VREvent_ChaperoneUniverseHasChanged: - case vr::VREvent_ChaperoneDataHasChanged: { - if (!chaperoneDataAlreadyUpdated) { - //LOG(INFO) << "Re-loading chaperone data ..."; - m_chaperoneUtils.loadChaperoneData(); - //LOG(INFO) << "Found " << m_chaperoneUtils.quadsCount() << " chaperone quads."; - //if (m_chaperoneUtils.isChaperoneWellFormed()) { - //LOG(INFO) << "Chaperone data seems to be well-formed."; - //} else { - //LOG(INFO) << "Chaperone data is NOT well-formed."; - //} - chaperoneDataAlreadyUpdated = true; - } - } - break; - } - } + // Multiple ChaperoneUniverseHasChanged are often emitted at the same + // time (some with a little bit of delay) There is no sure way to + // recognize redundant events, we can only exclude redundant events + // during the same call of OnTimeoutPumpEvents() + // INFO Removed logging on play space mover for possible crashing + // issues. + case vr::VREvent_ChaperoneUniverseHasChanged: + case vr::VREvent_ChaperoneDataHasChanged: + { + if ( !chaperoneDataAlreadyUpdated ) + { + // LOG(INFO) << "Re-loading chaperone data ..."; + m_chaperoneUtils.loadChaperoneData(); + // LOG(INFO) << "Found " << m_chaperoneUtils.quadsCount() << " + // chaperone quads."; if + // (m_chaperoneUtils.isChaperoneWellFormed()) { LOG(INFO) << + // "Chaperone data seems to be well-formed."; + //} else { + // LOG(INFO) << "Chaperone data is NOT well-formed."; + //} + chaperoneDataAlreadyUpdated = true; + } + } + break; + } + } - vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount]; - vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0.0f, devicePoses, vr::k_unMaxTrackedDeviceCount); - - // HMD/Controller Velocities - auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - float leftSpeed = 0.0f; - if (leftId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[leftId].bPoseIsValid && devicePoses[leftId].eTrackingResult == vr::TrackingResult_Running_OK) { - auto& vel = devicePoses[leftId].vVelocity.v; - leftSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]); - } - auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - auto rightSpeed = 0.0f; - if (rightId != vr::k_unTrackedDeviceIndexInvalid && devicePoses[rightId].bPoseIsValid && devicePoses[rightId].eTrackingResult == vr::TrackingResult_Running_OK) { - auto& vel = devicePoses[rightId].vVelocity.v; - rightSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]); - } - auto hmdSpeed = 0.0f; - if (devicePoses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid && devicePoses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult == vr::TrackingResult_Running_OK) { - auto& vel = devicePoses[vr::k_unTrackedDeviceIndex_Hmd].vVelocity.v; - hmdSpeed = std::sqrt(vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2]); - } - - fixFloorTabController.eventLoopTick(devicePoses); - statisticsTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed); - moveCenterTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace(), devicePoses); - steamVRTabController.eventLoopTick(); - chaperoneTabController.eventLoopTick(devicePoses, leftSpeed, rightSpeed, hmdSpeed); - settingsTabController.eventLoopTick(); - reviveTabController.eventLoopTick(); - audioTabController.eventLoopTick(); - utilitiesTabController.eventLoopTick(); - accessibilityTabController.eventLoopTick(vr::VRCompositor()->GetTrackingSpace()); + vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount]; + vr::VRSystem()->GetDeviceToAbsoluteTrackingPose( + vr::TrackingUniverseStanding, + 0.0f, + devicePoses, + vr::k_unMaxTrackedDeviceCount ); - if (m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid) { - while (vr::VROverlay()->PollNextOverlayEvent(m_ulOverlayThumbnailHandle, &vrEvent, sizeof(vrEvent))) { - switch (vrEvent.eventType) { - case vr::VREvent_OverlayShown: { - m_pWindow->update(); - } - break; - } - } - } + // HMD/Controller Velocities + auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_LeftHand ); + float leftSpeed = 0.0f; + if ( leftId != vr::k_unTrackedDeviceIndexInvalid + && devicePoses[leftId].bPoseIsValid + && devicePoses[leftId].eTrackingResult + == vr::TrackingResult_Running_OK ) + { + auto& vel = devicePoses[leftId].vVelocity.v; + leftSpeed + = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] ); + } + auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_RightHand ); + auto rightSpeed = 0.0f; + if ( rightId != vr::k_unTrackedDeviceIndexInvalid + && devicePoses[rightId].bPoseIsValid + && devicePoses[rightId].eTrackingResult + == vr::TrackingResult_Running_OK ) + { + auto& vel = devicePoses[rightId].vVelocity.v; + rightSpeed + = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] ); + } + auto hmdSpeed = 0.0f; + if ( devicePoses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid + && devicePoses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult + == vr::TrackingResult_Running_OK ) + { + auto& vel = devicePoses[vr::k_unTrackedDeviceIndex_Hmd].vVelocity.v; + hmdSpeed + = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] ); + } + + fixFloorTabController.eventLoopTick( devicePoses ); + statisticsTabController.eventLoopTick( devicePoses, leftSpeed, rightSpeed ); + moveCenterTabController.eventLoopTick( + vr::VRCompositor()->GetTrackingSpace(), devicePoses ); + steamVRTabController.eventLoopTick(); + chaperoneTabController.eventLoopTick( + devicePoses, leftSpeed, rightSpeed, hmdSpeed ); + settingsTabController.eventLoopTick(); + reviveTabController.eventLoopTick(); + audioTabController.eventLoopTick(); + utilitiesTabController.eventLoopTick(); + accessibilityTabController.eventLoopTick( + vr::VRCompositor()->GetTrackingSpace() ); + + if ( m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid ) + { + while ( vr::VROverlay()->PollNextOverlayEvent( + m_ulOverlayThumbnailHandle, &vrEvent, sizeof( vrEvent ) ) ) + { + switch ( vrEvent.eventType ) + { + case vr::VREvent_OverlayShown: + { + m_pWindow->update(); + } + break; + } + } + } } -void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds, bool commit) { - float offsetArray[3] = { 0,0,0 }; - offsetArray[axisId] = offset; - AddOffsetToUniverseCenter(universe, offsetArray, adjustBounds, commit); +void OverlayController::AddOffsetToUniverseCenter( + vr::ETrackingUniverseOrigin universe, + unsigned axisId, + float offset, + bool adjustBounds, + bool commit ) +{ + float offsetArray[3] = { 0, 0, 0 }; + offsetArray[axisId] = offset; + AddOffsetToUniverseCenter( universe, offsetArray, adjustBounds, commit ); } -void OverlayController::AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, float offset[3], bool adjustBounds, bool commit) { - if (offset[0] != 0.0f || offset[1] != 0.0f || offset[2] != 0.0f) { - if (commit) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - } - vr::HmdMatrix34_t curPos; - if (universe == vr::TrackingUniverseStanding) { - vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose(&curPos); - } else { - vr::VRChaperoneSetup()->GetWorkingSeatedZeroPoseToRawTrackingPose(&curPos); - } - for (int i = 0; i < 3; i++) { - curPos.m[0][3] += curPos.m[0][i] * offset[i]; - curPos.m[1][3] += curPos.m[1][i] * offset[i]; - curPos.m[2][3] += curPos.m[2][i] * offset[i]; - } - if (universe == vr::TrackingUniverseStanding) { - vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose(&curPos); - } else { - vr::VRChaperoneSetup()->SetWorkingSeatedZeroPoseToRawTrackingPose(&curPos); - } - if (adjustBounds && universe == vr::TrackingUniverseStanding) { - float collisionOffset[] = { - -offset[0], - -offset[1], - -offset[2] - }; - AddOffsetToCollisionBounds(collisionOffset, false); - } - if (commit) { - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } - } +void OverlayController::AddOffsetToUniverseCenter( + vr::ETrackingUniverseOrigin universe, + float offset[3], + bool adjustBounds, + bool commit ) +{ + if ( offset[0] != 0.0f || offset[1] != 0.0f || offset[2] != 0.0f ) + { + if ( commit ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + } + vr::HmdMatrix34_t curPos; + if ( universe == vr::TrackingUniverseStanding ) + { + vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose( + &curPos ); + } + else + { + vr::VRChaperoneSetup()->GetWorkingSeatedZeroPoseToRawTrackingPose( + &curPos ); + } + for ( int i = 0; i < 3; i++ ) + { + curPos.m[0][3] += curPos.m[0][i] * offset[i]; + curPos.m[1][3] += curPos.m[1][i] * offset[i]; + curPos.m[2][3] += curPos.m[2][i] * offset[i]; + } + if ( universe == vr::TrackingUniverseStanding ) + { + vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose( + &curPos ); + } + else + { + vr::VRChaperoneSetup()->SetWorkingSeatedZeroPoseToRawTrackingPose( + &curPos ); + } + if ( adjustBounds && universe == vr::TrackingUniverseStanding ) + { + float collisionOffset[] = { -offset[0], -offset[1], -offset[2] }; + AddOffsetToCollisionBounds( collisionOffset, false ); + } + if ( commit ) + { + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + } + } } -void OverlayController::RotateUniverseCenter(vr::ETrackingUniverseOrigin universe, float yAngle, bool adjustBounds, bool commit) { - if (yAngle != 0.0f) { - if (commit) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - } - vr::HmdMatrix34_t curPos; - if (universe == vr::TrackingUniverseStanding) { - vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose(&curPos); - } else { - vr::VRChaperoneSetup()->GetWorkingSeatedZeroPoseToRawTrackingPose(&curPos); - } +void OverlayController::RotateUniverseCenter( + vr::ETrackingUniverseOrigin universe, + float yAngle, + bool adjustBounds, + bool commit ) +{ + if ( yAngle != 0.0f ) + { + if ( commit ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + } + vr::HmdMatrix34_t curPos; + if ( universe == vr::TrackingUniverseStanding ) + { + vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose( + &curPos ); + } + else + { + vr::VRChaperoneSetup()->GetWorkingSeatedZeroPoseToRawTrackingPose( + &curPos ); + } - vr::HmdMatrix34_t rotMat; - vr::HmdMatrix34_t newPos; - utils::initRotationMatrix(rotMat, 1, yAngle); - utils::matMul33(newPos, rotMat, curPos); - newPos.m[0][3] = curPos.m[0][3]; - newPos.m[1][3] = curPos.m[1][3]; - newPos.m[2][3] = curPos.m[2][3]; - if (universe == vr::TrackingUniverseStanding) { - vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose(&newPos); - } else { - vr::VRChaperoneSetup()->SetWorkingSeatedZeroPoseToRawTrackingPose(&newPos); - } - if (adjustBounds && universe == vr::TrackingUniverseStanding) { - RotateCollisionBounds(-yAngle, false); - } - if (commit) { - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } - } + vr::HmdMatrix34_t rotMat; + vr::HmdMatrix34_t newPos; + utils::initRotationMatrix( rotMat, 1, yAngle ); + utils::matMul33( newPos, rotMat, curPos ); + newPos.m[0][3] = curPos.m[0][3]; + newPos.m[1][3] = curPos.m[1][3]; + newPos.m[2][3] = curPos.m[2][3]; + if ( universe == vr::TrackingUniverseStanding ) + { + vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose( + &newPos ); + } + else + { + vr::VRChaperoneSetup()->SetWorkingSeatedZeroPoseToRawTrackingPose( + &newPos ); + } + if ( adjustBounds && universe == vr::TrackingUniverseStanding ) + { + RotateCollisionBounds( -yAngle, false ); + } + if ( commit ) + { + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + } + } } - -void OverlayController::AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit) { - float offsetArray[3] = { 0,0,0 }; - offsetArray[axisId] = offset; - AddOffsetToCollisionBounds(offsetArray, commit); +void OverlayController::AddOffsetToCollisionBounds( unsigned axisId, + float offset, + bool commit ) +{ + float offsetArray[3] = { 0, 0, 0 }; + offsetArray[axisId] = offset; + AddOffsetToCollisionBounds( offsetArray, commit ); } -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. - if (commit) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - } - unsigned collisionBoundsCount = 0; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(nullptr, &collisionBoundsCount); - if (collisionBoundsCount > 0) { - vr::HmdQuad_t* collisionBounds = new vr::HmdQuad_t[collisionBoundsCount]; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(collisionBounds, &collisionBoundsCount); - for (unsigned b = 0; b < collisionBoundsCount; b++) { - for (unsigned c = 0; c < 4; c++) { - collisionBounds[b].vCorners[c].v[0] += offset[0]; +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. + if ( commit ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + } + unsigned collisionBoundsCount = 0; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + nullptr, &collisionBoundsCount ); + if ( collisionBoundsCount > 0 ) + { + vr::HmdQuad_t* collisionBounds + = new vr::HmdQuad_t[collisionBoundsCount]; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + collisionBounds, &collisionBoundsCount ); + for ( unsigned b = 0; b < collisionBoundsCount; b++ ) + { + for ( unsigned c = 0; c < 4; c++ ) + { + 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 - if (collisionBounds[b].vCorners[c].v[1] != 0) { - collisionBounds[b].vCorners[c].v[1] += offset[1]; - } - collisionBounds[b].vCorners[c].v[2] += offset[2]; - } - } - vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(collisionBounds, collisionBoundsCount); - delete[] collisionBounds; - } - if (commit && collisionBoundsCount > 0) { - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } + // 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]; + } + collisionBounds[b].vCorners[c].v[2] += offset[2]; + } + } + vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo( + collisionBounds, collisionBoundsCount ); + delete[] collisionBounds; + } + if ( commit && collisionBoundsCount > 0 ) + { + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + } } -void OverlayController::RotateCollisionBounds(float angle, bool commit) { - if (commit) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - } - unsigned collisionBoundsCount = 0; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(nullptr, &collisionBoundsCount); - if (collisionBoundsCount > 0) { - vr::HmdQuad_t* collisionBounds = new vr::HmdQuad_t[collisionBoundsCount]; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(collisionBounds, &collisionBoundsCount); +void OverlayController::RotateCollisionBounds( float angle, bool commit ) +{ + if ( commit ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + } + unsigned collisionBoundsCount = 0; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + nullptr, &collisionBoundsCount ); + if ( collisionBoundsCount > 0 ) + { + vr::HmdQuad_t* collisionBounds + = new vr::HmdQuad_t[collisionBoundsCount]; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + collisionBounds, &collisionBoundsCount ); - vr::HmdMatrix34_t rotMat; - utils::initRotationMatrix(rotMat, 1, angle); - for (unsigned b = 0; b < collisionBoundsCount; b++) { - for (unsigned c = 0; c < 4; c++) { - auto& corner = collisionBounds[b].vCorners[c]; - vr::HmdVector3_t newVal; - utils::matMul33(newVal, rotMat, corner); - corner = newVal; - } - } - vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(collisionBounds, collisionBoundsCount); - delete[] collisionBounds; - } - if (commit && collisionBoundsCount > 0) { - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } + vr::HmdMatrix34_t rotMat; + utils::initRotationMatrix( rotMat, 1, angle ); + for ( unsigned b = 0; b < collisionBoundsCount; b++ ) + { + for ( unsigned c = 0; c < 4; c++ ) + { + auto& corner = collisionBounds[b].vCorners[c]; + vr::HmdVector3_t newVal; + utils::matMul33( newVal, rotMat, corner ); + corner = newVal; + } + } + vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo( + collisionBounds, collisionBoundsCount ); + delete[] collisionBounds; + } + if ( commit && collisionBoundsCount > 0 ) + { + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + } } -QString OverlayController::getVersionString() { - return QString(applicationVersionString); +QString OverlayController::getVersionString() +{ + return QString( applicationVersionString ); } - -QUrl OverlayController::getVRRuntimePathUrl() { - return m_runtimePathUrl; +QUrl OverlayController::getVRRuntimePathUrl() +{ + return m_runtimePathUrl; } - -bool OverlayController::soundDisabled() { - return noSound; +bool OverlayController::soundDisabled() +{ + return noSound; } - -const vr::VROverlayHandle_t& OverlayController::overlayHandle() { - return m_ulOverlayHandle; +const vr::VROverlayHandle_t& OverlayController::overlayHandle() +{ + return m_ulOverlayHandle; } - -const vr::VROverlayHandle_t& OverlayController::overlayThumbnailHandle() { - return m_ulOverlayThumbnailHandle; +const vr::VROverlayHandle_t& OverlayController::overlayThumbnailHandle() +{ + return m_ulOverlayThumbnailHandle; } - -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); +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 ); } - -void OverlayController::playActivationSound() { - if (!noSound) { - activationSoundEffect.play(); - } +void OverlayController::playActivationSound() +{ + if ( !noSound ) + { + activationSoundEffect.play(); + } } - -void OverlayController::playFocusChangedSound() { - if (!noSound) { - focusChangedSoundEffect.play(); - } +void OverlayController::playFocusChangedSound() +{ + if ( !noSound ) + { + focusChangedSoundEffect.play(); + } } -void OverlayController::playAlarm01Sound(bool loop) { - if (!noSound && !alarm01SoundEffect.isPlaying()) { - if (loop) { - alarm01SoundEffect.setLoopCount(QSoundEffect::Infinite); - } else { - alarm01SoundEffect.setLoopCount(1); - } - alarm01SoundEffect.play(); - } +void OverlayController::playAlarm01Sound( bool loop ) +{ + if ( !noSound && !alarm01SoundEffect.isPlaying() ) + { + if ( loop ) + { + alarm01SoundEffect.setLoopCount( QSoundEffect::Infinite ); + } + else + { + alarm01SoundEffect.setLoopCount( 1 ); + } + alarm01SoundEffect.play(); + } } -void OverlayController::setAlarm01SoundVolume(float vol) { - alarm01SoundEffect.setVolume(vol); +void OverlayController::setAlarm01SoundVolume( float vol ) +{ + alarm01SoundEffect.setVolume( vol ); } -void OverlayController::cancelAlarm01Sound() { - alarm01SoundEffect.stop(); +void OverlayController::cancelAlarm01Sound() +{ + alarm01SoundEffect.stop(); } - -} // namespace advconfig +} // namespace advsettings diff --git a/src/overlaycontroller.h b/src/overlaycontroller.h index f47a4a9..d4ebbf9 100644 --- a/src/overlaycontroller.h +++ b/src/overlaycontroller.h @@ -3,7 +3,8 @@ #include #include -// because of incompatibilities with QtOpenGL and GLEW we need to cherry pick includes +// because of incompatibilities with QtOpenGL and GLEW we need to cherry pick +// includes #include #include #include @@ -35,130 +36,166 @@ #include "tabcontrollers/UtilitiesTabController.h" #include "tabcontrollers/AccessibilityTabController.h" - - // application namespace -namespace advsettings { - -class OverlayController : public QObject { - Q_OBJECT - Q_PROPERTY(bool desktopMode READ isDesktopMode) +namespace advsettings +{ +class OverlayController : public QObject +{ + Q_OBJECT + Q_PROPERTY( bool desktopMode READ isDesktopMode ) public: - static constexpr const char* applicationKey = "matzman666.AdvancedSettings"; - static constexpr const char* applicationName = "Advanced Settings"; - static constexpr const char* applicationVersionString = "v2.5"; + static constexpr const char* applicationKey = "matzman666.AdvancedSettings"; + static constexpr const char* applicationName = "Advanced Settings"; + static constexpr const char* applicationVersionString = "v2.5"; private: - vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid; - vr::VROverlayHandle_t m_ulOverlayThumbnailHandle = vr::k_ulOverlayHandleInvalid; + vr::VROverlayHandle_t m_ulOverlayHandle = vr::k_ulOverlayHandleInvalid; + vr::VROverlayHandle_t m_ulOverlayThumbnailHandle + = vr::k_ulOverlayHandleInvalid; - std::unique_ptr m_pRenderControl; - std::unique_ptr m_pWindow; - std::unique_ptr m_pFbo; - std::unique_ptr m_pOpenGLContext; - std::unique_ptr m_pOffscreenSurface; + std::unique_ptr m_pRenderControl; + std::unique_ptr m_pWindow; + std::unique_ptr m_pFbo; + std::unique_ptr m_pOpenGLContext; + std::unique_ptr m_pOffscreenSurface; - std::unique_ptr m_pPumpEventsTimer; - std::unique_ptr m_pRenderTimer; - bool dashboardVisible = false; + std::unique_ptr m_pPumpEventsTimer; + std::unique_ptr m_pRenderTimer; + bool dashboardVisible = false; - QPoint m_ptLastMouse; - Qt::MouseButtons m_lastMouseButtons = 0; + QPoint m_ptLastMouse; + Qt::MouseButtons m_lastMouseButtons = 0; - bool desktopMode; - bool noSound; + bool desktopMode; + bool noSound; - QUrl m_runtimePathUrl; + QUrl m_runtimePathUrl; - utils::ChaperoneUtils m_chaperoneUtils; + utils::ChaperoneUtils m_chaperoneUtils; - QSoundEffect activationSoundEffect; - QSoundEffect focusChangedSoundEffect; - QSoundEffect alarm01SoundEffect; + QSoundEffect activationSoundEffect; + QSoundEffect focusChangedSoundEffect; + QSoundEffect alarm01SoundEffect; -public: // I know it's an ugly hack to make them public to enable external access, but I am too lazy to implement getters. - SteamVRTabController steamVRTabController; - ChaperoneTabController chaperoneTabController; - MoveCenterTabController moveCenterTabController; - FixFloorTabController fixFloorTabController; - AudioTabController audioTabController; - StatisticsTabController statisticsTabController; - SettingsTabController settingsTabController; - ReviveTabController reviveTabController; - UtilitiesTabController utilitiesTabController; - AccessibilityTabController accessibilityTabController; +public: // I know it's an ugly hack to make them public to enable external + // access, but I am too lazy to implement getters. + SteamVRTabController steamVRTabController; + ChaperoneTabController chaperoneTabController; + MoveCenterTabController moveCenterTabController; + FixFloorTabController fixFloorTabController; + AudioTabController audioTabController; + StatisticsTabController statisticsTabController; + SettingsTabController settingsTabController; + ReviveTabController reviveTabController; + UtilitiesTabController utilitiesTabController; + AccessibilityTabController accessibilityTabController; private: - OverlayController(bool desktopMode, bool noSound) : QObject(), desktopMode(desktopMode), noSound(noSound) {} - QPoint getMousePositionForEvent(vr::VREvent_Mouse_t mouse); + OverlayController( bool desktopMode, bool noSound ) + : QObject(), desktopMode( desktopMode ), noSound( noSound ) + { + } + QPoint getMousePositionForEvent( vr::VREvent_Mouse_t mouse ); public: - virtual ~OverlayController(); + virtual ~OverlayController(); - void Init(QQmlEngine* qmlEngine); - void Shutdown(); + void Init( QQmlEngine* qmlEngine ); + void Shutdown(); - bool isDashboardVisible() { - return dashboardVisible; - } + bool isDashboardVisible() + { + return dashboardVisible; + } - void SetWidget(QQuickItem* quickItem, const std::string& name, const std::string& key = ""); + void SetWidget( QQuickItem* quickItem, + const std::string& name, + const std::string& key = "" ); - void AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, unsigned axisId, float offset, bool adjustBounds = true, bool commit = true); - void AddOffsetToUniverseCenter(vr::ETrackingUniverseOrigin universe, float offset[3], bool adjustBounds = true, bool commit = true); - void RotateUniverseCenter(vr::ETrackingUniverseOrigin universe, float yAngle, bool adjustBounds = true, bool commit = true); // around y axis - void AddOffsetToCollisionBounds(unsigned axisId, float offset, bool commit = true); - void AddOffsetToCollisionBounds(float offset[3], bool commit = true); - void RotateCollisionBounds(float angle, bool commit = true); // around y axis + void AddOffsetToUniverseCenter( vr::ETrackingUniverseOrigin universe, + unsigned axisId, + float offset, + bool adjustBounds = true, + bool commit = true ); + void AddOffsetToUniverseCenter( vr::ETrackingUniverseOrigin universe, + float offset[3], + bool adjustBounds = true, + bool commit = true ); + void RotateUniverseCenter( vr::ETrackingUniverseOrigin universe, + float yAngle, + bool adjustBounds = true, + bool commit = true ); // around y axis + void AddOffsetToCollisionBounds( unsigned axisId, + float offset, + bool commit = true ); + void AddOffsetToCollisionBounds( float offset[3], bool commit = true ); + void RotateCollisionBounds( float angle, + bool commit = true ); // around y axis - bool isDesktopMode() { return desktopMode; }; + bool isDesktopMode() + { + return desktopMode; + }; - utils::ChaperoneUtils& chaperoneUtils() noexcept { return m_chaperoneUtils; } + utils::ChaperoneUtils& chaperoneUtils() noexcept + { + return m_chaperoneUtils; + } - Q_INVOKABLE QString getVersionString(); - Q_INVOKABLE QUrl getVRRuntimePathUrl(); + Q_INVOKABLE QString getVersionString(); + Q_INVOKABLE QUrl getVRRuntimePathUrl(); - Q_INVOKABLE bool soundDisabled(); + Q_INVOKABLE bool soundDisabled(); - const vr::VROverlayHandle_t& overlayHandle(); - const vr::VROverlayHandle_t& overlayThumbnailHandle(); + const vr::VROverlayHandle_t& overlayHandle(); + const vr::VROverlayHandle_t& overlayThumbnailHandle(); - bool pollNextEvent(vr::VROverlayHandle_t ulOverlayHandle, vr::VREvent_t* pEvent); + bool pollNextEvent( vr::VROverlayHandle_t ulOverlayHandle, + vr::VREvent_t* pEvent ); public slots: - void renderOverlay(); - void OnRenderRequest(); - void OnTimeoutPumpEvents(); + void renderOverlay(); + void OnRenderRequest(); + void OnTimeoutPumpEvents(); - void showKeyboard(QString existingText, unsigned long userValue = 0); + void showKeyboard( QString existingText, unsigned long userValue = 0 ); - void playActivationSound(); - void playFocusChangedSound(); - void playAlarm01Sound(bool loop = false); - void setAlarm01SoundVolume(float vol); - void cancelAlarm01Sound(); + void playActivationSound(); + void playFocusChangedSound(); + void playAlarm01Sound( bool loop = false ); + void setAlarm01SoundVolume( float vol ); + void cancelAlarm01Sound(); signals: - void keyBoardInputSignal(QString input, unsigned long userValue = 0); + void keyBoardInputSignal( QString input, unsigned long userValue = 0 ); private: - static QSettings* _appSettings; - static std::unique_ptr singleton; + static QSettings* _appSettings; + static std::unique_ptr singleton; public: - static OverlayController* getInstance() { - return singleton.get(); - } + static OverlayController* getInstance() + { + return singleton.get(); + } - static OverlayController* createInstance(bool desktopMode, bool noSound) { - singleton.reset(new advsettings::OverlayController(desktopMode, noSound)); - return singleton.get(); - } + static OverlayController* createInstance( bool desktopMode, bool noSound ) + { + singleton.reset( + new advsettings::OverlayController( desktopMode, noSound ) ); + return singleton.get(); + } - static QSettings* appSettings() { return _appSettings; } + static QSettings* appSettings() + { + return _appSettings; + } - static void setAppSettings(QSettings* settings) { _appSettings = settings; } + static void setAppSettings( QSettings* settings ) + { + _appSettings = settings; + } }; } // namespace advsettings diff --git a/src/tabcontrollers/AccessibilityTabController.cpp b/src/tabcontrollers/AccessibilityTabController.cpp index c2dfa9c..76ca2ba 100644 --- a/src/tabcontrollers/AccessibilityTabController.cpp +++ b/src/tabcontrollers/AccessibilityTabController.cpp @@ -3,95 +3,130 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { +namespace advsettings +{ +void AccessibilityTabController::initStage1() +{ + setTrackingUniverse( vr::VRCompositor()->GetTrackingSpace() ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + auto value = settings->value( "heightOffset", m_heightOffset ); + settings->endGroup(); + if ( value.isValid() && !value.isNull() ) + { + m_heightOffset = value.toFloat(); + emit heightOffsetChanged( m_heightOffset ); + } -void AccessibilityTabController::initStage1() { - setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace()); - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - auto value = settings->value("heightOffset", m_heightOffset); - settings->endGroup(); - if (value.isValid() && !value.isNull()) { - m_heightOffset = value.toFloat(); - emit heightOffsetChanged(m_heightOffset); - } - - reloadPttConfig(); + reloadPttConfig(); } -void AccessibilityTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void AccessibilityTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } -void AccessibilityTabController::setTrackingUniverse(int value) { - if (m_trackingUniverse != value) { - reset(); - m_trackingUniverse = value; - } +void AccessibilityTabController::setTrackingUniverse( int value ) +{ + if ( m_trackingUniverse != value ) + { + reset(); + m_trackingUniverse = value; + } } -float AccessibilityTabController::heightOffset() const { - return m_heightOffset; +float AccessibilityTabController::heightOffset() const +{ + return m_heightOffset; } -void AccessibilityTabController::setHeightOffset(float value, bool notify) { - if (std::abs(m_heightOffset - value) > 0.001) { - modHeightOffset(value - m_heightOffset, notify); - } +void AccessibilityTabController::setHeightOffset( float value, bool notify ) +{ + if ( std::abs( m_heightOffset - value ) > 0.001 ) + { + modHeightOffset( value - m_heightOffset, notify ); + } } -void AccessibilityTabController::modHeightOffset(float value, bool notify) { - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, -value, false); - m_heightOffset += value; - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - settings->setValue("heightOffset", m_heightOffset); - settings->endGroup(); - settings->sync(); - if (notify) { - emit heightOffsetChanged(m_heightOffset); - } +void AccessibilityTabController::modHeightOffset( float value, bool notify ) +{ + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, 1, -value, false ); + m_heightOffset += value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + settings->setValue( "heightOffset", m_heightOffset ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit heightOffsetChanged( m_heightOffset ); + } } - -void AccessibilityTabController::onPttStart() { - m_toggleHeightOffset = m_heightOffset; - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, m_toggleHeightOffset, false); +void AccessibilityTabController::onPttStart() +{ + m_toggleHeightOffset = m_heightOffset; + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + 1, + m_toggleHeightOffset, + false ); } -void AccessibilityTabController::onPttStop() { - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, -m_toggleHeightOffset, false); +void AccessibilityTabController::onPttStop() +{ + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + 1, + -m_toggleHeightOffset, + false ); } -void AccessibilityTabController::onPttDisabled() { - if (pttActive()) { - stopPtt(); - } - m_toggleHeightOffset = 0; +void AccessibilityTabController::onPttDisabled() +{ + if ( pttActive() ) + { + stopPtt(); + } + m_toggleHeightOffset = 0; } -void AccessibilityTabController::reset() { - std::lock_guard lock(eventLoopMutex); - vr::VRChaperoneSetup()->RevertWorkingCopy(); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, m_heightOffset, false, false); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - m_heightOffset = 0.0f; - emit heightOffsetChanged(m_heightOffset); +void AccessibilityTabController::reset() +{ + std::lock_guard lock( eventLoopMutex ); + vr::VRChaperoneSetup()->RevertWorkingCopy(); + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + 1, + m_heightOffset, + false, + false ); + vr::VRChaperoneSetup()->CommitWorkingCopy( vr::EChaperoneConfigFile_Live ); + m_heightOffset = 0.0f; + emit heightOffsetChanged( m_heightOffset ); } -void AccessibilityTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe) { - if (!eventLoopMutex.try_lock()) { - return; - } - if (settingsUpdateCounter >= 50) { - setTrackingUniverse((int)universe); - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } - checkPttStatus(); - eventLoopMutex.unlock(); +void AccessibilityTabController::eventLoopTick( + vr::ETrackingUniverseOrigin universe ) +{ + if ( !eventLoopMutex.try_lock() ) + { + return; + } + if ( settingsUpdateCounter >= 50 ) + { + setTrackingUniverse( ( int ) universe ); + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + } + checkPttStatus(); + eventLoopMutex.unlock(); } -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/AccessibilityTabController.h b/src/tabcontrollers/AccessibilityTabController.h index 4966102..65de4d2 100644 --- a/src/tabcontrollers/AccessibilityTabController.h +++ b/src/tabcontrollers/AccessibilityTabController.h @@ -5,46 +5,50 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; - -class AccessibilityTabController : public PttController { - Q_OBJECT - Q_PROPERTY(float heightOffset READ heightOffset WRITE setHeightOffset NOTIFY heightOffsetChanged) +class AccessibilityTabController : public PttController +{ + Q_OBJECT + Q_PROPERTY( float heightOffset READ heightOffset WRITE setHeightOffset + NOTIFY heightOffsetChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - int m_trackingUniverse = (int)vr::TrackingUniverseStanding; - float m_heightOffset = 0.0f; - float m_toggleHeightOffset = 0.0f; + int m_trackingUniverse = ( int ) vr::TrackingUniverseStanding; + float m_heightOffset = 0.0f; + float m_toggleHeightOffset = 0.0f; - unsigned settingsUpdateCounter = 0; + unsigned settingsUpdateCounter = 0; - QString getSettingsName() override { return "accessibilitySettings"; } - void onPttStart() override; - void onPttStop() override; - void onPttDisabled() override; + QString getSettingsName() override + { + return "accessibilitySettings"; + } + void onPttStart() override; + void onPttStop() override; + void onPttDisabled() override; public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); - void eventLoopTick(vr::ETrackingUniverseOrigin universe); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); + void eventLoopTick( vr::ETrackingUniverseOrigin universe ); - float heightOffset() const; + float heightOffset() const; public slots: - void setTrackingUniverse(int value); - void setHeightOffset(float value, bool notify = true); - void modHeightOffset(float value, bool notify = true); - void reset(); + void setTrackingUniverse( int value ); + void setHeightOffset( float value, bool notify = true ); + void modHeightOffset( float value, bool notify = true ); + void reset(); signals: - void heightOffsetChanged(float value); + void heightOffsetChanged( float value ); }; } // namespace advsettings diff --git a/src/tabcontrollers/AudioManager.h b/src/tabcontrollers/AudioManager.h index 9cc9dda..a60bc15 100644 --- a/src/tabcontrollers/AudioManager.h +++ b/src/tabcontrollers/AudioManager.h @@ -4,42 +4,45 @@ #include // application namespace -namespace advsettings { - +namespace advsettings +{ class AudioTabController; class AudioManager { public: - virtual ~AudioManager() {}; + virtual ~AudioManager(){}; - virtual void init(AudioTabController* controller) = 0; + virtual void init( AudioTabController* controller ) = 0; - virtual void setPlaybackDevice(const std::string& id, bool notify = true) = 0; - virtual std::string getPlaybackDevName() = 0; - virtual std::string getPlaybackDevId() = 0; + virtual void setPlaybackDevice( const std::string& id, bool notify = true ) + = 0; + virtual std::string getPlaybackDevName() = 0; + virtual std::string getPlaybackDevId() = 0; - virtual void setMirrorDevice(const std::string& id, bool notify = true) = 0; - virtual bool isMirrorValid() = 0; - virtual std::string getMirrorDevName() = 0; - virtual std::string getMirrorDevId() = 0; - virtual float getMirrorVolume() = 0; - virtual bool setMirrorVolume(float value) = 0; - virtual bool getMirrorMuted() = 0; - virtual bool setMirrorMuted(bool value) = 0; + virtual void setMirrorDevice( const std::string& id, bool notify = true ) + = 0; + virtual bool isMirrorValid() = 0; + virtual std::string getMirrorDevName() = 0; + virtual std::string getMirrorDevId() = 0; + virtual float getMirrorVolume() = 0; + virtual bool setMirrorVolume( float value ) = 0; + virtual bool getMirrorMuted() = 0; + virtual bool setMirrorMuted( bool value ) = 0; - virtual void setMicDevice(const std::string& id, bool notify = true) = 0; - virtual bool isMicValid() = 0; - virtual std::string getMicDevName() = 0; - virtual std::string getMicDevId() = 0; - virtual float getMicVolume() = 0; - virtual bool setMicVolume(float value) = 0; - virtual bool getMicMuted() = 0; - virtual bool setMicMuted(bool value) = 0; + virtual void setMicDevice( const std::string& id, bool notify = true ) = 0; + virtual bool isMicValid() = 0; + virtual std::string getMicDevName() = 0; + virtual std::string getMicDevId() = 0; + virtual float getMicVolume() = 0; + virtual bool setMicVolume( float value ) = 0; + virtual bool getMicMuted() = 0; + virtual bool setMicMuted( bool value ) = 0; - virtual std::vector> getRecordingDevices() = 0; - virtual std::vector> getPlaybackDevices() = 0; + virtual std::vector> + getRecordingDevices() = 0; + virtual std::vector> + getPlaybackDevices() = 0; }; -} - +} // namespace advsettings diff --git a/src/tabcontrollers/AudioTabController.cpp b/src/tabcontrollers/AudioTabController.cpp index ab79030..4998938 100644 --- a/src/tabcontrollers/AudioTabController.cpp +++ b/src/tabcontrollers/AudioTabController.cpp @@ -3,717 +3,975 @@ #include #include "../overlaycontroller.h" #ifdef _WIN32 - #include "audiomanager/AudioManagerWindows.h" +# include "audiomanager/AudioManagerWindows.h" #else - #include "audiomanager/AudioManagerDummy.h" +# include "audiomanager/AudioManagerDummy.h" #endif // application namespace -namespace advsettings { - - void AudioTabController::initStage1() { - vr::EVRSettingsError vrSettingsError; - #ifdef _WIN32 - audioManager.reset(new AudioManagerWindows()); - #else - audioManager.reset(new AudioManagerDummy()); - #endif - audioManager->init(this); - m_playbackDevices = audioManager->getPlaybackDevices(); - m_recordingDevices = audioManager->getRecordingDevices(); - findPlaybackDeviceIndex(audioManager->getPlaybackDevId(), false); - char deviceId[1024]; - vr::VRSettings()->GetString(vr::k_pch_audio_Section, vr::k_pch_audio_OnPlaybackMirrorDevice_String, deviceId, 1024, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_audio_OnPlaybackMirrorDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - audioManager->setMirrorDevice(deviceId); - findMirrorDeviceIndex(audioManager->getMirrorDevId(), false); - lastMirrorDevId = deviceId; - m_mirrorVolume = audioManager->getMirrorVolume(); - m_mirrorMuted = audioManager->getMirrorMuted(); - } - findMicDeviceIndex(audioManager->getMicDevId(), false); - m_micVolume = audioManager->getMicVolume(); - m_micMuted = audioManager->getMicMuted(); - reloadPttProfiles(); - reloadPttConfig(); - reloadAudioProfiles(); - reloadAudioSettings(); - eventLoopTick(); - } - - - void AudioTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; - - std::string notifKey = std::string(OverlayController::applicationKey) + ".pptnotification"; - vr::VROverlayError overlayError = vr::VROverlay()->CreateOverlay(notifKey.c_str(), notifKey.c_str(), &m_ulNotificationOverlayHandle); - if (overlayError == vr::VROverlayError_None) { - std::string notifIconPath = QApplication::applicationDirPath().toStdString() + "/res/qml/ptt_notification.png"; - if (QFile::exists(QString::fromStdString(notifIconPath))) { - vr::VROverlay()->SetOverlayFromFile(m_ulNotificationOverlayHandle, notifIconPath.c_str()); - vr::VROverlay()->SetOverlayWidthInMeters(m_ulNotificationOverlayHandle, 0.02f); - vr::HmdMatrix34_t notificationTransform = {{ - {1.0f, 0.0f, 0.0f, 0.12f}, - {0.0f, 1.0f, 0.0f, 0.08f}, - {0.0f, 0.0f, 1.0f, -0.3f} - }}; - vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative(m_ulNotificationOverlayHandle, vr::k_unTrackedDeviceIndex_Hmd, ¬ificationTransform); - } else { - LOG(ERROR) << "Could not find notification icon \"" << notifIconPath << "\""; - } - } else { - LOG(ERROR) << "Could not create ptt notification overlay: " << vr::VROverlay()->GetOverlayErrorNameFromEnum(overlayError); - } - } - - void AudioTabController::reloadAudioSettings() { - std::lock_guard lock(eventLoopMutex); - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - setMicProximitySensorCanMute(settings->value("micProximitySensorCanMute", false).toBool(), false); - setMicReversePtt(settings->value("micReversePtt", false).toBool(), false); - settings->endGroup(); - } - - void AudioTabController::saveAudioSettings() { - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - settings->setValue("micProximitySensorCanMute", micProximitySensorCanMute()); - settings->setValue("micReversePtt", micReversePtt()); - settings->endGroup(); - settings->sync(); - } - - - float AudioTabController::mirrorVolume() const { - return m_mirrorVolume; - } - - - bool AudioTabController::mirrorMuted() const { - return m_mirrorMuted; - } - - - float AudioTabController::micVolume() const { - return m_micVolume; - } - - - bool AudioTabController::micMuted() const { - return m_micMuted; - } - - bool AudioTabController::micProximitySensorCanMute() const { - return m_micProximitySensorCanMute; - } - - bool AudioTabController::micReversePtt() const { - return m_micReversePtt; - } - - void AudioTabController::eventLoopTick() { - if (!eventLoopMutex.try_lock()) { - return; - } - if (settingsUpdateCounter >= 50) { - if (m_micProximitySensorCanMute) { - vr::VRControllerState_t controllerState; - if (vr::VRSystem()->GetControllerState(vr::k_unTrackedDeviceIndex_Hmd, &controllerState, sizeof(vr::VRControllerState_t))) { - if ((controllerState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor)) == 0) { - if (!m_micMuted) { - setMicMuted(true); - } - } else { - if (m_micMuted) { - setMicMuted(false); - } - } - } else { - if (!parent->isDashboardVisible()) { - LOG(ERROR) << "Could not read proximity sensor!"; - } - } - } - vr::EVRSettingsError vrSettingsError; - char mirrorDeviceId[1024]; - vr::VRSettings()->GetString(vr::k_pch_audio_Section, vr::k_pch_audio_OnPlaybackMirrorDevice_String, mirrorDeviceId, 1024, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_audio_OnPlaybackMirrorDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - if (lastMirrorDevId.compare(mirrorDeviceId) != 0) { - audioManager->setMirrorDevice(mirrorDeviceId); - findMirrorDeviceIndex(audioManager->getMirrorDevId()); - lastMirrorDevId = mirrorDeviceId; - } - if (m_mirrorDeviceIndex >= 0) { - setMirrorVolume(audioManager->getMirrorVolume()); - setMirrorMuted(audioManager->getMirrorMuted()); - } - if (m_recordingDeviceIndex >= 0) { - setMicVolume(audioManager->getMicVolume()); - setMicMuted(audioManager->getMicMuted()); - } - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } - checkPttStatus(); - eventLoopMutex.unlock(); - } - - bool AudioTabController::pttChangeValid() { - return audioManager && audioManager->isMicValid(); - } - - void AudioTabController::onPttStart() { - if (m_micReversePtt) { - setMicMuted(true); - } else { - setMicMuted(false); - } - } - - void AudioTabController::onPttEnabled() { - if (m_micReversePtt) { - setMicMuted(false); - } else { - setMicMuted(true); - } - } - - void AudioTabController::onPttStop() { - if (m_micReversePtt) { - setMicMuted(false); - } else { - setMicMuted(true); - } - } - - void AudioTabController::onPttDisabled() { - setMicMuted(false); - } - - void AudioTabController::setMirrorVolume(float value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_mirrorVolume) { - m_mirrorVolume = value; - if (audioManager->isMirrorValid()) { - audioManager->setMirrorVolume(value); - } - if (notify) { - emit mirrorVolumeChanged(value); - } - } - } - - void AudioTabController::setMirrorMuted(bool value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_mirrorMuted) { - m_mirrorMuted = value; - if (audioManager->isMirrorValid()) { - audioManager->setMirrorMuted(value); - } - if (notify) { - emit mirrorMutedChanged(value); - } - } - } - - void AudioTabController::setMicVolume(float value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_micVolume) { - m_micVolume = value; - if (audioManager->isMicValid()) { - audioManager->setMicVolume(value); - } - if (notify) { - emit micVolumeChanged(value); - } - } - } - - void AudioTabController::setMicMuted(bool value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_micMuted) { - m_micMuted = value; - if (audioManager->isMicValid()) { - audioManager->setMicMuted(value); - } - if (notify) { - emit micMutedChanged(value); - } - } - } - - void AudioTabController::setMicProximitySensorCanMute(bool value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_micProximitySensorCanMute) { - m_micProximitySensorCanMute = value; - saveAudioSettings(); - if (notify) { - emit micProximitySensorCanMuteChanged(value); - } - } - } - - void AudioTabController::setMicReversePtt(bool value, bool notify) { - std::lock_guard lock(eventLoopMutex); - if (value != m_micReversePtt) { - m_micReversePtt = value; - saveAudioSettings(); - if (m_pttEnabled) { - if (m_pttActive) { - setMicMuted(value); - } else { - setMicMuted(!value); - } - } - if (notify) { - emit micReversePttChanged(value); - } - } - } - - void AudioTabController::onNewRecordingDevice() { - findMicDeviceIndex(audioManager->getMicDevId()); - } - - void AudioTabController::onNewPlaybackDevice() { - findPlaybackDeviceIndex(audioManager->getPlaybackDevId()); - } - - void AudioTabController::onNewMirrorDevice() { - auto devid = audioManager->getMirrorDevId(); - if (devid.empty()) { - m_mirrorDeviceIndex = -1; - emit mirrorDeviceIndexChanged(m_mirrorDeviceIndex); - } else { - findMirrorDeviceIndex(devid); - } - } - - void AudioTabController::onDeviceStateChanged() { - // I'm too lazy to find out which device has changed, so let's invalidate all device lists - m_playbackDevices = audioManager->getPlaybackDevices(); - m_recordingDevices = audioManager->getRecordingDevices(); - findPlaybackDeviceIndex(audioManager->getPlaybackDevId(), false); - findMirrorDeviceIndex(audioManager->getMirrorDevId(), false); - findMicDeviceIndex(audioManager->getMicDevId(), false); - emit playbackDeviceListChanged(); - emit recordingDeviceListChanged(); - } - - int AudioTabController::getPlaybackDeviceCount() { - return static_cast(m_playbackDevices.size()); - } - - QString AudioTabController::getPlaybackDeviceName(int index) { - if (index > 0 && static_cast(index) < m_playbackDevices.size()) { - return QString::fromStdString(m_playbackDevices[static_cast(index)].second); - } else { - return ""; - } - } - - int AudioTabController::getRecordingDeviceCount() { - return static_cast(m_recordingDevices.size()); - } - - QString AudioTabController::getRecordingDeviceName(int index) { - if (index > 0 && static_cast(index) < m_playbackDevices.size()) { - return QString::fromStdString(m_recordingDevices[static_cast(index)].second); - } else { - return ""; - } - } - - - int AudioTabController::playbackDeviceIndex() const { - return m_playbackDeviceIndex; - } - - int AudioTabController::mirrorDeviceIndex() const { - return m_mirrorDeviceIndex; - } - - int AudioTabController::micDeviceIndex() const { - return m_recordingDeviceIndex; - } - - void AudioTabController::setPlaybackDeviceIndex(int index, bool notify) { - if (index != m_playbackDeviceIndex) { - if (index > 0 && static_cast(index) < m_playbackDevices.size() && index != m_mirrorDeviceIndex) { - vr::EVRSettingsError vrSettingsError; - //Applys Audio Switch IN VR - vr::VRSettings()->SetString(vr::k_pch_audio_Section, - vr::k_pch_audio_OnPlaybackDevice_String, - m_playbackDevices[static_cast(index)].first.c_str(), - &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not write \"" << vr::k_pch_audio_OnPlaybackDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(); - audioManager->setPlaybackDevice(m_playbackDevices[static_cast(index)].first, notify); - } - } else if (notify) { - emit playbackDeviceIndexChanged(m_playbackDeviceIndex); - } - } - } - - void AudioTabController::setMirrorDeviceIndex(int index, bool notify) { - if (index != m_mirrorDeviceIndex) { - if (index == -1) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_audio_Section, vr::k_pch_audio_OnPlaybackMirrorDevice_String, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_audio_OnPlaybackMirrorDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(); - audioManager->setMirrorDevice("", notify); - } - } else if (index > 0 && static_cast(index) < m_playbackDevices.size() && index != m_playbackDeviceIndex && index != m_mirrorDeviceIndex) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetString(vr::k_pch_audio_Section, - vr::k_pch_audio_OnPlaybackMirrorDevice_String, - m_playbackDevices[static_cast(index)].first.c_str(), - &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not write \"" << vr::k_pch_audio_OnPlaybackMirrorDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(); - audioManager->setMirrorDevice(m_playbackDevices[static_cast(index)].first, notify); - } - } else if (notify) { - emit mirrorDeviceIndexChanged(m_mirrorDeviceIndex); - } - } - } - - void AudioTabController::setMicDeviceIndex(int index, bool notify) { - if (index != m_recordingDeviceIndex) { - if (index > 0 && static_cast(index) < m_recordingDevices.size()) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetString(vr::k_pch_audio_Section, vr::k_pch_audio_OnRecordDevice_String, m_recordingDevices[static_cast(index)].first.c_str(), &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not write \"" << vr::k_pch_audio_OnRecordDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(); - audioManager->setMicDevice(m_recordingDevices[static_cast(index)].first, notify); - } - } else if (notify) { - emit micDeviceIndexChanged(m_recordingDeviceIndex); - } - } - } - - void AudioTabController::findPlaybackDeviceIndex(std::string id, bool notify) { - int i = 0; - bool deviceFound = false; - for (auto d : m_playbackDevices) { - if (d.first.compare(id) == 0) { - deviceFound = true; - break; - } else { - ++i; - } - } - if (deviceFound) { - m_playbackDeviceIndex = i; - if (notify) { - emit playbackDeviceIndexChanged(i); - } - } - } - - void AudioTabController::findMirrorDeviceIndex(std::string id, bool notify) { - int i = 0; - bool deviceFound = false; - for (auto d : m_playbackDevices) { - if (d.first.compare(id) == 0) { - deviceFound = true; - break; - } else { - ++i; - } - } - if (deviceFound && m_mirrorDeviceIndex != i) { - m_mirrorDeviceIndex = i; - if (notify) { - emit mirrorDeviceIndexChanged(i); - } - } - } - - void AudioTabController::findMicDeviceIndex(std::string id, bool notify) { - int i = 0; - bool deviceFound = false; - for (auto d : m_recordingDevices) { - if (d.first.compare(id) == 0) { - deviceFound = true; - break; - } else { - ++i; - } - } - if (deviceFound) { - m_recordingDeviceIndex = i; - if (notify) { - emit micDeviceIndexChanged(i); - } - } - } - - - /*AUDIO PROFILE FUNCTIONS - The following section includes the code required to save and load Audio Profiles. - - Saved Settings Include: - Playback Device - Mirror Device - Mirror Vol - Microphone - Microphone Volume - Profile Name - - */ - - /* - Name: reloadAudioProfiles - - Inputs: args: none - other: Reads audioProfiles setting from file - - - Output: return:none - other:none - - Description: Clears working copy, and reloads from Settings file. - - */ - void AudioTabController::reloadAudioProfiles() { - audioProfiles.clear(); - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - auto profileCount = settings->beginReadArray("audioProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - audioProfiles.emplace_back(); - auto& entry = audioProfiles[static_cast(i)]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.playbackName = settings->value("playbackName").toString().toStdString(); - entry.micName = settings->value("micName").toString().toStdString(); - entry.mirrorName = settings->value("mirrorName").toString().toStdString(); - entry.micMute = settings->value("micMute", false).toBool(); - entry.mirrorMute = settings->value("mirrorMute", false).toBool(); - entry.mirrorVol = settings->value("mirrorVol", 0.0).toFloat(); - entry.micVol = settings->value("micVol", 1.0).toFloat(); - } - settings->endArray(); - settings->endGroup(); - } - - /* - Name: saveAudioProfile - - Inputs: args: none - other: none - - - Output: return: none - other: Writes audioProfiles setting to file - - Description: saves a copy of the audio profiles from working to Settings file. - - */ - void AudioTabController::saveAudioProfiles() { - auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - settings->beginWriteArray("audioProfiles"); - int i = 0; - for (auto& p : audioProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("playbackName", QString::fromStdString(p.playbackName)); - settings->setValue("micName", QString::fromStdString(p.micName)); - settings->setValue("mirrorName", QString::fromStdString(p.mirrorName)); - settings->setValue("micMute", p.micMute); - settings->setValue("mirrorMute", p.mirrorMute); - settings->setValue("micVol", p.micVol); - settings->setValue("mirrorVol", p.mirrorVol); - i++; - } - settings->endArray(); - settings->endGroup(); - } - - - - /* - Name: addAudioProfile - - Inputs: args: Qstring name - the name of the audio profile - other: none - - - Output: return: none - other: audioProfile to audioProfiles array - - Description: Creates an audioProfile, and adds it to the working copy of audioProfiles[] - - */ - - void AudioTabController::addAudioProfile(QString name) { - AudioProfile* profile = nullptr; - for (auto& p : audioProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } - } - if (!profile) { - auto i = audioProfiles.size(); - audioProfiles.emplace_back(); - profile = &audioProfiles[i]; - } - profile->profileName = name.toStdString(); - profile->playbackName = getPlaybackDeviceName(m_playbackDeviceIndex).toStdString(); - profile->mirrorName = getPlaybackDeviceName(m_mirrorDeviceIndex).toStdString(); - profile->micName = getRecordingDeviceName(m_recordingDeviceIndex).toStdString(); - profile->micMute = m_micMuted; - profile->mirrorMute = m_mirrorMuted; - profile->mirrorVol = m_mirrorVolume; - profile->micVol = m_micVolume; - - saveAudioProfiles(); - OverlayController::appSettings()->sync(); - emit audioProfilesUpdated(); - } - - - /* - Name: applyAudioProfile - - Inputs: args: index - index of audioProfile in audioProfiles[] - other: audioProfile based on index - - - Output: return: none - other: none - - Description: Applies the required logic to activate the audio profile. - - */ - //TODO Remembers Mirror Volume when switching to main volume. - void AudioTabController::applyAudioProfile(unsigned index) { - if (index < audioProfiles.size()) { - auto& profile = audioProfiles[index]; - int mInd = getMirrorIndex(profile.mirrorName); - int pInd = getPlaybackIndex(profile.playbackName); - - //Needed to keep remembering when swtiching from mirror/main etc. - setMicMuted(false, false); - setMirrorMuted(false, false); - - if ((m_playbackDeviceIndex == mInd) && (m_mirrorDeviceIndex == pInd)) { - setMirrorDeviceIndex(-1, true); - } - if (m_playbackDeviceIndex == mInd) { - setPlaybackDeviceIndex(pInd, true); - setMirrorDeviceIndex(mInd, true); - } - else { - setMirrorDeviceIndex(mInd, true); - setPlaybackDeviceIndex(pInd, true); - } - setMicDeviceIndex(getRecordingIndex(profile.micName), true); - setMicMuted(profile.micMute, true); - setMirrorMuted(profile.mirrorMute, true); - setMicVolume(profile.micVol, true); - setMirrorVolume(profile.mirrorVol, true); - - } - } - - /* - Name: deleteAudioProfile - - Inputs: args: index - index of audioProfile in audioProfiles[] - other: audioProfile based on index - - - Output: return: none - other: none - - Description: Removes selected Audio Profile - - */ - void AudioTabController::deleteAudioProfile(unsigned index) { - if (index < audioProfiles.size()) { - auto pos = audioProfiles.begin() + index; - audioProfiles.erase(pos); - saveAudioProfiles(); - OverlayController::appSettings()->sync(); - emit audioProfilesUpdated(); - } - } - - - unsigned AudioTabController::getAudioProfileCount() { - return static_cast(audioProfiles.size()); +namespace advsettings +{ +void AudioTabController::initStage1() +{ + vr::EVRSettingsError vrSettingsError; +#ifdef _WIN32 + audioManager.reset( new AudioManagerWindows() ); +#else + audioManager.reset( new AudioManagerDummy() ); +#endif + audioManager->init( this ); + m_playbackDevices = audioManager->getPlaybackDevices(); + m_recordingDevices = audioManager->getRecordingDevices(); + findPlaybackDeviceIndex( audioManager->getPlaybackDevId(), false ); + char deviceId[1024]; + vr::VRSettings()->GetString( vr::k_pch_audio_Section, + vr::k_pch_audio_OnPlaybackMirrorDevice_String, + deviceId, + 1024, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_audio_OnPlaybackMirrorDevice_String + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + audioManager->setMirrorDevice( deviceId ); + findMirrorDeviceIndex( audioManager->getMirrorDevId(), false ); + lastMirrorDevId = deviceId; + m_mirrorVolume = audioManager->getMirrorVolume(); + m_mirrorMuted = audioManager->getMirrorMuted(); + } + findMicDeviceIndex( audioManager->getMicDevId(), false ); + m_micVolume = audioManager->getMicVolume(); + m_micMuted = audioManager->getMicMuted(); + reloadPttProfiles(); + reloadPttConfig(); + reloadAudioProfiles(); + reloadAudioSettings(); + eventLoopTick(); +} + +void AudioTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; + + std::string notifKey + = std::string( OverlayController::applicationKey ) + ".pptnotification"; + vr::VROverlayError overlayError = vr::VROverlay()->CreateOverlay( + notifKey.c_str(), notifKey.c_str(), &m_ulNotificationOverlayHandle ); + if ( overlayError == vr::VROverlayError_None ) + { + std::string notifIconPath + = QApplication::applicationDirPath().toStdString() + + "/res/qml/ptt_notification.png"; + if ( QFile::exists( QString::fromStdString( notifIconPath ) ) ) + { + vr::VROverlay()->SetOverlayFromFile( m_ulNotificationOverlayHandle, + notifIconPath.c_str() ); + vr::VROverlay()->SetOverlayWidthInMeters( + m_ulNotificationOverlayHandle, 0.02f ); + vr::HmdMatrix34_t notificationTransform + = { { { 1.0f, 0.0f, 0.0f, 0.12f }, + { 0.0f, 1.0f, 0.0f, 0.08f }, + { 0.0f, 0.0f, 1.0f, -0.3f } } }; + vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative( + m_ulNotificationOverlayHandle, + vr::k_unTrackedDeviceIndex_Hmd, + ¬ificationTransform ); } + else + { + LOG( ERROR ) << "Could not find notification icon \"" + << notifIconPath << "\""; + } + } + else + { + LOG( ERROR ) << "Could not create ptt notification overlay: " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( + overlayError ); + } +} - QString AudioTabController::getAudioProfileName(unsigned index) { - if (index < audioProfiles.size()) { - return QString::fromStdString(audioProfiles[index].profileName); - } - return ""; - } +void AudioTabController::reloadAudioSettings() +{ + std::lock_guard lock( eventLoopMutex ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + setMicProximitySensorCanMute( + settings->value( "micProximitySensorCanMute", false ).toBool(), false ); + setMicReversePtt( settings->value( "micReversePtt", false ).toBool(), + false ); + settings->endGroup(); +} - /* - Name: getPlaybackIndex, getRecordingIndex, and getMirrorIndex +void AudioTabController::saveAudioSettings() +{ + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + settings->setValue( "micProximitySensorCanMute", + micProximitySensorCanMute() ); + settings->setValue( "micReversePtt", micReversePtt() ); + settings->endGroup(); + settings->sync(); +} - input: string, of microphone/playback device name - output: integer for use In: setMicDeviceIndex(int,bool), setMirrorDeviceIndex(int,bool) setPlayBackDeviceIndex(int,bool) +float AudioTabController::mirrorVolume() const +{ + return m_mirrorVolume; +} - description: Gets proper index value for selecting specific devices. - */ - int AudioTabController::getPlaybackIndex(std::string str) { - //Unsigned to avoid two casts. i won't be negative because we only increment it. - for (unsigned int i = 0; i < m_playbackDevices.size(); i++) { - if (str.compare(m_playbackDevices[i].second)==0) { - return static_cast(i); - } - } - return m_playbackDeviceIndex; - } +bool AudioTabController::mirrorMuted() const +{ + return m_mirrorMuted; +} - int AudioTabController::getRecordingIndex(std::string str) { - //Unsigned to avoid two casts. i won't be negative because we only increment it. - for (unsigned int i = 0; i < m_recordingDevices.size(); i++) { - if (str.compare(m_recordingDevices[i].second) == 0) { - return static_cast(i); - } - } - return m_recordingDeviceIndex; - } +float AudioTabController::micVolume() const +{ + return m_micVolume; +} - int AudioTabController::getMirrorIndex(std::string str) { - //Unsigned to avoid two casts. i won't be negative because we only increment it. - for (unsigned int i = 0; i < m_playbackDevices.size(); i++) { - if (str.compare(m_playbackDevices[i].second) == 0) { - return static_cast(i); - } - } - return -1; - } +bool AudioTabController::micMuted() const +{ + return m_micMuted; +} - /* ---------------------------*/ +bool AudioTabController::micProximitySensorCanMute() const +{ + return m_micProximitySensorCanMute; +} - /*----------------*/ +bool AudioTabController::micReversePtt() const +{ + return m_micReversePtt; +} -} // namespace advconfig +void AudioTabController::eventLoopTick() +{ + if ( !eventLoopMutex.try_lock() ) + { + return; + } + if ( settingsUpdateCounter >= 50 ) + { + if ( m_micProximitySensorCanMute ) + { + vr::VRControllerState_t controllerState; + if ( vr::VRSystem()->GetControllerState( + vr::k_unTrackedDeviceIndex_Hmd, + &controllerState, + sizeof( vr::VRControllerState_t ) ) ) + { + if ( ( controllerState.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ProximitySensor ) ) + == 0 ) + { + if ( !m_micMuted ) + { + setMicMuted( true ); + } + } + else + { + if ( m_micMuted ) + { + setMicMuted( false ); + } + } + } + else + { + if ( !parent->isDashboardVisible() ) + { + LOG( ERROR ) << "Could not read proximity sensor!"; + } + } + } + vr::EVRSettingsError vrSettingsError; + char mirrorDeviceId[1024]; + vr::VRSettings()->GetString( + vr::k_pch_audio_Section, + vr::k_pch_audio_OnPlaybackMirrorDevice_String, + mirrorDeviceId, + 1024, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_audio_OnPlaybackMirrorDevice_String + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + if ( lastMirrorDevId.compare( mirrorDeviceId ) != 0 ) + { + audioManager->setMirrorDevice( mirrorDeviceId ); + findMirrorDeviceIndex( audioManager->getMirrorDevId() ); + lastMirrorDevId = mirrorDeviceId; + } + if ( m_mirrorDeviceIndex >= 0 ) + { + setMirrorVolume( audioManager->getMirrorVolume() ); + setMirrorMuted( audioManager->getMirrorMuted() ); + } + if ( m_recordingDeviceIndex >= 0 ) + { + setMicVolume( audioManager->getMicVolume() ); + setMicMuted( audioManager->getMicMuted() ); + } + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + } + checkPttStatus(); + eventLoopMutex.unlock(); +} + +bool AudioTabController::pttChangeValid() +{ + return audioManager && audioManager->isMicValid(); +} + +void AudioTabController::onPttStart() +{ + if ( m_micReversePtt ) + { + setMicMuted( true ); + } + else + { + setMicMuted( false ); + } +} + +void AudioTabController::onPttEnabled() +{ + if ( m_micReversePtt ) + { + setMicMuted( false ); + } + else + { + setMicMuted( true ); + } +} + +void AudioTabController::onPttStop() +{ + if ( m_micReversePtt ) + { + setMicMuted( false ); + } + else + { + setMicMuted( true ); + } +} + +void AudioTabController::onPttDisabled() +{ + setMicMuted( false ); +} + +void AudioTabController::setMirrorVolume( float value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_mirrorVolume ) + { + m_mirrorVolume = value; + if ( audioManager->isMirrorValid() ) + { + audioManager->setMirrorVolume( value ); + } + if ( notify ) + { + emit mirrorVolumeChanged( value ); + } + } +} + +void AudioTabController::setMirrorMuted( bool value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_mirrorMuted ) + { + m_mirrorMuted = value; + if ( audioManager->isMirrorValid() ) + { + audioManager->setMirrorMuted( value ); + } + if ( notify ) + { + emit mirrorMutedChanged( value ); + } + } +} + +void AudioTabController::setMicVolume( float value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_micVolume ) + { + m_micVolume = value; + if ( audioManager->isMicValid() ) + { + audioManager->setMicVolume( value ); + } + if ( notify ) + { + emit micVolumeChanged( value ); + } + } +} + +void AudioTabController::setMicMuted( bool value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_micMuted ) + { + m_micMuted = value; + if ( audioManager->isMicValid() ) + { + audioManager->setMicMuted( value ); + } + if ( notify ) + { + emit micMutedChanged( value ); + } + } +} + +void AudioTabController::setMicProximitySensorCanMute( bool value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_micProximitySensorCanMute ) + { + m_micProximitySensorCanMute = value; + saveAudioSettings(); + if ( notify ) + { + emit micProximitySensorCanMuteChanged( value ); + } + } +} + +void AudioTabController::setMicReversePtt( bool value, bool notify ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_micReversePtt ) + { + m_micReversePtt = value; + saveAudioSettings(); + if ( m_pttEnabled ) + { + if ( m_pttActive ) + { + setMicMuted( value ); + } + else + { + setMicMuted( !value ); + } + } + if ( notify ) + { + emit micReversePttChanged( value ); + } + } +} + +void AudioTabController::onNewRecordingDevice() +{ + findMicDeviceIndex( audioManager->getMicDevId() ); +} + +void AudioTabController::onNewPlaybackDevice() +{ + findPlaybackDeviceIndex( audioManager->getPlaybackDevId() ); +} + +void AudioTabController::onNewMirrorDevice() +{ + auto devid = audioManager->getMirrorDevId(); + if ( devid.empty() ) + { + m_mirrorDeviceIndex = -1; + emit mirrorDeviceIndexChanged( m_mirrorDeviceIndex ); + } + else + { + findMirrorDeviceIndex( devid ); + } +} + +void AudioTabController::onDeviceStateChanged() +{ + // I'm too lazy to find out which device has changed, so let's invalidate + // all device lists + m_playbackDevices = audioManager->getPlaybackDevices(); + m_recordingDevices = audioManager->getRecordingDevices(); + findPlaybackDeviceIndex( audioManager->getPlaybackDevId(), false ); + findMirrorDeviceIndex( audioManager->getMirrorDevId(), false ); + findMicDeviceIndex( audioManager->getMicDevId(), false ); + emit playbackDeviceListChanged(); + emit recordingDeviceListChanged(); +} + +int AudioTabController::getPlaybackDeviceCount() +{ + return static_cast( m_playbackDevices.size() ); +} + +QString AudioTabController::getPlaybackDeviceName( int index ) +{ + if ( index > 0 && static_cast( index ) < m_playbackDevices.size() ) + { + return QString::fromStdString( + m_playbackDevices[static_cast( index )].second ); + } + else + { + return ""; + } +} + +int AudioTabController::getRecordingDeviceCount() +{ + return static_cast( m_recordingDevices.size() ); +} + +QString AudioTabController::getRecordingDeviceName( int index ) +{ + if ( index > 0 && static_cast( index ) < m_playbackDevices.size() ) + { + return QString::fromStdString( + m_recordingDevices[static_cast( index )].second ); + } + else + { + return ""; + } +} + +int AudioTabController::playbackDeviceIndex() const +{ + return m_playbackDeviceIndex; +} + +int AudioTabController::mirrorDeviceIndex() const +{ + return m_mirrorDeviceIndex; +} + +int AudioTabController::micDeviceIndex() const +{ + return m_recordingDeviceIndex; +} + +void AudioTabController::setPlaybackDeviceIndex( int index, bool notify ) +{ + if ( index != m_playbackDeviceIndex ) + { + if ( index > 0 + && static_cast( index ) < m_playbackDevices.size() + && index != m_mirrorDeviceIndex ) + { + vr::EVRSettingsError vrSettingsError; + // Applys Audio Switch IN VR + vr::VRSettings()->SetString( + vr::k_pch_audio_Section, + vr::k_pch_audio_OnPlaybackDevice_String, + m_playbackDevices[static_cast( index )].first.c_str(), + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not write \"" + << vr::k_pch_audio_OnPlaybackDevice_String << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync(); + audioManager->setPlaybackDevice( + m_playbackDevices[static_cast( index )].first, + notify ); + } + } + else if ( notify ) + { + emit playbackDeviceIndexChanged( m_playbackDeviceIndex ); + } + } +} + +void AudioTabController::setMirrorDeviceIndex( int index, bool notify ) +{ + if ( index != m_mirrorDeviceIndex ) + { + if ( index == -1 ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_audio_Section, + vr::k_pch_audio_OnPlaybackMirrorDevice_String, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not remove \"" + << vr::k_pch_audio_OnPlaybackMirrorDevice_String + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync(); + audioManager->setMirrorDevice( "", notify ); + } + } + else if ( index > 0 + && static_cast( index ) < m_playbackDevices.size() + && index != m_playbackDeviceIndex + && index != m_mirrorDeviceIndex ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetString( + vr::k_pch_audio_Section, + vr::k_pch_audio_OnPlaybackMirrorDevice_String, + m_playbackDevices[static_cast( index )].first.c_str(), + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not write \"" + << vr::k_pch_audio_OnPlaybackMirrorDevice_String + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync(); + audioManager->setMirrorDevice( + m_playbackDevices[static_cast( index )].first, + notify ); + } + } + else if ( notify ) + { + emit mirrorDeviceIndexChanged( m_mirrorDeviceIndex ); + } + } +} + +void AudioTabController::setMicDeviceIndex( int index, bool notify ) +{ + if ( index != m_recordingDeviceIndex ) + { + if ( index > 0 + && static_cast( index ) < m_recordingDevices.size() ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetString( + vr::k_pch_audio_Section, + vr::k_pch_audio_OnRecordDevice_String, + m_recordingDevices[static_cast( index )].first.c_str(), + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not write \"" + << vr::k_pch_audio_OnRecordDevice_String << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync(); + audioManager->setMicDevice( + m_recordingDevices[static_cast( index )].first, + notify ); + } + } + else if ( notify ) + { + emit micDeviceIndexChanged( m_recordingDeviceIndex ); + } + } +} + +void AudioTabController::findPlaybackDeviceIndex( std::string id, bool notify ) +{ + int i = 0; + bool deviceFound = false; + for ( auto d : m_playbackDevices ) + { + if ( d.first.compare( id ) == 0 ) + { + deviceFound = true; + break; + } + else + { + ++i; + } + } + if ( deviceFound ) + { + m_playbackDeviceIndex = i; + if ( notify ) + { + emit playbackDeviceIndexChanged( i ); + } + } +} + +void AudioTabController::findMirrorDeviceIndex( std::string id, bool notify ) +{ + int i = 0; + bool deviceFound = false; + for ( auto d : m_playbackDevices ) + { + if ( d.first.compare( id ) == 0 ) + { + deviceFound = true; + break; + } + else + { + ++i; + } + } + if ( deviceFound && m_mirrorDeviceIndex != i ) + { + m_mirrorDeviceIndex = i; + if ( notify ) + { + emit mirrorDeviceIndexChanged( i ); + } + } +} + +void AudioTabController::findMicDeviceIndex( std::string id, bool notify ) +{ + int i = 0; + bool deviceFound = false; + for ( auto d : m_recordingDevices ) + { + if ( d.first.compare( id ) == 0 ) + { + deviceFound = true; + break; + } + else + { + ++i; + } + } + if ( deviceFound ) + { + m_recordingDeviceIndex = i; + if ( notify ) + { + emit micDeviceIndexChanged( i ); + } + } +} + +/*AUDIO PROFILE FUNCTIONS +The following section includes the code required to save and load Audio +Profiles. + +Saved Settings Include: +Playback Device +Mirror Device +Mirror Vol +Microphone +Microphone Volume +Profile Name + +*/ + +/* + Name: reloadAudioProfiles + + Inputs: args: none + other: Reads audioProfiles setting from file + + + Output: return:none + other:none + + Description: Clears working copy, and reloads from Settings file. + +*/ +void AudioTabController::reloadAudioProfiles() +{ + audioProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + auto profileCount = settings->beginReadArray( "audioProfiles" ); + for ( int i = 0; i < profileCount; i++ ) + { + settings->setArrayIndex( i ); + audioProfiles.emplace_back(); + auto& entry = audioProfiles[static_cast( i )]; + entry.profileName + = settings->value( "profileName" ).toString().toStdString(); + entry.playbackName + = settings->value( "playbackName" ).toString().toStdString(); + entry.micName = settings->value( "micName" ).toString().toStdString(); + entry.mirrorName + = settings->value( "mirrorName" ).toString().toStdString(); + entry.micMute = settings->value( "micMute", false ).toBool(); + entry.mirrorMute = settings->value( "mirrorMute", false ).toBool(); + entry.mirrorVol = settings->value( "mirrorVol", 0.0 ).toFloat(); + entry.micVol = settings->value( "micVol", 1.0 ).toFloat(); + } + settings->endArray(); + settings->endGroup(); +} + +/* +Name: saveAudioProfile + +Inputs: args: none +other: none + + +Output: return: none +other: Writes audioProfiles setting to file + +Description: saves a copy of the audio profiles from working to Settings file. + +*/ +void AudioTabController::saveAudioProfiles() +{ + auto settings = OverlayController::appSettings(); + settings->beginGroup( getSettingsName() ); + settings->beginWriteArray( "audioProfiles" ); + int i = 0; + for ( auto& p : audioProfiles ) + { + settings->setArrayIndex( i ); + settings->setValue( "profileName", + QString::fromStdString( p.profileName ) ); + settings->setValue( "playbackName", + QString::fromStdString( p.playbackName ) ); + settings->setValue( "micName", QString::fromStdString( p.micName ) ); + settings->setValue( "mirrorName", + QString::fromStdString( p.mirrorName ) ); + settings->setValue( "micMute", p.micMute ); + settings->setValue( "mirrorMute", p.mirrorMute ); + settings->setValue( "micVol", p.micVol ); + settings->setValue( "mirrorVol", p.mirrorVol ); + i++; + } + settings->endArray(); + settings->endGroup(); +} + +/* +Name: addAudioProfile + +Inputs: args: Qstring name - the name of the audio profile +other: none + + +Output: return: none +other: audioProfile to audioProfiles array + +Description: Creates an audioProfile, and adds it to the working copy of +audioProfiles[] + +*/ + +void AudioTabController::addAudioProfile( QString name ) +{ + AudioProfile* profile = nullptr; + for ( auto& p : audioProfiles ) + { + if ( p.profileName.compare( name.toStdString() ) == 0 ) + { + profile = &p; + break; + } + } + if ( !profile ) + { + auto i = audioProfiles.size(); + audioProfiles.emplace_back(); + profile = &audioProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->playbackName + = getPlaybackDeviceName( m_playbackDeviceIndex ).toStdString(); + profile->mirrorName + = getPlaybackDeviceName( m_mirrorDeviceIndex ).toStdString(); + profile->micName + = getRecordingDeviceName( m_recordingDeviceIndex ).toStdString(); + profile->micMute = m_micMuted; + profile->mirrorMute = m_mirrorMuted; + profile->mirrorVol = m_mirrorVolume; + profile->micVol = m_micVolume; + + saveAudioProfiles(); + OverlayController::appSettings()->sync(); + emit audioProfilesUpdated(); +} + +/* +Name: applyAudioProfile + +Inputs: args: index - index of audioProfile in audioProfiles[] +other: audioProfile based on index + + +Output: return: none +other: none + +Description: Applies the required logic to activate the audio profile. + +*/ +// TODO Remembers Mirror Volume when switching to main volume. +void AudioTabController::applyAudioProfile( unsigned index ) +{ + if ( index < audioProfiles.size() ) + { + auto& profile = audioProfiles[index]; + int mInd = getMirrorIndex( profile.mirrorName ); + int pInd = getPlaybackIndex( profile.playbackName ); + + // Needed to keep remembering when swtiching from mirror/main etc. + setMicMuted( false, false ); + setMirrorMuted( false, false ); + + if ( ( m_playbackDeviceIndex == mInd ) + && ( m_mirrorDeviceIndex == pInd ) ) + { + setMirrorDeviceIndex( -1, true ); + } + if ( m_playbackDeviceIndex == mInd ) + { + setPlaybackDeviceIndex( pInd, true ); + setMirrorDeviceIndex( mInd, true ); + } + else + { + setMirrorDeviceIndex( mInd, true ); + setPlaybackDeviceIndex( pInd, true ); + } + setMicDeviceIndex( getRecordingIndex( profile.micName ), true ); + setMicMuted( profile.micMute, true ); + setMirrorMuted( profile.mirrorMute, true ); + setMicVolume( profile.micVol, true ); + setMirrorVolume( profile.mirrorVol, true ); + } +} + +/* +Name: deleteAudioProfile + +Inputs: args: index - index of audioProfile in audioProfiles[] +other: audioProfile based on index + + +Output: return: none +other: none + +Description: Removes selected Audio Profile + +*/ +void AudioTabController::deleteAudioProfile( unsigned index ) +{ + if ( index < audioProfiles.size() ) + { + auto pos = audioProfiles.begin() + index; + audioProfiles.erase( pos ); + saveAudioProfiles(); + OverlayController::appSettings()->sync(); + emit audioProfilesUpdated(); + } +} + +unsigned AudioTabController::getAudioProfileCount() +{ + return static_cast( audioProfiles.size() ); +} + +QString AudioTabController::getAudioProfileName( unsigned index ) +{ + if ( index < audioProfiles.size() ) + { + return QString::fromStdString( audioProfiles[index].profileName ); + } + return ""; +} + +/* + Name: getPlaybackIndex, getRecordingIndex, and getMirrorIndex + + input: string, of microphone/playback device name + output: integer for use In: setMicDeviceIndex(int,bool), + setMirrorDeviceIndex(int,bool) setPlayBackDeviceIndex(int,bool) + + description: Gets proper index value for selecting specific devices. +*/ +int AudioTabController::getPlaybackIndex( std::string str ) +{ + // Unsigned to avoid two casts. i won't be negative because we only + // increment it. + for ( unsigned int i = 0; i < m_playbackDevices.size(); i++ ) + { + if ( str.compare( m_playbackDevices[i].second ) == 0 ) + { + return static_cast( i ); + } + } + return m_playbackDeviceIndex; +} + +int AudioTabController::getRecordingIndex( std::string str ) +{ + // Unsigned to avoid two casts. i won't be negative because we only + // increment it. + for ( unsigned int i = 0; i < m_recordingDevices.size(); i++ ) + { + if ( str.compare( m_recordingDevices[i].second ) == 0 ) + { + return static_cast( i ); + } + } + return m_recordingDeviceIndex; +} + +int AudioTabController::getMirrorIndex( std::string str ) +{ + // Unsigned to avoid two casts. i won't be negative because we only + // increment it. + for ( unsigned int i = 0; i < m_playbackDevices.size(); i++ ) + { + if ( str.compare( m_playbackDevices[i].second ) == 0 ) + { + return static_cast( i ); + } + } + return -1; +} + +/* ---------------------------*/ + +/*----------------*/ + +} // namespace advsettings diff --git a/src/tabcontrollers/AudioTabController.h b/src/tabcontrollers/AudioTabController.h index acad6fa..0aed808 100644 --- a/src/tabcontrollers/AudioTabController.h +++ b/src/tabcontrollers/AudioTabController.h @@ -8,160 +8,177 @@ class QQuickWindow; // application namespace -namespace advsettings { +namespace advsettings +{ +// forward declaration +class OverlayController; - // forward declaration - class OverlayController; +struct AudioProfile +{ + std::string profileName; + std::string playbackName; + std::string mirrorName; + std::string micName; + float mirrorVol = 0.0; + float micVol = 0.0; + bool micMute = false; + bool mirrorMute = false; +}; - struct AudioProfile { - std::string profileName; - std::string playbackName; - std::string mirrorName; - std::string micName; - float mirrorVol = 0.0; - float micVol = 0.0; - bool micMute = false; - bool mirrorMute = false; - }; +class AudioTabController : public PttController +{ + Q_OBJECT + Q_PROPERTY( int playbackDeviceIndex READ playbackDeviceIndex WRITE + setPlaybackDeviceIndex NOTIFY playbackDeviceIndexChanged ) + Q_PROPERTY( int mirrorDeviceIndex READ mirrorDeviceIndex WRITE + setMirrorDeviceIndex NOTIFY mirrorDeviceIndexChanged ) + // Q_PROPERTY(bool mirrorPresent READ mirrorPresent NOTIFY + // mirrorPresentChanged) Q_PROPERTY(QString mirrorDevName READ mirrorDevName + // NOTIFY mirrorDevNameChanged) + Q_PROPERTY( float mirrorVolume READ mirrorVolume WRITE setMirrorVolume + NOTIFY mirrorVolumeChanged ) + Q_PROPERTY( bool mirrorMuted READ mirrorMuted WRITE setMirrorMuted NOTIFY + mirrorMutedChanged ) + Q_PROPERTY( int micDeviceIndex READ micDeviceIndex WRITE setMicDeviceIndex + NOTIFY micDeviceIndexChanged ) + // Q_PROPERTY(bool micPresent READ micPresent NOTIFY micPresentChanged) + // Q_PROPERTY(QString micDevName READ micDevName NOTIFY micDevNameChanged) + Q_PROPERTY( float micVolume READ micVolume WRITE setMicVolume NOTIFY + micVolumeChanged ) + Q_PROPERTY( + bool micMuted READ micMuted WRITE setMicMuted NOTIFY micMutedChanged ) + Q_PROPERTY( bool micProximitySensorCanMute READ micProximitySensorCanMute + WRITE setMicProximitySensorCanMute NOTIFY + micProximitySensorCanMuteChanged ) + Q_PROPERTY( bool micReversePtt READ micReversePtt WRITE setMicReversePtt + NOTIFY micReversePttChanged ) +private: + OverlayController* parent; + QQuickWindow* widget; - class AudioTabController : public PttController { - Q_OBJECT - Q_PROPERTY(int playbackDeviceIndex READ playbackDeviceIndex WRITE setPlaybackDeviceIndex NOTIFY playbackDeviceIndexChanged) - Q_PROPERTY(int mirrorDeviceIndex READ mirrorDeviceIndex WRITE setMirrorDeviceIndex NOTIFY mirrorDeviceIndexChanged) - //Q_PROPERTY(bool mirrorPresent READ mirrorPresent NOTIFY mirrorPresentChanged) - //Q_PROPERTY(QString mirrorDevName READ mirrorDevName NOTIFY mirrorDevNameChanged) - Q_PROPERTY(float mirrorVolume READ mirrorVolume WRITE setMirrorVolume NOTIFY mirrorVolumeChanged) - Q_PROPERTY(bool mirrorMuted READ mirrorMuted WRITE setMirrorMuted NOTIFY mirrorMutedChanged) - Q_PROPERTY(int micDeviceIndex READ micDeviceIndex WRITE setMicDeviceIndex NOTIFY micDeviceIndexChanged) - //Q_PROPERTY(bool micPresent READ micPresent NOTIFY micPresentChanged) - //Q_PROPERTY(QString micDevName READ micDevName NOTIFY micDevNameChanged) - Q_PROPERTY(float micVolume READ micVolume WRITE setMicVolume NOTIFY micVolumeChanged) - Q_PROPERTY(bool micMuted READ micMuted WRITE setMicMuted NOTIFY micMutedChanged) - Q_PROPERTY(bool micProximitySensorCanMute READ micProximitySensorCanMute WRITE setMicProximitySensorCanMute NOTIFY micProximitySensorCanMuteChanged) - Q_PROPERTY(bool micReversePtt READ micReversePtt WRITE setMicReversePtt NOTIFY micReversePttChanged) + vr::VROverlayHandle_t m_ulNotificationOverlayHandle + = vr::k_ulOverlayHandleInvalid; - private: - OverlayController* parent; - QQuickWindow* widget; + int m_playbackDeviceIndex = -1; - vr::VROverlayHandle_t m_ulNotificationOverlayHandle = vr::k_ulOverlayHandleInvalid; + int m_mirrorDeviceIndex = -1; + float m_mirrorVolume = 1.0; + bool m_mirrorMuted = false; - int m_playbackDeviceIndex = -1; + int m_recordingDeviceIndex = -1; + float m_micVolume = 1.0; + bool m_micMuted = false; + bool m_micProximitySensorCanMute = false; + bool m_micReversePtt = false; - int m_mirrorDeviceIndex = -1; - float m_mirrorVolume = 1.0; - bool m_mirrorMuted = false; + unsigned settingsUpdateCounter = 0; - int m_recordingDeviceIndex = -1; - float m_micVolume = 1.0; - bool m_micMuted = false; - bool m_micProximitySensorCanMute = false; - bool m_micReversePtt = false; + std::unique_ptr audioManager; + std::vector> m_recordingDevices; + std::vector> m_playbackDevices; + std::string lastMirrorDevId; - unsigned settingsUpdateCounter = 0; + QString getSettingsName() override + { + return "audioSettings"; + } + // QString getSettingsNameAudio() override { return "audioSettingsTest"; } + void onPttStart() override; + void onPttStop() override; + void onPttEnabled() override; + void onPttDisabled() override; + bool pttChangeValid() override; + virtual vr::VROverlayHandle_t getNotificationOverlayHandle() override + { + return m_ulNotificationOverlayHandle; + } - std::unique_ptr audioManager; - std::vector> m_recordingDevices; - std::vector> m_playbackDevices; - std::string lastMirrorDevId; + void findPlaybackDeviceIndex( std::string id, bool notify = true ); + void findMirrorDeviceIndex( std::string id, bool notify = true ); + void findMicDeviceIndex( std::string id, bool notify = true ); - QString getSettingsName() override { return "audioSettings"; } - //QString getSettingsNameAudio() override { return "audioSettingsTest"; } - void onPttStart() override; - void onPttStop() override; - void onPttEnabled() override; - void onPttDisabled() override; - bool pttChangeValid() override; - virtual vr::VROverlayHandle_t getNotificationOverlayHandle() override { return m_ulNotificationOverlayHandle; } + int getPlaybackIndex( std::string str ); + int getRecordingIndex( std::string str ); + int getMirrorIndex( std::string str ); + // void setPlaybackDeviceControl(int index, bool notify = true); - void findPlaybackDeviceIndex(std::string id, bool notify = true); - void findMirrorDeviceIndex(std::string id, bool notify = true); - void findMicDeviceIndex(std::string id, bool notify = true); + std::vector audioProfiles; + // std::recursive_mutex eventLoopMutexAudio; - int getPlaybackIndex(std::string str); - int getRecordingIndex(std::string str); - int getMirrorIndex(std::string str); - //void setPlaybackDeviceControl(int index, bool notify = true); +public: + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - std::vector audioProfiles; - //std::recursive_mutex eventLoopMutexAudio; + void reloadAudioSettings(); + void saveAudioSettings(); - public: + void eventLoopTick(); + int playbackDeviceIndex() const; - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + int mirrorDeviceIndex() const; + float mirrorVolume() const; + bool mirrorMuted() const; - void reloadAudioSettings(); - void saveAudioSettings(); + int micDeviceIndex() const; + float micVolume() const; + bool micMuted() const; + bool micProximitySensorCanMute() const; + bool micReversePtt() const; - void eventLoopTick(); + void reloadAudioProfiles(); + void saveAudioProfiles(); - int playbackDeviceIndex() const; + Q_INVOKABLE int getPlaybackDeviceCount(); + Q_INVOKABLE QString getPlaybackDeviceName( int index ); - int mirrorDeviceIndex() const; - float mirrorVolume() const; - bool mirrorMuted() const; + Q_INVOKABLE int getRecordingDeviceCount(); + Q_INVOKABLE QString getRecordingDeviceName( int index ); - int micDeviceIndex() const; - float micVolume() const; - bool micMuted() const; - bool micProximitySensorCanMute() const; - bool micReversePtt() const; + // TODO check if needed? + Q_INVOKABLE unsigned getAudioProfileCount(); + Q_INVOKABLE QString getAudioProfileName( unsigned index ); - void reloadAudioProfiles(); - void saveAudioProfiles(); + void onNewRecordingDevice(); + void onNewPlaybackDevice(); + void onNewMirrorDevice(); + void onDeviceStateChanged(); - Q_INVOKABLE int getPlaybackDeviceCount(); - Q_INVOKABLE QString getPlaybackDeviceName(int index); +public slots: + void setMirrorVolume( float value, bool notify = true ); + void setMirrorMuted( bool value, bool notify = true ); - Q_INVOKABLE int getRecordingDeviceCount(); - Q_INVOKABLE QString getRecordingDeviceName(int index); + void setMicVolume( float value, bool notify = true ); + void setMicMuted( bool value, bool notify = true ); + void setMicProximitySensorCanMute( bool value, bool notify = true ); + void setMicReversePtt( bool value, bool notify = true ); - //TODO check if needed? - Q_INVOKABLE unsigned getAudioProfileCount(); - Q_INVOKABLE QString getAudioProfileName(unsigned index); + void setPlaybackDeviceIndex( int value, bool notify = true ); + void setMirrorDeviceIndex( int value, bool notify = true ); + void setMicDeviceIndex( int value, bool notify = true ); - void onNewRecordingDevice(); - void onNewPlaybackDevice(); - void onNewMirrorDevice(); - void onDeviceStateChanged(); + void addAudioProfile( QString name ); + void applyAudioProfile( unsigned index ); + void deleteAudioProfile( unsigned index ); - public slots: - void setMirrorVolume(float value, bool notify = true); - void setMirrorMuted(bool value, bool notify = true); +signals: + void playbackDeviceIndexChanged( int index ); - void setMicVolume(float value, bool notify = true); - void setMicMuted(bool value, bool notify = true); - void setMicProximitySensorCanMute(bool value, bool notify = true); - void setMicReversePtt(bool value, bool notify = true); + void mirrorDeviceIndexChanged( int index ); + void mirrorVolumeChanged( float value ); + void mirrorMutedChanged( bool value ); - void setPlaybackDeviceIndex(int value, bool notify = true); - void setMirrorDeviceIndex(int value, bool notify = true); - void setMicDeviceIndex(int value, bool notify = true); + void micDeviceIndexChanged( int index ); + void micVolumeChanged( float value ); + void micMutedChanged( bool value ); + void micProximitySensorCanMuteChanged( bool value ); + void micReversePttChanged( bool value ); - void addAudioProfile(QString name); - void applyAudioProfile(unsigned index); - void deleteAudioProfile(unsigned index); + void playbackDeviceListChanged(); + void recordingDeviceListChanged(); - signals: - void playbackDeviceIndexChanged(int index); - - void mirrorDeviceIndexChanged(int index); - void mirrorVolumeChanged(float value); - void mirrorMutedChanged(bool value); - - void micDeviceIndexChanged(int index); - void micVolumeChanged(float value); - void micMutedChanged(bool value); - void micProximitySensorCanMuteChanged(bool value); - void micReversePttChanged(bool value); - - void playbackDeviceListChanged(); - void recordingDeviceListChanged(); - - void audioProfilesUpdated(); - }; + void audioProfilesUpdated(); +}; } // namespace advsettings diff --git a/src/tabcontrollers/ChaperoneTabController.cpp b/src/tabcontrollers/ChaperoneTabController.cpp index f286cd9..e9925f7 100644 --- a/src/tabcontrollers/ChaperoneTabController.cpp +++ b/src/tabcontrollers/ChaperoneTabController.cpp @@ -4,1054 +4,1647 @@ #include // application namespace -namespace advsettings { +namespace advsettings +{ +void ChaperoneTabController::initStage1() +{ + m_height = getBoundsMaxY(); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + m_enableChaperoneSwitchToBeginner + = settings->value( "chaperoneSwitchToBeginnerEnabled", false ).toBool(); + m_chaperoneSwitchToBeginnerDistance + = settings->value( "chaperoneSwitchToBeginnerDistance", 0.5f ) + .toFloat(); + m_enableChaperoneHapticFeedback + = settings->value( "chaperoneHapticFeedbackEnabled", false ).toBool(); + m_chaperoneHapticFeedbackDistance + = settings->value( "chaperoneHapticFeedbackDistance", 0.5f ).toFloat(); + m_enableChaperoneAlarmSound + = settings->value( "chaperoneAlarmSoundEnabled", false ).toBool(); + m_chaperoneAlarmSoundLooping + = settings->value( "chaperoneAlarmSoundLooping", true ).toBool(); + m_chaperoneAlarmSoundAdjustVolume + = settings->value( "chaperoneAlarmSoundAdjustVolume", false ).toBool(); + m_chaperoneAlarmSoundDistance + = settings->value( "chaperoneAlarmSoundDistance", 0.5f ).toFloat(); + m_enableChaperoneShowDashboard + = settings->value( "chaperoneShowDashboardEnabled", false ).toBool(); + m_chaperoneShowDashboardDistance + = settings->value( "chaperoneShowDashboardDistance", 0.5f ).toFloat(); + m_enableChaperoneVelocityModifier + = settings->value( "chaperoneVelocityModifierEnabled", false ).toBool(); + m_chaperoneVelocityModifier + = settings->value( "chaperoneVelocityModifier", 0.3f ).toFloat(); + m_chaperoneVelocityModifierCurrent = 1.0f; + settings->endGroup(); -void ChaperoneTabController::initStage1() { - m_height = getBoundsMaxY(); - - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - m_enableChaperoneSwitchToBeginner = settings->value("chaperoneSwitchToBeginnerEnabled", false).toBool(); - m_chaperoneSwitchToBeginnerDistance = settings->value("chaperoneSwitchToBeginnerDistance", 0.5f).toFloat(); - m_enableChaperoneHapticFeedback = settings->value("chaperoneHapticFeedbackEnabled", false).toBool(); - m_chaperoneHapticFeedbackDistance = settings->value("chaperoneHapticFeedbackDistance", 0.5f).toFloat(); - m_enableChaperoneAlarmSound = settings->value("chaperoneAlarmSoundEnabled", false).toBool(); - m_chaperoneAlarmSoundLooping = settings->value("chaperoneAlarmSoundLooping", true).toBool(); - m_chaperoneAlarmSoundAdjustVolume = settings->value("chaperoneAlarmSoundAdjustVolume", false).toBool(); - m_chaperoneAlarmSoundDistance = settings->value("chaperoneAlarmSoundDistance", 0.5f).toFloat(); - m_enableChaperoneShowDashboard = settings->value("chaperoneShowDashboardEnabled", false).toBool(); - m_chaperoneShowDashboardDistance = settings->value("chaperoneShowDashboardDistance", 0.5f).toFloat(); - m_enableChaperoneVelocityModifier = settings->value("chaperoneVelocityModifierEnabled", false).toBool(); - m_chaperoneVelocityModifier = settings->value("chaperoneVelocityModifier", 0.3f).toFloat(); - m_chaperoneVelocityModifierCurrent = 1.0f; - settings->endGroup(); - - reloadChaperoneProfiles(); - eventLoopTick(nullptr, 0.0f, 0.0f, 0.0f); + reloadChaperoneProfiles(); + eventLoopTick( nullptr, 0.0f, 0.0f, 0.0f ); } - -void ChaperoneTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void ChaperoneTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } - - -ChaperoneTabController::~ChaperoneTabController() { - m_chaperoneHapticFeedbackActive = false; - if (m_chaperoneHapticFeedbackThread.joinable()) { - m_chaperoneHapticFeedbackThread.join(); - } +ChaperoneTabController::~ChaperoneTabController() +{ + m_chaperoneHapticFeedbackActive = false; + if ( m_chaperoneHapticFeedbackThread.joinable() ) + { + m_chaperoneHapticFeedbackThread.join(); + } } - -void ChaperoneTabController::reloadChaperoneProfiles() { - chaperoneProfiles.clear(); - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - auto profileCount = settings->beginReadArray("chaperoneProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - chaperoneProfiles.emplace_back(); - auto& entry = chaperoneProfiles[i]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.includesChaperoneGeometry = settings->value("includesChaperoneGeometry", false).toBool(); - if (entry.includesChaperoneGeometry) { - entry.chaperoneGeometryQuadCount = settings->value("chaperoneGeometryQuadCount", 0).toUInt(); - entry.chaperoneGeometryQuads.reset(new vr::HmdQuad_t[entry.chaperoneGeometryQuadCount]); - unsigned qi = 0; - for (auto q : settings->value("chaperoneGeometryQuads").toList()) { - unsigned ci = 0; - for (auto c : q.toList()) { - unsigned cci = 0; - for (auto cc : c.toList()) { - entry.chaperoneGeometryQuads.get()[qi].vCorners[ci].v[cci] = cc.toFloat(); - cci++; - } - ci++; - } - qi++; - } - unsigned i1 = 0; - for (auto l1 : settings->value("standingCenter").toList()) { - unsigned i2 = 0; - for (auto l2 : l1.toList()) { - entry.standingCenter.m[i1][i2] = l2.toFloat(); - i2++; - } - i1++; - } - entry.playSpaceAreaX = settings->value("playSpaceAreaX", 0.0f).toFloat(); - entry.playSpaceAreaZ = settings->value("playSpaceAreaZ", 0.0f).toFloat(); - } - entry.includesVisibility = settings->value("includesVisibility", false).toBool(); - if (entry.includesVisibility) { - entry.visibility = settings->value("visibility", 0.6).toFloat(); - } - entry.includesFadeDistance = settings->value("includesFadeDistance", false).toBool(); - if (entry.includesFadeDistance) { - entry.fadeDistance = settings->value("fadeDistance", 0.7).toFloat(); - } - entry.includesCenterMarker = settings->value("includesCenterMarker", false).toBool(); - if (entry.includesCenterMarker) { - entry.centerMarker = settings->value("centerMarker", false).toBool(); - } - entry.includesPlaySpaceMarker = settings->value("includesPlaySpaceMarker", false).toBool(); - if (entry.includesPlaySpaceMarker) { - entry.playSpaceMarker = settings->value("playSpaceMarker", false).toBool(); - } - entry.includesFloorBoundsMarker = settings->value("includesFloorBoundsMarker", false).toBool(); - if (entry.includesFloorBoundsMarker) { - entry.floorBoundsMarker = settings->value("floorBoundsMarker", false).toBool(); - } - entry.includesBoundsColor = settings->value("includesBoundsColor", false).toBool(); - if (entry.includesBoundsColor) { - auto color = settings->value("boundsColor").toList(); - entry.boundsColor[0] = color[0].toInt(); - entry.boundsColor[1] = color[1].toInt(); - entry.boundsColor[2] = color[2].toInt(); - } - entry.includesChaperoneStyle = settings->value("includesChaperoneStyle", false).toBool(); - if (entry.includesChaperoneStyle) { - entry.chaperoneStyle = settings->value("chaperoneStyle", 0).toInt(); - } - entry.includesForceBounds = settings->value("includesForceBounds", false).toBool(); - if (entry.includesForceBounds) { - entry.forceBounds = settings->value("forceBounds", false).toBool(); - } - entry.includesProximityWarningSettings = settings->value("includesProximityWarningSettings", false).toBool(); - if (entry.includesProximityWarningSettings){ - entry.enableChaperoneSwitchToBeginner = settings->value("chaperoneSwitchToBeginnerEnabled", false).toBool(); - entry.chaperoneSwitchToBeginnerDistance = settings->value("chaperoneSwitchToBeginnerDistance", 0.5f).toFloat(); - entry.enableChaperoneHapticFeedback = settings->value("chaperoneHapticFeedbackEnabled", false).toBool(); - entry.chaperoneHapticFeedbackDistance = settings->value("chaperoneHapticFeedbackDistance", 0.5f).toFloat(); - entry.enableChaperoneAlarmSound = settings->value("chaperoneAlarmSoundEnabled", false).toBool(); - entry.chaperoneAlarmSoundLooping = settings->value("chaperoneAlarmSoundLooping", true).toBool(); - entry.chaperoneAlarmSoundAdjustVolume = settings->value("chaperoneAlarmSoundAdjustVolume", false).toBool(); - entry.chaperoneAlarmSoundDistance = settings->value("chaperoneAlarmSoundDistance", 0.5f).toFloat(); - entry.enableChaperoneShowDashboard = settings->value("chaperoneShowDashboardEnabled", false).toBool(); - entry.chaperoneShowDashboardDistance = settings->value("chaperoneShowDashboardDistance", 0.5f).toFloat(); - entry.enableChaperoneVelocityModifier = settings->value("chaperoneVelocityModifierEnabled", false).toBool(); - entry.chaperoneVelocityModifier = settings->value("chaperoneVelocityModifier", 0.3f).toFloat(); - } - } - settings->endArray(); - settings->endGroup(); +void ChaperoneTabController::reloadChaperoneProfiles() +{ + chaperoneProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + auto profileCount = settings->beginReadArray( "chaperoneProfiles" ); + for ( int i = 0; i < profileCount; i++ ) + { + settings->setArrayIndex( i ); + chaperoneProfiles.emplace_back(); + auto& entry = chaperoneProfiles[i]; + entry.profileName + = settings->value( "profileName" ).toString().toStdString(); + entry.includesChaperoneGeometry + = settings->value( "includesChaperoneGeometry", false ).toBool(); + if ( entry.includesChaperoneGeometry ) + { + entry.chaperoneGeometryQuadCount + = settings->value( "chaperoneGeometryQuadCount", 0 ).toUInt(); + entry.chaperoneGeometryQuads.reset( + new vr::HmdQuad_t[entry.chaperoneGeometryQuadCount] ); + unsigned qi = 0; + for ( auto q : + settings->value( "chaperoneGeometryQuads" ).toList() ) + { + unsigned ci = 0; + for ( auto c : q.toList() ) + { + unsigned cci = 0; + for ( auto cc : c.toList() ) + { + entry.chaperoneGeometryQuads.get()[qi] + .vCorners[ci] + .v[cci] + = cc.toFloat(); + cci++; + } + ci++; + } + qi++; + } + unsigned i1 = 0; + for ( auto l1 : settings->value( "standingCenter" ).toList() ) + { + unsigned i2 = 0; + for ( auto l2 : l1.toList() ) + { + entry.standingCenter.m[i1][i2] = l2.toFloat(); + i2++; + } + i1++; + } + entry.playSpaceAreaX + = settings->value( "playSpaceAreaX", 0.0f ).toFloat(); + entry.playSpaceAreaZ + = settings->value( "playSpaceAreaZ", 0.0f ).toFloat(); + } + entry.includesVisibility + = settings->value( "includesVisibility", false ).toBool(); + if ( entry.includesVisibility ) + { + entry.visibility = settings->value( "visibility", 0.6 ).toFloat(); + } + entry.includesFadeDistance + = settings->value( "includesFadeDistance", false ).toBool(); + if ( entry.includesFadeDistance ) + { + entry.fadeDistance + = settings->value( "fadeDistance", 0.7 ).toFloat(); + } + entry.includesCenterMarker + = settings->value( "includesCenterMarker", false ).toBool(); + if ( entry.includesCenterMarker ) + { + entry.centerMarker + = settings->value( "centerMarker", false ).toBool(); + } + entry.includesPlaySpaceMarker + = settings->value( "includesPlaySpaceMarker", false ).toBool(); + if ( entry.includesPlaySpaceMarker ) + { + entry.playSpaceMarker + = settings->value( "playSpaceMarker", false ).toBool(); + } + entry.includesFloorBoundsMarker + = settings->value( "includesFloorBoundsMarker", false ).toBool(); + if ( entry.includesFloorBoundsMarker ) + { + entry.floorBoundsMarker + = settings->value( "floorBoundsMarker", false ).toBool(); + } + entry.includesBoundsColor + = settings->value( "includesBoundsColor", false ).toBool(); + if ( entry.includesBoundsColor ) + { + auto color = settings->value( "boundsColor" ).toList(); + entry.boundsColor[0] = color[0].toInt(); + entry.boundsColor[1] = color[1].toInt(); + entry.boundsColor[2] = color[2].toInt(); + } + entry.includesChaperoneStyle + = settings->value( "includesChaperoneStyle", false ).toBool(); + if ( entry.includesChaperoneStyle ) + { + entry.chaperoneStyle + = settings->value( "chaperoneStyle", 0 ).toInt(); + } + entry.includesForceBounds + = settings->value( "includesForceBounds", false ).toBool(); + if ( entry.includesForceBounds ) + { + entry.forceBounds + = settings->value( "forceBounds", false ).toBool(); + } + entry.includesProximityWarningSettings + = settings->value( "includesProximityWarningSettings", false ) + .toBool(); + if ( entry.includesProximityWarningSettings ) + { + entry.enableChaperoneSwitchToBeginner + = settings->value( "chaperoneSwitchToBeginnerEnabled", false ) + .toBool(); + entry.chaperoneSwitchToBeginnerDistance + = settings->value( "chaperoneSwitchToBeginnerDistance", 0.5f ) + .toFloat(); + entry.enableChaperoneHapticFeedback + = settings->value( "chaperoneHapticFeedbackEnabled", false ) + .toBool(); + entry.chaperoneHapticFeedbackDistance + = settings->value( "chaperoneHapticFeedbackDistance", 0.5f ) + .toFloat(); + entry.enableChaperoneAlarmSound + = settings->value( "chaperoneAlarmSoundEnabled", false ) + .toBool(); + entry.chaperoneAlarmSoundLooping + = settings->value( "chaperoneAlarmSoundLooping", true ) + .toBool(); + entry.chaperoneAlarmSoundAdjustVolume + = settings->value( "chaperoneAlarmSoundAdjustVolume", false ) + .toBool(); + entry.chaperoneAlarmSoundDistance + = settings->value( "chaperoneAlarmSoundDistance", 0.5f ) + .toFloat(); + entry.enableChaperoneShowDashboard + = settings->value( "chaperoneShowDashboardEnabled", false ) + .toBool(); + entry.chaperoneShowDashboardDistance + = settings->value( "chaperoneShowDashboardDistance", 0.5f ) + .toFloat(); + entry.enableChaperoneVelocityModifier + = settings->value( "chaperoneVelocityModifierEnabled", false ) + .toBool(); + entry.chaperoneVelocityModifier + = settings->value( "chaperoneVelocityModifier", 0.3f ) + .toFloat(); + } + } + settings->endArray(); + settings->endGroup(); } -void ChaperoneTabController::saveChaperoneProfiles() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->beginWriteArray("chaperoneProfiles"); - unsigned i = 0; - for (auto& p : chaperoneProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("includesChaperoneGeometry", p.includesChaperoneGeometry); - if (p.includesChaperoneGeometry) { - settings->setValue("chaperoneGeometryQuadCount", p.chaperoneGeometryQuadCount); - QVariantList quadList; - for (unsigned qi = 0; qi < p.chaperoneGeometryQuadCount; qi++) { - QVariantList cornerList; - for (unsigned ci = 0; ci < 4; ci++) { - QVariantList coordVector; - for (unsigned cci = 0; cci < 3; cci++) { - coordVector.push_back(p.chaperoneGeometryQuads.get()[qi].vCorners[ci].v[cci]); - } - cornerList.push_back(coordVector); - } - quadList.push_back(cornerList); - } - settings->setValue("chaperoneGeometryQuads", quadList); - QVariantList l1; - for (unsigned i1 = 0; i1 < 3; i1++) { - QVariantList l2; - for (unsigned i2 = 0; i2 < 4; i2++) { - l2.push_back(p.standingCenter.m[i1][i2]); - } - l1.push_back(l2); - } - settings->setValue("standingCenter", l1); - settings->setValue("playSpaceAreaX", p.playSpaceAreaX); - settings->setValue("playSpaceAreaZ", p.playSpaceAreaZ); - } - settings->setValue("includesVisibility", p.includesVisibility); - if (p.includesVisibility) { - settings->setValue("visibility", p.visibility); - } - settings->setValue("includesFadeDistance", p.includesFadeDistance); - if (p.includesFadeDistance) { - settings->setValue("fadeDistance", p.fadeDistance); - } - settings->setValue("includesCenterMarker", p.includesCenterMarker); - if (p.includesCenterMarker) { - settings->setValue("centerMarker", p.centerMarker); - } - settings->setValue("includesPlaySpaceMarker", p.includesPlaySpaceMarker); - if (p.includesPlaySpaceMarker) { - settings->setValue("playSpaceMarker", p.playSpaceMarker); - } - settings->setValue("includesFloorBoundsMarker", p.includesFloorBoundsMarker); - if (p.includesFloorBoundsMarker) { - settings->setValue("floorBoundsMarker", p.floorBoundsMarker); - } - settings->setValue("includesBoundsColor", p.includesBoundsColor); - if (p.includesBoundsColor) { - QVariantList color; - color.push_back(p.boundsColor[0]); - color.push_back(p.boundsColor[1]); - color.push_back(p.boundsColor[2]); - settings->setValue("boundsColor", color); - } - settings->setValue("includesChaperoneStyle", p.includesChaperoneStyle); - if (p.includesChaperoneStyle) { - settings->setValue("chaperoneStyle", p.chaperoneStyle); - } - settings->setValue("includesForceBounds", p.includesForceBounds); - if (p.includesForceBounds) { - settings->setValue("forceBounds", p.forceBounds); - } - settings->setValue("includesProximityWarningSettings", p.includesProximityWarningSettings); - if (p.includesProximityWarningSettings) { - settings->setValue("chaperoneSwitchToBeginnerEnabled", p.enableChaperoneSwitchToBeginner); - settings->setValue("chaperoneSwitchToBeginnerDistance", p.chaperoneSwitchToBeginnerDistance); - settings->setValue("chaperoneHapticFeedbackEnabled", p.enableChaperoneHapticFeedback); - settings->setValue("chaperoneHapticFeedbackDistance", p.chaperoneHapticFeedbackDistance); - settings->setValue("chaperoneAlarmSoundEnabled", p.enableChaperoneAlarmSound); - settings->setValue("chaperoneAlarmSoundLooping", p.chaperoneAlarmSoundLooping); - settings->setValue("chaperoneAlarmSoundAdjustVolume", p.chaperoneAlarmSoundAdjustVolume); - settings->setValue("chaperoneAlarmSoundDistance", p.chaperoneAlarmSoundDistance); - settings->setValue("chaperoneShowDashboardEnabled", p.enableChaperoneShowDashboard); - settings->setValue("chaperoneShowDashboardDistance", p.chaperoneShowDashboardDistance); - settings->setValue("chaperoneVelocityModifierEnabled", p.enableChaperoneVelocityModifier); - settings->setValue("chaperoneVelocityModifier", p.chaperoneVelocityModifier); - } - i++; - } - settings->endArray(); - settings->endGroup(); +void ChaperoneTabController::saveChaperoneProfiles() +{ + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->beginWriteArray( "chaperoneProfiles" ); + unsigned i = 0; + for ( auto& p : chaperoneProfiles ) + { + settings->setArrayIndex( i ); + settings->setValue( "profileName", + QString::fromStdString( p.profileName ) ); + settings->setValue( "includesChaperoneGeometry", + p.includesChaperoneGeometry ); + if ( p.includesChaperoneGeometry ) + { + settings->setValue( "chaperoneGeometryQuadCount", + p.chaperoneGeometryQuadCount ); + QVariantList quadList; + for ( unsigned qi = 0; qi < p.chaperoneGeometryQuadCount; qi++ ) + { + QVariantList cornerList; + for ( unsigned ci = 0; ci < 4; ci++ ) + { + QVariantList coordVector; + for ( unsigned cci = 0; cci < 3; cci++ ) + { + coordVector.push_back( + p.chaperoneGeometryQuads.get()[qi] + .vCorners[ci] + .v[cci] ); + } + cornerList.push_back( coordVector ); + } + quadList.push_back( cornerList ); + } + settings->setValue( "chaperoneGeometryQuads", quadList ); + QVariantList l1; + for ( unsigned i1 = 0; i1 < 3; i1++ ) + { + QVariantList l2; + for ( unsigned i2 = 0; i2 < 4; i2++ ) + { + l2.push_back( p.standingCenter.m[i1][i2] ); + } + l1.push_back( l2 ); + } + settings->setValue( "standingCenter", l1 ); + settings->setValue( "playSpaceAreaX", p.playSpaceAreaX ); + settings->setValue( "playSpaceAreaZ", p.playSpaceAreaZ ); + } + settings->setValue( "includesVisibility", p.includesVisibility ); + if ( p.includesVisibility ) + { + settings->setValue( "visibility", p.visibility ); + } + settings->setValue( "includesFadeDistance", p.includesFadeDistance ); + if ( p.includesFadeDistance ) + { + settings->setValue( "fadeDistance", p.fadeDistance ); + } + settings->setValue( "includesCenterMarker", p.includesCenterMarker ); + if ( p.includesCenterMarker ) + { + settings->setValue( "centerMarker", p.centerMarker ); + } + settings->setValue( "includesPlaySpaceMarker", + p.includesPlaySpaceMarker ); + if ( p.includesPlaySpaceMarker ) + { + settings->setValue( "playSpaceMarker", p.playSpaceMarker ); + } + settings->setValue( "includesFloorBoundsMarker", + p.includesFloorBoundsMarker ); + if ( p.includesFloorBoundsMarker ) + { + settings->setValue( "floorBoundsMarker", p.floorBoundsMarker ); + } + settings->setValue( "includesBoundsColor", p.includesBoundsColor ); + if ( p.includesBoundsColor ) + { + QVariantList color; + color.push_back( p.boundsColor[0] ); + color.push_back( p.boundsColor[1] ); + color.push_back( p.boundsColor[2] ); + settings->setValue( "boundsColor", color ); + } + settings->setValue( "includesChaperoneStyle", + p.includesChaperoneStyle ); + if ( p.includesChaperoneStyle ) + { + settings->setValue( "chaperoneStyle", p.chaperoneStyle ); + } + settings->setValue( "includesForceBounds", p.includesForceBounds ); + if ( p.includesForceBounds ) + { + settings->setValue( "forceBounds", p.forceBounds ); + } + settings->setValue( "includesProximityWarningSettings", + p.includesProximityWarningSettings ); + if ( p.includesProximityWarningSettings ) + { + settings->setValue( "chaperoneSwitchToBeginnerEnabled", + p.enableChaperoneSwitchToBeginner ); + settings->setValue( "chaperoneSwitchToBeginnerDistance", + p.chaperoneSwitchToBeginnerDistance ); + settings->setValue( "chaperoneHapticFeedbackEnabled", + p.enableChaperoneHapticFeedback ); + settings->setValue( "chaperoneHapticFeedbackDistance", + p.chaperoneHapticFeedbackDistance ); + settings->setValue( "chaperoneAlarmSoundEnabled", + p.enableChaperoneAlarmSound ); + settings->setValue( "chaperoneAlarmSoundLooping", + p.chaperoneAlarmSoundLooping ); + settings->setValue( "chaperoneAlarmSoundAdjustVolume", + p.chaperoneAlarmSoundAdjustVolume ); + settings->setValue( "chaperoneAlarmSoundDistance", + p.chaperoneAlarmSoundDistance ); + settings->setValue( "chaperoneShowDashboardEnabled", + p.enableChaperoneShowDashboard ); + settings->setValue( "chaperoneShowDashboardDistance", + p.chaperoneShowDashboardDistance ); + settings->setValue( "chaperoneVelocityModifierEnabled", + p.enableChaperoneVelocityModifier ); + settings->setValue( "chaperoneVelocityModifier", + p.chaperoneVelocityModifier ); + } + i++; + } + settings->endArray(); + settings->endGroup(); } +void ChaperoneTabController::handleChaperoneWarnings( float distance ) +{ + vr::VRControllerState_t hmdState; + vr::VRSystem()->GetControllerState( vr::k_unTrackedDeviceIndex_Hmd, + &hmdState, + sizeof( vr::VRControllerState_t ) ); -void ChaperoneTabController::handleChaperoneWarnings(float distance) { - vr::VRControllerState_t hmdState; - vr::VRSystem()->GetControllerState(vr::k_unTrackedDeviceIndex_Hmd, &hmdState, sizeof(vr::VRControllerState_t)); + // Switch to Beginner Mode + if ( m_enableChaperoneSwitchToBeginner ) + { + float activationDistance = m_chaperoneSwitchToBeginnerDistance + * m_chaperoneVelocityModifierCurrent; + if ( distance <= activationDistance + && ( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ProximitySensor ) ) + && !m_chaperoneSwitchToBeginnerActive ) + { + vr::EVRSettingsError vrSettingsError; + m_chaperoneSwitchToBeginnerLastStyle = vr::VRSettings()->GetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not read \"" + << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->SetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + vr::COLLISION_BOUNDS_STYLE_BEGINNER, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not set \"" + << vr::k_pch_CollisionBounds_Style_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync( true ); + m_chaperoneSwitchToBeginnerActive = true; + } + } + } + else if ( ( distance > activationDistance + || !( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( + vr::k_EButton_ProximitySensor ) ) ) + && m_chaperoneSwitchToBeginnerActive ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + m_chaperoneSwitchToBeginnerLastStyle, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not set \"" + << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync( true ); + m_chaperoneSwitchToBeginnerActive = false; + } + } + } - // Switch to Beginner Mode - if (m_enableChaperoneSwitchToBeginner) { - float activationDistance = m_chaperoneSwitchToBeginnerDistance * m_chaperoneVelocityModifierCurrent; - if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor)) && !m_chaperoneSwitchToBeginnerActive) { - vr::EVRSettingsError vrSettingsError; - m_chaperoneSwitchToBeginnerLastStyle = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, vr::COLLISION_BOUNDS_STYLE_BEGINNER, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(true); - m_chaperoneSwitchToBeginnerActive = true; - } - } - } else if ((distance > activationDistance || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && m_chaperoneSwitchToBeginnerActive) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, m_chaperoneSwitchToBeginnerLastStyle, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(true); - m_chaperoneSwitchToBeginnerActive = false; - } - } - } + // Haptic Feedback + if ( m_enableChaperoneHapticFeedback ) + { + float activationDistance = m_chaperoneHapticFeedbackDistance + * m_chaperoneVelocityModifierCurrent; + if ( distance <= activationDistance + && ( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ProximitySensor ) ) ) + { + if ( !m_chaperoneHapticFeedbackActive ) + { + if ( m_chaperoneHapticFeedbackThread.joinable() ) + { + m_chaperoneHapticFeedbackActive = false; + m_chaperoneHapticFeedbackThread.join(); + } + m_chaperoneHapticFeedbackActive = true; + m_chaperoneHapticFeedbackThread = std::thread( + []( ChaperoneTabController* _this ) { + auto leftIndex + = vr::VRSystem() + ->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_LeftHand ); + auto rightIndex + = vr::VRSystem() + ->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_RightHand ); + while ( _this->m_chaperoneHapticFeedbackActive ) + { + if ( leftIndex + != vr::k_unTrackedDeviceIndexInvalid ) + { + vr::VRSystem()->TriggerHapticPulse( + leftIndex, 0, 2000 ); + } + if ( rightIndex + != vr::k_unTrackedDeviceIndexInvalid ) + { + vr::VRSystem()->TriggerHapticPulse( + rightIndex, 0, 2000 ); + } + std::this_thread::sleep_for( + std::chrono::milliseconds( 5 ) ); + } + }, + this ); + } + } + else if ( ( distance > activationDistance + || !( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( + vr::k_EButton_ProximitySensor ) ) ) + && m_chaperoneHapticFeedbackActive ) + { + m_chaperoneHapticFeedbackActive = false; + } + } - // Haptic Feedback - if (m_enableChaperoneHapticFeedback) { - float activationDistance = m_chaperoneHapticFeedbackDistance * m_chaperoneVelocityModifierCurrent; - if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) { - if (!m_chaperoneHapticFeedbackActive) { - if (m_chaperoneHapticFeedbackThread.joinable()) { - m_chaperoneHapticFeedbackActive = false; - m_chaperoneHapticFeedbackThread.join(); - } - m_chaperoneHapticFeedbackActive = true; - m_chaperoneHapticFeedbackThread = std::thread([](ChaperoneTabController* _this) { - auto leftIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - auto rightIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - while (_this->m_chaperoneHapticFeedbackActive) { - if (leftIndex != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRSystem()->TriggerHapticPulse(leftIndex, 0, 2000); - } - if (rightIndex != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRSystem()->TriggerHapticPulse(rightIndex, 0, 2000); - } - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - }, this); - } - } else if ((distance > activationDistance || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && m_chaperoneHapticFeedbackActive) { - m_chaperoneHapticFeedbackActive = false; - } - } + // Alarm Sound + if ( m_enableChaperoneAlarmSound ) + { + float activationDistance = m_chaperoneAlarmSoundDistance + * m_chaperoneVelocityModifierCurrent; + if ( distance <= activationDistance + && ( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ProximitySensor ) ) ) + { + if ( !m_chaperoneAlarmSoundActive ) + { + parent->playAlarm01Sound( m_chaperoneAlarmSoundLooping ); + m_chaperoneAlarmSoundActive = true; + } + if ( m_chaperoneAlarmSoundLooping + && m_chaperoneAlarmSoundAdjustVolume ) + { + float vol = 1.1f - distance / activationDistance; + if ( vol > 1.0f ) + { + vol = 1.0f; + } + parent->setAlarm01SoundVolume( vol ); + } + else + { + parent->setAlarm01SoundVolume( 1.0f ); + } + } + else if ( ( distance > activationDistance + || !( hmdState.ulButtonPressed + & vr::ButtonMaskFromId( + vr::k_EButton_ProximitySensor ) ) ) + && m_chaperoneAlarmSoundActive ) + { + parent->cancelAlarm01Sound(); + m_chaperoneAlarmSoundActive = false; + } + } - // Alarm Sound - if (m_enableChaperoneAlarmSound) { - float activationDistance = m_chaperoneAlarmSoundDistance * m_chaperoneVelocityModifierCurrent; - if (distance <= activationDistance && (hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) { - if (!m_chaperoneAlarmSoundActive) { - parent->playAlarm01Sound(m_chaperoneAlarmSoundLooping); - m_chaperoneAlarmSoundActive = true; - } - if (m_chaperoneAlarmSoundLooping && m_chaperoneAlarmSoundAdjustVolume) { - float vol = 1.1f - distance / activationDistance; - if (vol > 1.0f) { - vol = 1.0f; - } - parent->setAlarm01SoundVolume(vol); - } else { - parent->setAlarm01SoundVolume(1.0f); - } - } else if ((distance > activationDistance || !(hmdState.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ProximitySensor))) && m_chaperoneAlarmSoundActive) { - parent->cancelAlarm01Sound(); - m_chaperoneAlarmSoundActive = false; - } - } - - // Show Dashboard - if (m_enableChaperoneShowDashboard) { - float activationDistance = m_chaperoneShowDashboardDistance * m_chaperoneVelocityModifierCurrent; - if (distance <= activationDistance && !m_chaperoneShowDashboardActive) { - if (!vr::VROverlay()->IsDashboardVisible()) { - vr::VROverlay()->ShowDashboard(OverlayController::applicationKey); - } - m_chaperoneShowDashboardActive = true; - } else if (distance > activationDistance && m_chaperoneShowDashboardActive) { - m_chaperoneShowDashboardActive = false; - } - } + // Show Dashboard + if ( m_enableChaperoneShowDashboard ) + { + float activationDistance = m_chaperoneShowDashboardDistance + * m_chaperoneVelocityModifierCurrent; + if ( distance <= activationDistance && !m_chaperoneShowDashboardActive ) + { + if ( !vr::VROverlay()->IsDashboardVisible() ) + { + vr::VROverlay()->ShowDashboard( + OverlayController::applicationKey ); + } + m_chaperoneShowDashboardActive = true; + } + else if ( distance > activationDistance + && m_chaperoneShowDashboardActive ) + { + m_chaperoneShowDashboardActive = false; + } + } } +void ChaperoneTabController::eventLoopTick( + vr::TrackedDevicePose_t* devicePoses, + float leftSpeed, + float rightSpeed, + float hmdSpeed ) +{ + m_chaperoneVelocityModifierCurrent = 1.0f; + if ( m_enableChaperoneVelocityModifier ) + { + float mod = m_chaperoneVelocityModifier + * std::max( { leftSpeed, rightSpeed, hmdSpeed } ); + if ( mod > 0.02 ) + { + m_chaperoneVelocityModifierCurrent += mod; + } + } + // LOG(INFO) << "m_chaperoneVelocityModifierCurrent: " << + // m_chaperoneVelocityModifierCurrent; + float newFadeDistance = m_fadeDistance * m_chaperoneVelocityModifierCurrent; + if ( m_fadeDistanceModified != newFadeDistance ) + { + m_fadeDistanceModified = newFadeDistance; + vr::VRSettings()->SetFloat( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_FadeDistance_Float, + m_fadeDistanceModified ); + vr::VRSettings()->Sync(); + } -void ChaperoneTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed, float hmdSpeed) { - m_chaperoneVelocityModifierCurrent = 1.0f; - if (m_enableChaperoneVelocityModifier) { - float mod = m_chaperoneVelocityModifier * std::max({ leftSpeed, rightSpeed, hmdSpeed }); - if (mod > 0.02) { - m_chaperoneVelocityModifierCurrent += mod; - } - } - //LOG(INFO) << "m_chaperoneVelocityModifierCurrent: " << m_chaperoneVelocityModifierCurrent; - float newFadeDistance = m_fadeDistance * m_chaperoneVelocityModifierCurrent; - if (m_fadeDistanceModified != newFadeDistance) { - m_fadeDistanceModified = newFadeDistance; - vr::VRSettings()->SetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, m_fadeDistanceModified); - vr::VRSettings()->Sync(); - } + if ( devicePoses ) + { + std::lock_guard lock( + parent->chaperoneUtils().mutex() ); + auto minDistance = NAN; + auto& poseHmd = devicePoses[vr::k_unTrackedDeviceIndex_Hmd]; + if ( poseHmd.bPoseIsValid && poseHmd.bDeviceIsConnected + && poseHmd.eTrackingResult == vr::TrackingResult_Running_OK ) + { + auto distanceHmd = parent->chaperoneUtils().getDistanceToChaperone( + { poseHmd.mDeviceToAbsoluteTracking.m[0][3], + poseHmd.mDeviceToAbsoluteTracking.m[1][3], + poseHmd.mDeviceToAbsoluteTracking.m[2][3] } ); + if ( !std::isnan( distanceHmd ) ) + { + minDistance = distanceHmd; + } + } + auto leftIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_LeftHand ); + if ( leftIndex != vr::k_unTrackedDeviceIndexInvalid ) + { + auto& poseLeft = devicePoses[leftIndex]; + if ( poseLeft.bPoseIsValid && poseLeft.bDeviceIsConnected + && poseLeft.eTrackingResult == vr::TrackingResult_Running_OK ) + { + auto distanceLeft + = parent->chaperoneUtils().getDistanceToChaperone( + { poseLeft.mDeviceToAbsoluteTracking.m[0][3], + poseLeft.mDeviceToAbsoluteTracking.m[1][3], + poseLeft.mDeviceToAbsoluteTracking.m[2][3] } ); + if ( !std::isnan( distanceLeft ) + && ( std::isnan( minDistance ) + || distanceLeft < minDistance ) ) + { + minDistance = distanceLeft; + } + } + } + auto rightIndex + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_RightHand ); + if ( rightIndex != vr::k_unTrackedDeviceIndexInvalid ) + { + auto& poseRight = devicePoses[rightIndex]; + if ( poseRight.bPoseIsValid && poseRight.bDeviceIsConnected + && poseRight.eTrackingResult == vr::TrackingResult_Running_OK ) + { + auto distanceRight + = parent->chaperoneUtils().getDistanceToChaperone( + { poseRight.mDeviceToAbsoluteTracking.m[0][3], + poseRight.mDeviceToAbsoluteTracking.m[1][3], + poseRight.mDeviceToAbsoluteTracking.m[2][3] } ); + if ( !std::isnan( distanceRight ) + && ( std::isnan( minDistance ) + || distanceRight < minDistance ) ) + { + minDistance = distanceRight; + } + } + } + if ( !std::isnan( minDistance ) ) + { + handleChaperoneWarnings( minDistance ); + } + } - if (devicePoses) { - std::lock_guard lock(parent->chaperoneUtils().mutex()); - auto minDistance = NAN; - auto& poseHmd = devicePoses[vr::k_unTrackedDeviceIndex_Hmd]; - if (poseHmd.bPoseIsValid && poseHmd.bDeviceIsConnected && poseHmd.eTrackingResult == vr::TrackingResult_Running_OK) { - auto distanceHmd = parent->chaperoneUtils().getDistanceToChaperone({ - poseHmd.mDeviceToAbsoluteTracking.m[0][3], - poseHmd.mDeviceToAbsoluteTracking.m[1][3], - poseHmd.mDeviceToAbsoluteTracking.m[2][3] - }); - if (!std::isnan(distanceHmd)) { - minDistance = distanceHmd; - } - } - auto leftIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - if (leftIndex != vr::k_unTrackedDeviceIndexInvalid) { - auto& poseLeft = devicePoses[leftIndex]; - if (poseLeft.bPoseIsValid && poseLeft.bDeviceIsConnected && poseLeft.eTrackingResult == vr::TrackingResult_Running_OK) { - auto distanceLeft = parent->chaperoneUtils().getDistanceToChaperone({ - poseLeft.mDeviceToAbsoluteTracking.m[0][3], - poseLeft.mDeviceToAbsoluteTracking.m[1][3], - poseLeft.mDeviceToAbsoluteTracking.m[2][3] - }); - if (!std::isnan(distanceLeft) && (std::isnan(minDistance) || distanceLeft < minDistance)) { - minDistance = distanceLeft; - } - } - } - auto rightIndex = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (rightIndex != vr::k_unTrackedDeviceIndexInvalid) { - auto& poseRight = devicePoses[rightIndex]; - if (poseRight.bPoseIsValid && poseRight.bDeviceIsConnected && poseRight.eTrackingResult == vr::TrackingResult_Running_OK) { - auto distanceRight = parent->chaperoneUtils().getDistanceToChaperone({ - poseRight.mDeviceToAbsoluteTracking.m[0][3], - poseRight.mDeviceToAbsoluteTracking.m[1][3], - poseRight.mDeviceToAbsoluteTracking.m[2][3] - }); - if (!std::isnan(distanceRight) && (std::isnan(minDistance) || distanceRight < minDistance)) { - minDistance = distanceRight; - } - } - } - if (!std::isnan(minDistance)) { - handleChaperoneWarnings(minDistance); - } - } - - if (settingsUpdateCounter >= 50) { - vr::EVRSettingsError vrSettingsError; - float vis = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaA_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaA_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setBoundsVisibility(vis/255.0f); - if (m_chaperoneVelocityModifierCurrent == 1.0f) { - auto fd = vr::VRSettings()->GetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_FadeDistance_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setFadeDistance(fd); - } - auto cm = vr::VRSettings()->GetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setCenterMarker(cm); - auto ps = vr::VRSettings()->GetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_PlaySpaceOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setPlaySpaceMarker(ps); - updateHeight(getBoundsMaxY()); - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } + if ( settingsUpdateCounter >= 50 ) + { + vr::EVRSettingsError vrSettingsError; + float vis = vr::VRSettings()->GetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaA_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_ColorGammaA_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setBoundsVisibility( vis / 255.0f ); + if ( m_chaperoneVelocityModifierCurrent == 1.0f ) + { + auto fd = vr::VRSettings()->GetFloat( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_FadeDistance_Float, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not read \"" + << vr::k_pch_CollisionBounds_FadeDistance_Float + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setFadeDistance( fd ); + } + auto cm = vr::VRSettings()->GetBool( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setCenterMarker( cm ); + auto ps = vr::VRSettings()->GetBool( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_PlaySpaceOn_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setPlaySpaceMarker( ps ); + updateHeight( getBoundsMaxY() ); + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + } } - -float ChaperoneTabController::boundsVisibility() const { - return m_visibility; +float ChaperoneTabController::boundsVisibility() const +{ + return m_visibility; } - -void ChaperoneTabController::setBoundsVisibility(float value, bool notify) { - if (m_visibility != value) { - m_visibility = value; - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaA_Int32, 255 * m_visibility); - vr::VRSettings()->Sync(); - if (notify) { - emit boundsVisibilityChanged(m_visibility); - } - } +void ChaperoneTabController::setBoundsVisibility( float value, bool notify ) +{ + if ( m_visibility != value ) + { + m_visibility = value; + vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaA_Int32, + 255 * m_visibility ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit boundsVisibilityChanged( m_visibility ); + } + } } - -float ChaperoneTabController::fadeDistance() const { - return m_fadeDistance; +float ChaperoneTabController::fadeDistance() const +{ + return m_fadeDistance; } - -void ChaperoneTabController::setFadeDistance(float value, bool notify) { - if (m_fadeDistance != value) { - m_fadeDistance = value; - vr::VRSettings()->SetFloat(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, m_fadeDistance); - vr::VRSettings()->Sync(); - if (notify) { - emit fadeDistanceChanged(m_fadeDistance); - } - } +void ChaperoneTabController::setFadeDistance( float value, bool notify ) +{ + if ( m_fadeDistance != value ) + { + m_fadeDistance = value; + vr::VRSettings()->SetFloat( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_FadeDistance_Float, + m_fadeDistance ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit fadeDistanceChanged( m_fadeDistance ); + } + } } - -float ChaperoneTabController::height() const { - return m_height; +float ChaperoneTabController::height() const +{ + return m_height; } - -void ChaperoneTabController::setHeight(float value, bool notify) { - if (m_height != value) { - m_height = value; - vr::VRChaperoneSetup()->RevertWorkingCopy(); - unsigned collisionBoundsCount = 0; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(nullptr, &collisionBoundsCount); - if (collisionBoundsCount > 0) { - vr::HmdQuad_t* collisionBounds = new vr::HmdQuad_t[collisionBoundsCount]; - vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo(collisionBounds, &collisionBoundsCount); - for (unsigned b = 0; b < collisionBoundsCount; b++) { - collisionBounds[b].vCorners[0].v[1] = 0.0; - collisionBounds[b].vCorners[1].v[1] = value; - collisionBounds[b].vCorners[2].v[1] = value; - collisionBounds[b].vCorners[3].v[1] = 0.0; - } - vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(collisionBounds, collisionBoundsCount); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - delete[] collisionBounds; - } - if (notify) { - emit heightChanged(m_fadeDistance); - } - } +void ChaperoneTabController::setHeight( float value, bool notify ) +{ + if ( m_height != value ) + { + m_height = value; + vr::VRChaperoneSetup()->RevertWorkingCopy(); + unsigned collisionBoundsCount = 0; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + nullptr, &collisionBoundsCount ); + if ( collisionBoundsCount > 0 ) + { + vr::HmdQuad_t* collisionBounds + = new vr::HmdQuad_t[collisionBoundsCount]; + vr::VRChaperoneSetup()->GetWorkingCollisionBoundsInfo( + collisionBounds, &collisionBoundsCount ); + for ( unsigned b = 0; b < collisionBoundsCount; b++ ) + { + collisionBounds[b].vCorners[0].v[1] = 0.0; + collisionBounds[b].vCorners[1].v[1] = value; + collisionBounds[b].vCorners[2].v[1] = value; + collisionBounds[b].vCorners[3].v[1] = 0.0; + } + vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo( + collisionBounds, collisionBoundsCount ); + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + delete[] collisionBounds; + } + if ( notify ) + { + emit heightChanged( m_fadeDistance ); + } + } } - -void ChaperoneTabController::updateHeight(float value, bool notify) { - if (m_height != value) { - m_height = value; - if (notify) { - emit heightChanged(m_fadeDistance); - } - } +void ChaperoneTabController::updateHeight( float value, bool notify ) +{ + if ( m_height != value ) + { + m_height = value; + if ( notify ) + { + emit heightChanged( m_fadeDistance ); + } + } } - -bool ChaperoneTabController::centerMarker() const { - return m_centerMarker; +bool ChaperoneTabController::centerMarker() const +{ + return m_centerMarker; } -void ChaperoneTabController::setCenterMarker(bool value, bool notify) { - if (m_centerMarker != value) { - m_centerMarker = value; - vr::VRSettings()->SetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, m_centerMarker); - vr::VRSettings()->Sync(); - if (notify) { - emit centerMarkerChanged(m_centerMarker); - } - } +void ChaperoneTabController::setCenterMarker( bool value, bool notify ) +{ + if ( m_centerMarker != value ) + { + m_centerMarker = value; + vr::VRSettings()->SetBool( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, + m_centerMarker ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit centerMarkerChanged( m_centerMarker ); + } + } } -bool ChaperoneTabController::playSpaceMarker() const { - return m_playSpaceMarker; +bool ChaperoneTabController::playSpaceMarker() const +{ + return m_playSpaceMarker; } -void ChaperoneTabController::setPlaySpaceMarker(bool value, bool notify) { - if (m_playSpaceMarker != value) { - m_playSpaceMarker = value; - vr::VRSettings()->SetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, m_playSpaceMarker); - vr::VRSettings()->Sync(); - if (notify) { - emit playSpaceMarkerChanged(m_playSpaceMarker); - } - } +void ChaperoneTabController::setPlaySpaceMarker( bool value, bool notify ) +{ + if ( m_playSpaceMarker != value ) + { + m_playSpaceMarker = value; + vr::VRSettings()->SetBool( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, + m_playSpaceMarker ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit playSpaceMarkerChanged( m_playSpaceMarker ); + } + } } -bool ChaperoneTabController::forceBounds() const { - return m_forceBounds; +bool ChaperoneTabController::forceBounds() const +{ + return m_forceBounds; } - -bool ChaperoneTabController::isChaperoneSwitchToBeginnerEnabled() const { - return m_enableChaperoneSwitchToBeginner; +bool ChaperoneTabController::isChaperoneSwitchToBeginnerEnabled() const +{ + return m_enableChaperoneSwitchToBeginner; } -float ChaperoneTabController::chaperoneSwitchToBeginnerDistance() const { - return m_chaperoneSwitchToBeginnerDistance; +float ChaperoneTabController::chaperoneSwitchToBeginnerDistance() const +{ + return m_chaperoneSwitchToBeginnerDistance; } - -bool ChaperoneTabController::isChaperoneHapticFeedbackEnabled() const { - return m_enableChaperoneHapticFeedback; +bool ChaperoneTabController::isChaperoneHapticFeedbackEnabled() const +{ + return m_enableChaperoneHapticFeedback; } -float ChaperoneTabController::chaperoneHapticFeedbackDistance() const { - return m_chaperoneHapticFeedbackDistance; +float ChaperoneTabController::chaperoneHapticFeedbackDistance() const +{ + return m_chaperoneHapticFeedbackDistance; } - -bool ChaperoneTabController::isChaperoneAlarmSoundEnabled() const { - return m_enableChaperoneAlarmSound; +bool ChaperoneTabController::isChaperoneAlarmSoundEnabled() const +{ + return m_enableChaperoneAlarmSound; } -bool ChaperoneTabController::isChaperoneAlarmSoundLooping() const { - return m_chaperoneAlarmSoundLooping; +bool ChaperoneTabController::isChaperoneAlarmSoundLooping() const +{ + return m_chaperoneAlarmSoundLooping; } -bool ChaperoneTabController::isChaperoneAlarmSoundAdjustVolume() const { - return m_chaperoneAlarmSoundAdjustVolume; +bool ChaperoneTabController::isChaperoneAlarmSoundAdjustVolume() const +{ + return m_chaperoneAlarmSoundAdjustVolume; } -float ChaperoneTabController::chaperoneAlarmSoundDistance() const { - return m_chaperoneAlarmSoundDistance; +float ChaperoneTabController::chaperoneAlarmSoundDistance() const +{ + return m_chaperoneAlarmSoundDistance; } - -bool ChaperoneTabController::isChaperoneShowDashboardEnabled() const { - return m_enableChaperoneShowDashboard; +bool ChaperoneTabController::isChaperoneShowDashboardEnabled() const +{ + return m_enableChaperoneShowDashboard; } -float ChaperoneTabController::chaperoneShowDashboardDistance() const { - return m_chaperoneShowDashboardDistance; +float ChaperoneTabController::chaperoneShowDashboardDistance() const +{ + return m_chaperoneShowDashboardDistance; } - -bool ChaperoneTabController::isChaperoneVelocityModifierEnabled() const { - return m_enableChaperoneVelocityModifier; +bool ChaperoneTabController::isChaperoneVelocityModifierEnabled() const +{ + return m_enableChaperoneVelocityModifier; } -float ChaperoneTabController::chaperoneVelocityModifier() const { - return m_chaperoneVelocityModifier; +float ChaperoneTabController::chaperoneVelocityModifier() const +{ + return m_chaperoneVelocityModifier; } - - - -Q_INVOKABLE unsigned ChaperoneTabController::getChaperoneProfileCount() { - return (unsigned)chaperoneProfiles.size(); +Q_INVOKABLE unsigned ChaperoneTabController::getChaperoneProfileCount() +{ + return ( unsigned ) chaperoneProfiles.size(); } -Q_INVOKABLE QString ChaperoneTabController::getChaperoneProfileName(unsigned index) { - if (index >= chaperoneProfiles.size()) { - return QString(); - } else { - return QString::fromStdString(chaperoneProfiles[index].profileName); - } +Q_INVOKABLE QString + ChaperoneTabController::getChaperoneProfileName( unsigned index ) +{ + if ( index >= chaperoneProfiles.size() ) + { + return QString(); + } + else + { + return QString::fromStdString( chaperoneProfiles[index].profileName ); + } } -void ChaperoneTabController::setForceBounds(bool value, bool notify) { - if (m_forceBounds != value) { - m_forceBounds = value; - vr::VRChaperone()->ForceBoundsVisible(m_forceBounds); - if (notify) { - emit forceBoundsChanged(m_forceBounds); - } - } +void ChaperoneTabController::setForceBounds( bool value, bool notify ) +{ + if ( m_forceBounds != value ) + { + m_forceBounds = value; + vr::VRChaperone()->ForceBoundsVisible( m_forceBounds ); + if ( notify ) + { + emit forceBoundsChanged( m_forceBounds ); + } + } } - -void ChaperoneTabController::setChaperoneSwitchToBeginnerEnabled(bool value, bool notify) { - if (m_enableChaperoneSwitchToBeginner != value) { - if (!value && m_chaperoneSwitchToBeginnerActive) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, m_chaperoneSwitchToBeginnerLastStyle, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(true); - } - } - m_enableChaperoneSwitchToBeginner = value; - m_chaperoneSwitchToBeginnerActive = false; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneSwitchToBeginnerEnabled", m_enableChaperoneSwitchToBeginner); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneSwitchToBeginnerEnabledChanged(m_enableChaperoneSwitchToBeginner); - } - } +void ChaperoneTabController::setChaperoneSwitchToBeginnerEnabled( bool value, + bool notify ) +{ + if ( m_enableChaperoneSwitchToBeginner != value ) + { + if ( !value && m_chaperoneSwitchToBeginnerActive ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + m_chaperoneSwitchToBeginnerLastStyle, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not set \"" + << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync( true ); + } + } + m_enableChaperoneSwitchToBeginner = value; + m_chaperoneSwitchToBeginnerActive = false; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneSwitchToBeginnerEnabled", + m_enableChaperoneSwitchToBeginner ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneSwitchToBeginnerEnabledChanged( + m_enableChaperoneSwitchToBeginner ); + } + } } -void ChaperoneTabController::setChaperoneSwitchToBeginnerDistance(float value, bool notify) { - if (m_chaperoneSwitchToBeginnerDistance != value) { - m_chaperoneSwitchToBeginnerDistance = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneSwitchToBeginnerDistance", m_chaperoneSwitchToBeginnerDistance); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneSwitchToBeginnerDistanceChanged(m_chaperoneSwitchToBeginnerDistance); - } - } +void ChaperoneTabController::setChaperoneSwitchToBeginnerDistance( float value, + bool notify ) +{ + if ( m_chaperoneSwitchToBeginnerDistance != value ) + { + m_chaperoneSwitchToBeginnerDistance = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneSwitchToBeginnerDistance", + m_chaperoneSwitchToBeginnerDistance ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneSwitchToBeginnerDistanceChanged( + m_chaperoneSwitchToBeginnerDistance ); + } + } } - -void ChaperoneTabController::setChaperoneHapticFeedbackEnabled(bool value, bool notify) { - if (m_enableChaperoneHapticFeedback != value) { - m_chaperoneHapticFeedbackActive = false; - if (m_chaperoneHapticFeedbackThread.joinable()) { - m_chaperoneHapticFeedbackThread.join(); - } - m_enableChaperoneHapticFeedback = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneHapticFeedbackEnabled", m_enableChaperoneHapticFeedback); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneHapticFeedbackEnabledChanged(m_enableChaperoneHapticFeedback); - } - } +void ChaperoneTabController::setChaperoneHapticFeedbackEnabled( bool value, + bool notify ) +{ + if ( m_enableChaperoneHapticFeedback != value ) + { + m_chaperoneHapticFeedbackActive = false; + if ( m_chaperoneHapticFeedbackThread.joinable() ) + { + m_chaperoneHapticFeedbackThread.join(); + } + m_enableChaperoneHapticFeedback = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneHapticFeedbackEnabled", + m_enableChaperoneHapticFeedback ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneHapticFeedbackEnabledChanged( + m_enableChaperoneHapticFeedback ); + } + } } -void ChaperoneTabController::setChaperoneHapticFeedbackDistance(float value, bool notify) { - if (m_chaperoneHapticFeedbackDistance != value) { - m_chaperoneHapticFeedbackDistance = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneHapticFeedbackDistance", m_chaperoneHapticFeedbackDistance); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneHapticFeedbackDistanceChanged(m_chaperoneHapticFeedbackDistance); - } - } +void ChaperoneTabController::setChaperoneHapticFeedbackDistance( float value, + bool notify ) +{ + if ( m_chaperoneHapticFeedbackDistance != value ) + { + m_chaperoneHapticFeedbackDistance = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneHapticFeedbackDistance", + m_chaperoneHapticFeedbackDistance ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneHapticFeedbackDistanceChanged( + m_chaperoneHapticFeedbackDistance ); + } + } } - -void ChaperoneTabController::setChaperoneAlarmSoundEnabled(bool value, bool notify) { - if (m_enableChaperoneAlarmSound != value) { - if (!value && m_chaperoneAlarmSoundActive) { - parent->cancelAlarm01Sound(); - } - m_enableChaperoneAlarmSound = value; - m_chaperoneAlarmSoundActive = false; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneAlarmSoundEnabled", m_enableChaperoneAlarmSound); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneAlarmSoundEnabledChanged(m_enableChaperoneAlarmSound); - } - } +void ChaperoneTabController::setChaperoneAlarmSoundEnabled( bool value, + bool notify ) +{ + if ( m_enableChaperoneAlarmSound != value ) + { + if ( !value && m_chaperoneAlarmSoundActive ) + { + parent->cancelAlarm01Sound(); + } + m_enableChaperoneAlarmSound = value; + m_chaperoneAlarmSoundActive = false; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneAlarmSoundEnabled", + m_enableChaperoneAlarmSound ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneAlarmSoundEnabledChanged( + m_enableChaperoneAlarmSound ); + } + } } -void ChaperoneTabController::setChaperoneAlarmSoundLooping(bool value, bool notify) { - if (m_chaperoneAlarmSoundLooping != value) { - m_chaperoneAlarmSoundLooping = value; - if (m_enableChaperoneAlarmSound && m_chaperoneAlarmSoundActive) { - if (m_chaperoneAlarmSoundLooping) { - parent->playAlarm01Sound(m_chaperoneAlarmSoundLooping); - } else { - parent->cancelAlarm01Sound(); - } - } - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneAlarmSoundLooping", m_chaperoneAlarmSoundLooping); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneAlarmSoundLoopingChanged(m_chaperoneAlarmSoundLooping); - } - } +void ChaperoneTabController::setChaperoneAlarmSoundLooping( bool value, + bool notify ) +{ + if ( m_chaperoneAlarmSoundLooping != value ) + { + m_chaperoneAlarmSoundLooping = value; + if ( m_enableChaperoneAlarmSound && m_chaperoneAlarmSoundActive ) + { + if ( m_chaperoneAlarmSoundLooping ) + { + parent->playAlarm01Sound( m_chaperoneAlarmSoundLooping ); + } + else + { + parent->cancelAlarm01Sound(); + } + } + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneAlarmSoundLooping", + m_chaperoneAlarmSoundLooping ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneAlarmSoundLoopingChanged( + m_chaperoneAlarmSoundLooping ); + } + } } -void ChaperoneTabController::setChaperoneAlarmSoundAdjustVolume(bool value, bool notify) { - if (m_chaperoneAlarmSoundAdjustVolume != value) { - m_chaperoneAlarmSoundAdjustVolume = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneAlarmSoundAdjustVolume", m_chaperoneAlarmSoundAdjustVolume); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneAlarmSoundAdjustVolumeChanged(m_chaperoneAlarmSoundAdjustVolume); - } - } +void ChaperoneTabController::setChaperoneAlarmSoundAdjustVolume( bool value, + bool notify ) +{ + if ( m_chaperoneAlarmSoundAdjustVolume != value ) + { + m_chaperoneAlarmSoundAdjustVolume = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneAlarmSoundAdjustVolume", + m_chaperoneAlarmSoundAdjustVolume ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneAlarmSoundAdjustVolumeChanged( + m_chaperoneAlarmSoundAdjustVolume ); + } + } } -void ChaperoneTabController::setChaperoneAlarmSoundDistance(float value, bool notify) { - if (m_chaperoneAlarmSoundDistance != value) { - m_chaperoneAlarmSoundDistance = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneAlarmSoundDistance", m_chaperoneAlarmSoundDistance); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneAlarmSoundDistanceChanged(m_chaperoneAlarmSoundDistance); - } - } +void ChaperoneTabController::setChaperoneAlarmSoundDistance( float value, + bool notify ) +{ + if ( m_chaperoneAlarmSoundDistance != value ) + { + m_chaperoneAlarmSoundDistance = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneAlarmSoundDistance", + m_chaperoneAlarmSoundDistance ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneAlarmSoundDistanceChanged( + m_chaperoneAlarmSoundDistance ); + } + } } - -void ChaperoneTabController::setChaperoneShowDashboardEnabled(bool value, bool notify) { - if (m_enableChaperoneShowDashboard != value) { - m_enableChaperoneShowDashboard = value; - m_chaperoneShowDashboardActive = false; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneShowDashboardEnabled", m_enableChaperoneShowDashboard); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneShowDashboardEnabledChanged(m_enableChaperoneShowDashboard); - } - } +void ChaperoneTabController::setChaperoneShowDashboardEnabled( bool value, + bool notify ) +{ + if ( m_enableChaperoneShowDashboard != value ) + { + m_enableChaperoneShowDashboard = value; + m_chaperoneShowDashboardActive = false; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneShowDashboardEnabled", + m_enableChaperoneShowDashboard ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneShowDashboardEnabledChanged( + m_enableChaperoneShowDashboard ); + } + } } -void ChaperoneTabController::setChaperoneShowDashboardDistance(float value, bool notify) { - if (m_chaperoneShowDashboardDistance != value) { - m_chaperoneShowDashboardDistance = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneShowDashboardDistance", m_chaperoneShowDashboardDistance); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneShowDashboardDistanceChanged(m_chaperoneShowDashboardDistance); - } - } +void ChaperoneTabController::setChaperoneShowDashboardDistance( float value, + bool notify ) +{ + if ( m_chaperoneShowDashboardDistance != value ) + { + m_chaperoneShowDashboardDistance = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneShowDashboardDistance", + m_chaperoneShowDashboardDistance ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneShowDashboardDistanceChanged( + m_chaperoneShowDashboardDistance ); + } + } } - -void ChaperoneTabController::setChaperoneVelocityModifierEnabled(bool value, bool notify) { - if (m_enableChaperoneVelocityModifier != value) { - m_enableChaperoneVelocityModifier = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneVelocityModifierEnabled", m_enableChaperoneVelocityModifier); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneVelocityModifierEnabledChanged(m_enableChaperoneVelocityModifier); - } - } +void ChaperoneTabController::setChaperoneVelocityModifierEnabled( bool value, + bool notify ) +{ + if ( m_enableChaperoneVelocityModifier != value ) + { + m_enableChaperoneVelocityModifier = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneVelocityModifierEnabled", + m_enableChaperoneVelocityModifier ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneVelocityModifierEnabledChanged( + m_enableChaperoneVelocityModifier ); + } + } } -void ChaperoneTabController::setChaperoneVelocityModifier(float value, bool notify) { - if (m_chaperoneVelocityModifier != value) { - m_chaperoneVelocityModifier = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("chaperoneSettings"); - settings->setValue("chaperoneVelocityModifier", m_chaperoneVelocityModifier); - settings->endGroup(); - settings->sync(); - if (notify) { - emit chaperoneVelocityModifierChanged(m_chaperoneVelocityModifier); - } - } +void ChaperoneTabController::setChaperoneVelocityModifier( float value, + bool notify ) +{ + if ( m_chaperoneVelocityModifier != value ) + { + m_chaperoneVelocityModifier = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "chaperoneSettings" ); + settings->setValue( "chaperoneVelocityModifier", + m_chaperoneVelocityModifier ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit chaperoneVelocityModifierChanged( + m_chaperoneVelocityModifier ); + } + } } - - -void ChaperoneTabController::flipOrientation() { - parent->RotateUniverseCenter(vr::TrackingUniverseStanding, (float)M_PI); +void ChaperoneTabController::flipOrientation() +{ + parent->RotateUniverseCenter( vr::TrackingUniverseStanding, + ( float ) M_PI ); } -void ChaperoneTabController::reloadFromDisk() { - vr::VRChaperoneSetup()->ReloadFromDisk(vr::EChaperoneConfigFile_Live); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); +void ChaperoneTabController::reloadFromDisk() +{ + vr::VRChaperoneSetup()->ReloadFromDisk( vr::EChaperoneConfigFile_Live ); + vr::VRChaperoneSetup()->CommitWorkingCopy( vr::EChaperoneConfigFile_Live ); } -void ChaperoneTabController::addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker, - bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds, bool includesProximityWarningSettings) { - vr::EVRSettingsError vrSettingsError; - ChaperoneProfile* profile = nullptr; - for (auto& p : chaperoneProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } - } - if (!profile) { - auto i = chaperoneProfiles.size(); - chaperoneProfiles.emplace_back(); - profile = &chaperoneProfiles[i]; - } - profile->profileName = name.toStdString(); - profile->includesChaperoneGeometry = includeGeometry; - if (includeGeometry) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - uint32_t quadCount = 0; - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(nullptr, &quadCount); - profile->chaperoneGeometryQuadCount = quadCount; - profile->chaperoneGeometryQuads.reset(new vr::HmdQuad_t[quadCount]); - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(profile->chaperoneGeometryQuads.get(), &quadCount); - vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose(&profile->standingCenter); - vr::VRChaperoneSetup()->GetWorkingPlayAreaSize(&profile->playSpaceAreaX, &profile->playSpaceAreaZ); - } - profile->includesVisibility = includeVisbility; - if (includeVisbility) { - profile->visibility = m_visibility; - } - profile->includesFadeDistance = includeFadeDistance; - if (includeFadeDistance) { - profile->fadeDistance = m_fadeDistance; - } - profile->includesCenterMarker = includeCenterMarker; - if (includeCenterMarker) { - profile->centerMarker = m_centerMarker; - } - profile->includesPlaySpaceMarker = includePlaySpaceMarker; - if (includePlaySpaceMarker) { - profile->playSpaceMarker = m_playSpaceMarker; - } - profile->includesFloorBoundsMarker = includeFloorBounds; - if (includeFloorBounds) { - profile->floorBoundsMarker = vr::VRSettings()->GetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - } - profile->includesBoundsColor = includeBoundsColor; - if (includeBoundsColor) { - profile->boundsColor[0] = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaR_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaR_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - profile->boundsColor[1] = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaG_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaG_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - profile->boundsColor[2] = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaB_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_ColorGammaB_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - } - profile->includesChaperoneStyle = includeChaperoneStyle; - if (includeChaperoneStyle) { - profile->chaperoneStyle = vr::VRSettings()->GetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - } - profile->includesForceBounds = includeForceBounds; - if (includeForceBounds) { - profile->forceBounds = m_forceBounds; - } - profile->includesProximityWarningSettings = includesProximityWarningSettings; - if (includesProximityWarningSettings) { - profile->enableChaperoneSwitchToBeginner = m_enableChaperoneSwitchToBeginner; - profile->chaperoneSwitchToBeginnerDistance = m_chaperoneSwitchToBeginnerDistance; - profile->enableChaperoneHapticFeedback = m_enableChaperoneHapticFeedback; - profile->chaperoneHapticFeedbackDistance = m_chaperoneHapticFeedbackDistance; - profile->enableChaperoneAlarmSound = m_enableChaperoneAlarmSound; - profile->chaperoneAlarmSoundLooping = m_chaperoneAlarmSoundLooping; - profile->chaperoneAlarmSoundAdjustVolume = m_chaperoneAlarmSoundAdjustVolume; - profile->chaperoneAlarmSoundDistance = m_chaperoneAlarmSoundDistance; - profile->enableChaperoneShowDashboard = m_enableChaperoneShowDashboard; - profile->chaperoneShowDashboardDistance = m_chaperoneShowDashboardDistance; - profile->enableChaperoneVelocityModifier = m_enableChaperoneVelocityModifier; - profile->chaperoneVelocityModifier = m_chaperoneVelocityModifier; - } - saveChaperoneProfiles(); - OverlayController::appSettings()->sync(); - emit chaperoneProfilesUpdated(); +void ChaperoneTabController::addChaperoneProfile( + QString name, + bool includeGeometry, + bool includeVisbility, + bool includeFadeDistance, + bool includeCenterMarker, + bool includePlaySpaceMarker, + bool includeFloorBounds, + bool includeBoundsColor, + bool includeChaperoneStyle, + bool includeForceBounds, + bool includesProximityWarningSettings ) +{ + vr::EVRSettingsError vrSettingsError; + ChaperoneProfile* profile = nullptr; + for ( auto& p : chaperoneProfiles ) + { + if ( p.profileName.compare( name.toStdString() ) == 0 ) + { + profile = &p; + break; + } + } + if ( !profile ) + { + auto i = chaperoneProfiles.size(); + chaperoneProfiles.emplace_back(); + profile = &chaperoneProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->includesChaperoneGeometry = includeGeometry; + if ( includeGeometry ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + uint32_t quadCount = 0; + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( nullptr, + &quadCount ); + profile->chaperoneGeometryQuadCount = quadCount; + profile->chaperoneGeometryQuads.reset( new vr::HmdQuad_t[quadCount] ); + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( + profile->chaperoneGeometryQuads.get(), &quadCount ); + vr::VRChaperoneSetup()->GetWorkingStandingZeroPoseToRawTrackingPose( + &profile->standingCenter ); + vr::VRChaperoneSetup()->GetWorkingPlayAreaSize( + &profile->playSpaceAreaX, &profile->playSpaceAreaZ ); + } + profile->includesVisibility = includeVisbility; + if ( includeVisbility ) + { + profile->visibility = m_visibility; + } + profile->includesFadeDistance = includeFadeDistance; + if ( includeFadeDistance ) + { + profile->fadeDistance = m_fadeDistance; + } + profile->includesCenterMarker = includeCenterMarker; + if ( includeCenterMarker ) + { + profile->centerMarker = m_centerMarker; + } + profile->includesPlaySpaceMarker = includePlaySpaceMarker; + if ( includePlaySpaceMarker ) + { + profile->playSpaceMarker = m_playSpaceMarker; + } + profile->includesFloorBoundsMarker = includeFloorBounds; + if ( includeFloorBounds ) + { + profile->floorBoundsMarker = vr::VRSettings()->GetBool( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + } + profile->includesBoundsColor = includeBoundsColor; + if ( includeBoundsColor ) + { + profile->boundsColor[0] = vr::VRSettings()->GetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaR_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_ColorGammaR_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + profile->boundsColor[1] = vr::VRSettings()->GetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaG_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_ColorGammaG_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + profile->boundsColor[2] = vr::VRSettings()->GetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaB_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_ColorGammaB_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + } + profile->includesChaperoneStyle = includeChaperoneStyle; + if ( includeChaperoneStyle ) + { + profile->chaperoneStyle + = vr::VRSettings()->GetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_CollisionBounds_Style_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + } + profile->includesForceBounds = includeForceBounds; + if ( includeForceBounds ) + { + profile->forceBounds = m_forceBounds; + } + profile->includesProximityWarningSettings + = includesProximityWarningSettings; + if ( includesProximityWarningSettings ) + { + profile->enableChaperoneSwitchToBeginner + = m_enableChaperoneSwitchToBeginner; + profile->chaperoneSwitchToBeginnerDistance + = m_chaperoneSwitchToBeginnerDistance; + profile->enableChaperoneHapticFeedback + = m_enableChaperoneHapticFeedback; + profile->chaperoneHapticFeedbackDistance + = m_chaperoneHapticFeedbackDistance; + profile->enableChaperoneAlarmSound = m_enableChaperoneAlarmSound; + profile->chaperoneAlarmSoundLooping = m_chaperoneAlarmSoundLooping; + profile->chaperoneAlarmSoundAdjustVolume + = m_chaperoneAlarmSoundAdjustVolume; + profile->chaperoneAlarmSoundDistance = m_chaperoneAlarmSoundDistance; + profile->enableChaperoneShowDashboard = m_enableChaperoneShowDashboard; + profile->chaperoneShowDashboardDistance + = m_chaperoneShowDashboardDistance; + profile->enableChaperoneVelocityModifier + = m_enableChaperoneVelocityModifier; + profile->chaperoneVelocityModifier = m_chaperoneVelocityModifier; + } + saveChaperoneProfiles(); + OverlayController::appSettings()->sync(); + emit chaperoneProfilesUpdated(); } -void ChaperoneTabController::applyChaperoneProfile(unsigned index) { - if (index < chaperoneProfiles.size()) { - auto& profile = chaperoneProfiles[index]; - if (profile.includesChaperoneGeometry) { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo(profile.chaperoneGeometryQuads.get(), profile.chaperoneGeometryQuadCount); - vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose(&profile.standingCenter); - vr::VRChaperoneSetup()->SetWorkingPlayAreaSize(profile.playSpaceAreaX, profile.playSpaceAreaZ); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - } - if (profile.includesVisibility) { - setBoundsVisibility(profile.visibility); - } - if (profile.includesFadeDistance) { - setFadeDistance(profile.fadeDistance); - } - if (profile.includesCenterMarker) { - setCenterMarker(profile.centerMarker); - } - if (profile.includesPlaySpaceMarker) { - setPlaySpaceMarker(profile.playSpaceMarker); - } - if (profile.includesFloorBoundsMarker) { - vr::VRSettings()->SetBool(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool, profile.floorBoundsMarker); - } - if (profile.includesBoundsColor) { - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaR_Int32, profile.boundsColor[0]); - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaG_Int32, profile.boundsColor[1]); - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaB_Int32, profile.boundsColor[2]); - } - if (profile.includesChaperoneStyle) { - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, profile.chaperoneStyle); - } - if (profile.includesForceBounds) { - setForceBounds(profile.forceBounds); - } - if (profile.includesProximityWarningSettings) { - setChaperoneSwitchToBeginnerDistance(profile.chaperoneSwitchToBeginnerDistance); - setChaperoneSwitchToBeginnerEnabled(profile.enableChaperoneSwitchToBeginner); - setChaperoneHapticFeedbackDistance(profile.chaperoneHapticFeedbackDistance); - setChaperoneHapticFeedbackEnabled(profile.enableChaperoneHapticFeedback); - setChaperoneAlarmSoundLooping(profile.chaperoneAlarmSoundLooping); - setChaperoneAlarmSoundAdjustVolume(profile.chaperoneAlarmSoundAdjustVolume); - setChaperoneAlarmSoundDistance(profile.chaperoneAlarmSoundDistance); - setChaperoneAlarmSoundEnabled(profile.enableChaperoneAlarmSound); - setChaperoneShowDashboardDistance(profile.chaperoneShowDashboardDistance); - setChaperoneShowDashboardEnabled(profile.enableChaperoneShowDashboard); - setChaperoneVelocityModifier(profile.chaperoneVelocityModifier); - setChaperoneVelocityModifierEnabled(profile.enableChaperoneVelocityModifier); - } - vr::VRSettings()->Sync(true); - updateHeight(getBoundsMaxY()); - } +void ChaperoneTabController::applyChaperoneProfile( unsigned index ) +{ + if ( index < chaperoneProfiles.size() ) + { + auto& profile = chaperoneProfiles[index]; + if ( profile.includesChaperoneGeometry ) + { + vr::VRChaperoneSetup()->RevertWorkingCopy(); + vr::VRChaperoneSetup()->SetWorkingCollisionBoundsInfo( + profile.chaperoneGeometryQuads.get(), + profile.chaperoneGeometryQuadCount ); + vr::VRChaperoneSetup()->SetWorkingStandingZeroPoseToRawTrackingPose( + &profile.standingCenter ); + vr::VRChaperoneSetup()->SetWorkingPlayAreaSize( + profile.playSpaceAreaX, profile.playSpaceAreaZ ); + vr::VRChaperoneSetup()->CommitWorkingCopy( + vr::EChaperoneConfigFile_Live ); + } + if ( profile.includesVisibility ) + { + setBoundsVisibility( profile.visibility ); + } + if ( profile.includesFadeDistance ) + { + setFadeDistance( profile.fadeDistance ); + } + if ( profile.includesCenterMarker ) + { + setCenterMarker( profile.centerMarker ); + } + if ( profile.includesPlaySpaceMarker ) + { + setPlaySpaceMarker( profile.playSpaceMarker ); + } + if ( profile.includesFloorBoundsMarker ) + { + vr::VRSettings()->SetBool( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_GroundPerimeterOn_Bool, + profile.floorBoundsMarker ); + } + if ( profile.includesBoundsColor ) + { + vr::VRSettings()->SetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaR_Int32, + profile.boundsColor[0] ); + vr::VRSettings()->SetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaG_Int32, + profile.boundsColor[1] ); + vr::VRSettings()->SetInt32( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaB_Int32, + profile.boundsColor[2] ); + } + if ( profile.includesChaperoneStyle ) + { + vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + profile.chaperoneStyle ); + } + if ( profile.includesForceBounds ) + { + setForceBounds( profile.forceBounds ); + } + if ( profile.includesProximityWarningSettings ) + { + setChaperoneSwitchToBeginnerDistance( + profile.chaperoneSwitchToBeginnerDistance ); + setChaperoneSwitchToBeginnerEnabled( + profile.enableChaperoneSwitchToBeginner ); + setChaperoneHapticFeedbackDistance( + profile.chaperoneHapticFeedbackDistance ); + setChaperoneHapticFeedbackEnabled( + profile.enableChaperoneHapticFeedback ); + setChaperoneAlarmSoundLooping( profile.chaperoneAlarmSoundLooping ); + setChaperoneAlarmSoundAdjustVolume( + profile.chaperoneAlarmSoundAdjustVolume ); + setChaperoneAlarmSoundDistance( + profile.chaperoneAlarmSoundDistance ); + setChaperoneAlarmSoundEnabled( profile.enableChaperoneAlarmSound ); + setChaperoneShowDashboardDistance( + profile.chaperoneShowDashboardDistance ); + setChaperoneShowDashboardEnabled( + profile.enableChaperoneShowDashboard ); + setChaperoneVelocityModifier( profile.chaperoneVelocityModifier ); + setChaperoneVelocityModifierEnabled( + profile.enableChaperoneVelocityModifier ); + } + vr::VRSettings()->Sync( true ); + updateHeight( getBoundsMaxY() ); + } } -void ChaperoneTabController::deleteChaperoneProfile(unsigned index) { - if (index < chaperoneProfiles.size()) { - auto pos = chaperoneProfiles.begin() + index; - chaperoneProfiles.erase(pos); - saveChaperoneProfiles(); - OverlayController::appSettings()->sync(); - emit chaperoneProfilesUpdated(); - } +void ChaperoneTabController::deleteChaperoneProfile( unsigned index ) +{ + if ( index < chaperoneProfiles.size() ) + { + auto pos = chaperoneProfiles.begin() + index; + chaperoneProfiles.erase( pos ); + saveChaperoneProfiles(); + OverlayController::appSettings()->sync(); + emit chaperoneProfilesUpdated(); + } } -float ChaperoneTabController::getBoundsMaxY() { - unsigned collisionBoundsCount = 0; - float result = FP_NAN; - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(nullptr, &collisionBoundsCount); - if (collisionBoundsCount > 0) { - vr::HmdQuad_t* collisionBounds = new vr::HmdQuad_t[collisionBoundsCount]; - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(collisionBounds, &collisionBoundsCount); - for (unsigned b = 0; b < collisionBoundsCount; b++) { - int ci; - if (collisionBounds[b].vCorners[1].v[1] >= collisionBounds[b].vCorners[2].v[1]) { - ci = 1; - } else { - ci = 2; - } - if (std::isnan(result) || result < collisionBounds[b].vCorners[ci].v[1]) { - result = collisionBounds[b].vCorners[ci].v[1]; - } - } - delete[] collisionBounds; - } - return result; +float ChaperoneTabController::getBoundsMaxY() +{ + unsigned collisionBoundsCount = 0; + float result = FP_NAN; + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( nullptr, + &collisionBoundsCount ); + if ( collisionBoundsCount > 0 ) + { + vr::HmdQuad_t* collisionBounds + = new vr::HmdQuad_t[collisionBoundsCount]; + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( + collisionBounds, &collisionBoundsCount ); + for ( unsigned b = 0; b < collisionBoundsCount; b++ ) + { + int ci; + if ( collisionBounds[b].vCorners[1].v[1] + >= collisionBounds[b].vCorners[2].v[1] ) + { + ci = 1; + } + else + { + ci = 2; + } + if ( std::isnan( result ) + || result < collisionBounds[b].vCorners[ci].v[1] ) + { + result = collisionBounds[b].vCorners[ci].v[1]; + } + } + delete[] collisionBounds; + } + return result; } -void ChaperoneTabController::reset() { - vr::EVRSettingsError vrSettingsError; +void ChaperoneTabController::reset() +{ + vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_ColorGammaA_Int32, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_CollisionBounds_ColorGammaA_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_ColorGammaA_Int32, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_CollisionBounds_ColorGammaA_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_FadeDistance_Float, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_CollisionBounds_FadeDistance_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_FadeDistance_Float, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_CollisionBounds_FadeDistance_Float + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_CenterMarkerOn_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_CollisionBounds_CenterMarkerOn_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_CollisionBounds_PlaySpaceOn_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_PlaySpaceOn_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_CollisionBounds_PlaySpaceOn_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - setForceBounds(false); + setForceBounds( false ); - vr::VRSettings()->Sync(); - settingsUpdateCounter = 999; // Easiest way to get default values + vr::VRSettings()->Sync(); + settingsUpdateCounter = 999; // Easiest way to get default values } - -void ChaperoneTabController::shutdown() { - if (m_enableChaperoneSwitchToBeginner && m_chaperoneSwitchToBeginnerActive) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetInt32(vr::k_pch_CollisionBounds_Section, vr::k_pch_CollisionBounds_Style_Int32, m_chaperoneSwitchToBeginnerLastStyle, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"" << vr::k_pch_CollisionBounds_Style_Int32 << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - vr::VRSettings()->Sync(true); - } - } +void ChaperoneTabController::shutdown() +{ + if ( m_enableChaperoneSwitchToBeginner + && m_chaperoneSwitchToBeginnerActive ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetInt32( vr::k_pch_CollisionBounds_Section, + vr::k_pch_CollisionBounds_Style_Int32, + m_chaperoneSwitchToBeginnerLastStyle, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"" + << vr::k_pch_CollisionBounds_Style_Int32 + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + vr::VRSettings()->Sync( true ); + } + } } - -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/ChaperoneTabController.h b/src/tabcontrollers/ChaperoneTabController.h index d4d3293..d7e2be2 100644 --- a/src/tabcontrollers/ChaperoneTabController.h +++ b/src/tabcontrollers/ChaperoneTabController.h @@ -9,234 +9,286 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; +struct ChaperoneProfile +{ + std::string profileName; -struct ChaperoneProfile { - std::string profileName; + bool includesChaperoneGeometry = false; + unsigned chaperoneGeometryQuadCount = 0; + std::unique_ptr chaperoneGeometryQuads = nullptr; + vr::HmdMatrix34_t standingCenter; + float playSpaceAreaX = 0.0f; + float playSpaceAreaZ = 0.0f; - bool includesChaperoneGeometry = false; - unsigned chaperoneGeometryQuadCount = 0; - std::unique_ptr chaperoneGeometryQuads = nullptr; - vr::HmdMatrix34_t standingCenter; - float playSpaceAreaX = 0.0f; - float playSpaceAreaZ = 0.0f; + bool includesVisibility = false; + float visibility = 0.6f; - bool includesVisibility = false; - float visibility = 0.6f; + bool includesFadeDistance = false; + float fadeDistance = 0.7f; - bool includesFadeDistance = false; - float fadeDistance = 0.7f; + bool includesCenterMarker = false; + bool centerMarker = false; - bool includesCenterMarker = false; - bool centerMarker = false; + bool includesPlaySpaceMarker = false; + bool playSpaceMarker = false; - bool includesPlaySpaceMarker = false; - bool playSpaceMarker = false; + bool includesFloorBoundsMarker = false; + bool floorBoundsMarker = false; - bool includesFloorBoundsMarker = false; - bool floorBoundsMarker = false; + bool includesBoundsColor = false; + int boundsColor[3] = { 0, 0, 0 }; - bool includesBoundsColor = false; - int boundsColor[3] = {0, 0, 0}; + bool includesChaperoneStyle = false; + int chaperoneStyle = 0; - bool includesChaperoneStyle = false; - int chaperoneStyle = 0; + bool includesForceBounds = false; + bool forceBounds = false; - bool includesForceBounds = false; - bool forceBounds = false; - - bool includesProximityWarningSettings = false; - bool enableChaperoneSwitchToBeginner = false; - float chaperoneSwitchToBeginnerDistance = 0.0f; - bool enableChaperoneHapticFeedback = false; - float chaperoneHapticFeedbackDistance = 0.0f; - bool enableChaperoneAlarmSound = false; - bool chaperoneAlarmSoundLooping = true; - bool chaperoneAlarmSoundAdjustVolume = false; - float chaperoneAlarmSoundDistance = 0.0f; - bool enableChaperoneShowDashboard = false; - float chaperoneShowDashboardDistance = 0.0f; - bool enableChaperoneVelocityModifier = false; - float chaperoneVelocityModifier = 0.0f; + bool includesProximityWarningSettings = false; + bool enableChaperoneSwitchToBeginner = false; + float chaperoneSwitchToBeginnerDistance = 0.0f; + bool enableChaperoneHapticFeedback = false; + float chaperoneHapticFeedbackDistance = 0.0f; + bool enableChaperoneAlarmSound = false; + bool chaperoneAlarmSoundLooping = true; + bool chaperoneAlarmSoundAdjustVolume = false; + float chaperoneAlarmSoundDistance = 0.0f; + bool enableChaperoneShowDashboard = false; + float chaperoneShowDashboardDistance = 0.0f; + bool enableChaperoneVelocityModifier = false; + float chaperoneVelocityModifier = 0.0f; }; +class ChaperoneTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( float boundsVisibility READ boundsVisibility WRITE + setBoundsVisibility NOTIFY boundsVisibilityChanged ) + Q_PROPERTY( float fadeDistance READ fadeDistance WRITE setFadeDistance + NOTIFY fadeDistanceChanged ) + Q_PROPERTY( float height READ height WRITE setHeight NOTIFY heightChanged ) + Q_PROPERTY( bool centerMarker READ centerMarker WRITE setCenterMarker NOTIFY + centerMarkerChanged ) + Q_PROPERTY( bool playSpaceMarker READ playSpaceMarker WRITE + setPlaySpaceMarker NOTIFY playSpaceMarkerChanged ) + Q_PROPERTY( bool forceBounds READ forceBounds WRITE setForceBounds NOTIFY + forceBoundsChanged ) -class ChaperoneTabController : public QObject { - Q_OBJECT - Q_PROPERTY(float boundsVisibility READ boundsVisibility WRITE setBoundsVisibility NOTIFY boundsVisibilityChanged) - Q_PROPERTY(float fadeDistance READ fadeDistance WRITE setFadeDistance NOTIFY fadeDistanceChanged) - Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged) - Q_PROPERTY(bool centerMarker READ centerMarker WRITE setCenterMarker NOTIFY centerMarkerChanged) - Q_PROPERTY(bool playSpaceMarker READ playSpaceMarker WRITE setPlaySpaceMarker NOTIFY playSpaceMarkerChanged) - Q_PROPERTY(bool forceBounds READ forceBounds WRITE setForceBounds NOTIFY forceBoundsChanged) + Q_PROPERTY( bool chaperoneSwitchToBeginnerEnabled READ + isChaperoneSwitchToBeginnerEnabled WRITE + setChaperoneSwitchToBeginnerEnabled NOTIFY + chaperoneSwitchToBeginnerEnabledChanged ) + Q_PROPERTY( float chaperoneSwitchToBeginnerDistance READ + chaperoneSwitchToBeginnerDistance WRITE + setChaperoneSwitchToBeginnerDistance NOTIFY + chaperoneSwitchToBeginnerDistanceChanged ) - Q_PROPERTY(bool chaperoneSwitchToBeginnerEnabled READ isChaperoneSwitchToBeginnerEnabled WRITE setChaperoneSwitchToBeginnerEnabled NOTIFY chaperoneSwitchToBeginnerEnabledChanged) - Q_PROPERTY(float chaperoneSwitchToBeginnerDistance READ chaperoneSwitchToBeginnerDistance WRITE setChaperoneSwitchToBeginnerDistance NOTIFY chaperoneSwitchToBeginnerDistanceChanged) + Q_PROPERTY( bool chaperoneHapticFeedbackEnabled READ + isChaperoneHapticFeedbackEnabled WRITE + setChaperoneHapticFeedbackEnabled NOTIFY + chaperoneHapticFeedbackEnabledChanged ) + Q_PROPERTY( float chaperoneHapticFeedbackDistance READ + chaperoneHapticFeedbackDistance WRITE + setChaperoneHapticFeedbackDistance NOTIFY + chaperoneHapticFeedbackDistanceChanged ) - Q_PROPERTY(bool chaperoneHapticFeedbackEnabled READ isChaperoneHapticFeedbackEnabled WRITE setChaperoneHapticFeedbackEnabled NOTIFY chaperoneHapticFeedbackEnabledChanged) - Q_PROPERTY(float chaperoneHapticFeedbackDistance READ chaperoneHapticFeedbackDistance WRITE setChaperoneHapticFeedbackDistance NOTIFY chaperoneHapticFeedbackDistanceChanged) + Q_PROPERTY( + bool chaperoneAlarmSoundEnabled READ isChaperoneAlarmSoundEnabled WRITE + setChaperoneAlarmSoundEnabled NOTIFY + chaperoneAlarmSoundEnabledChanged ) + Q_PROPERTY( + bool chaperoneAlarmSoundLooping READ isChaperoneAlarmSoundLooping WRITE + setChaperoneAlarmSoundLooping NOTIFY + chaperoneAlarmSoundLoopingChanged ) + Q_PROPERTY( bool chaperoneAlarmSoundAdjustVolume READ + isChaperoneAlarmSoundAdjustVolume WRITE + setChaperoneAlarmSoundAdjustVolume NOTIFY + chaperoneAlarmSoundAdjustVolumeChanged ) + Q_PROPERTY( + float chaperoneAlarmSoundDistance READ chaperoneAlarmSoundDistance WRITE + setChaperoneAlarmSoundDistance NOTIFY + chaperoneAlarmSoundDistanceChanged ) - Q_PROPERTY(bool chaperoneAlarmSoundEnabled READ isChaperoneAlarmSoundEnabled WRITE setChaperoneAlarmSoundEnabled NOTIFY chaperoneAlarmSoundEnabledChanged) - Q_PROPERTY(bool chaperoneAlarmSoundLooping READ isChaperoneAlarmSoundLooping WRITE setChaperoneAlarmSoundLooping NOTIFY chaperoneAlarmSoundLoopingChanged) - Q_PROPERTY(bool chaperoneAlarmSoundAdjustVolume READ isChaperoneAlarmSoundAdjustVolume WRITE setChaperoneAlarmSoundAdjustVolume NOTIFY chaperoneAlarmSoundAdjustVolumeChanged) - Q_PROPERTY(float chaperoneAlarmSoundDistance READ chaperoneAlarmSoundDistance WRITE setChaperoneAlarmSoundDistance NOTIFY chaperoneAlarmSoundDistanceChanged) - - Q_PROPERTY(bool chaperoneShowDashboardEnabled READ isChaperoneShowDashboardEnabled WRITE setChaperoneShowDashboardEnabled NOTIFY chaperoneShowDashboardEnabledChanged) - Q_PROPERTY(float chaperoneShowDashboardDistance READ chaperoneShowDashboardDistance WRITE setChaperoneShowDashboardDistance NOTIFY chaperoneShowDashboardDistanceChanged) + Q_PROPERTY( + bool chaperoneShowDashboardEnabled READ isChaperoneShowDashboardEnabled + WRITE setChaperoneShowDashboardEnabled NOTIFY + chaperoneShowDashboardEnabledChanged ) + Q_PROPERTY( + float chaperoneShowDashboardDistance READ chaperoneShowDashboardDistance + WRITE setChaperoneShowDashboardDistance NOTIFY + chaperoneShowDashboardDistanceChanged ) - Q_PROPERTY(bool chaperoneVelocityModifierEnabled READ isChaperoneVelocityModifierEnabled WRITE setChaperoneVelocityModifierEnabled NOTIFY chaperoneVelocityModifierEnabledChanged) - Q_PROPERTY(float chaperoneVelocityModifier READ chaperoneVelocityModifier WRITE setChaperoneVelocityModifier NOTIFY chaperoneVelocityModifierChanged) + Q_PROPERTY( bool chaperoneVelocityModifierEnabled READ + isChaperoneVelocityModifierEnabled WRITE + setChaperoneVelocityModifierEnabled NOTIFY + chaperoneVelocityModifierEnabledChanged ) + Q_PROPERTY( float chaperoneVelocityModifier READ chaperoneVelocityModifier + WRITE setChaperoneVelocityModifier NOTIFY + chaperoneVelocityModifierChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - float m_visibility = 0.6f; - float m_fadeDistance = 0.7f; - float m_fadeDistanceModified = 0.7f; - float m_height = 2.0f; - bool m_centerMarker = false; - bool m_playSpaceMarker = false; - bool m_forceBounds = false; + float m_visibility = 0.6f; + float m_fadeDistance = 0.7f; + float m_fadeDistanceModified = 0.7f; + float m_height = 2.0f; + bool m_centerMarker = false; + bool m_playSpaceMarker = false; + bool m_forceBounds = false; - bool m_enableChaperoneSwitchToBeginner = false; - float m_chaperoneSwitchToBeginnerDistance = 0.5f; - bool m_chaperoneSwitchToBeginnerActive = false; - int32_t m_chaperoneSwitchToBeginnerLastStyle = 0; + bool m_enableChaperoneSwitchToBeginner = false; + float m_chaperoneSwitchToBeginnerDistance = 0.5f; + bool m_chaperoneSwitchToBeginnerActive = false; + int32_t m_chaperoneSwitchToBeginnerLastStyle = 0; - bool m_enableChaperoneHapticFeedback = true; - float m_chaperoneHapticFeedbackDistance = 0.5f; - bool m_chaperoneHapticFeedbackActive = false; - std::thread m_chaperoneHapticFeedbackThread; + bool m_enableChaperoneHapticFeedback = true; + float m_chaperoneHapticFeedbackDistance = 0.5f; + bool m_chaperoneHapticFeedbackActive = false; + std::thread m_chaperoneHapticFeedbackThread; - bool m_enableChaperoneAlarmSound = false; - bool m_chaperoneAlarmSoundLooping = true; - bool m_chaperoneAlarmSoundAdjustVolume = false; - float m_chaperoneAlarmSoundDistance = 0.5f; - bool m_chaperoneAlarmSoundActive = false; + bool m_enableChaperoneAlarmSound = false; + bool m_chaperoneAlarmSoundLooping = true; + bool m_chaperoneAlarmSoundAdjustVolume = false; + float m_chaperoneAlarmSoundDistance = 0.5f; + bool m_chaperoneAlarmSoundActive = false; - bool m_enableChaperoneShowDashboard = false; - float m_chaperoneShowDashboardDistance = 0.5f; - bool m_chaperoneShowDashboardActive = false; + bool m_enableChaperoneShowDashboard = false; + float m_chaperoneShowDashboardDistance = 0.5f; + bool m_chaperoneShowDashboardActive = false; - bool m_enableChaperoneVelocityModifier = false; - float m_chaperoneVelocityModifier = 0.0f; - float m_chaperoneVelocityModifierCurrent = 1.0f; + bool m_enableChaperoneVelocityModifier = false; + float m_chaperoneVelocityModifier = 0.0f; + float m_chaperoneVelocityModifierCurrent = 1.0f; - unsigned settingsUpdateCounter = 0; + unsigned settingsUpdateCounter = 0; - std::vector chaperoneProfiles; + std::vector chaperoneProfiles; public: - ~ChaperoneTabController(); + ~ChaperoneTabController(); - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed, float hmdSpeed); - void handleChaperoneWarnings(float distance); + void eventLoopTick( vr::TrackedDevicePose_t* devicePoses, + float leftSpeed, + float rightSpeed, + float hmdSpeed ); + void handleChaperoneWarnings( float distance ); - float boundsVisibility() const; - float fadeDistance() const; - float height() const; - bool centerMarker() const; - bool playSpaceMarker() const; - bool forceBounds() const; + float boundsVisibility() const; + float fadeDistance() const; + float height() const; + bool centerMarker() const; + bool playSpaceMarker() const; + bool forceBounds() const; - bool isChaperoneSwitchToBeginnerEnabled() const; - float chaperoneSwitchToBeginnerDistance() const; + bool isChaperoneSwitchToBeginnerEnabled() const; + float chaperoneSwitchToBeginnerDistance() const; - bool isChaperoneHapticFeedbackEnabled() const; - float chaperoneHapticFeedbackDistance() const; + bool isChaperoneHapticFeedbackEnabled() const; + float chaperoneHapticFeedbackDistance() const; - bool isChaperoneAlarmSoundEnabled() const; - bool isChaperoneAlarmSoundLooping() const; - bool isChaperoneAlarmSoundAdjustVolume() const; - float chaperoneAlarmSoundDistance() const; + bool isChaperoneAlarmSoundEnabled() const; + bool isChaperoneAlarmSoundLooping() const; + bool isChaperoneAlarmSoundAdjustVolume() const; + float chaperoneAlarmSoundDistance() const; - bool isChaperoneShowDashboardEnabled() const; - float chaperoneShowDashboardDistance() const; + bool isChaperoneShowDashboardEnabled() const; + float chaperoneShowDashboardDistance() const; - bool isChaperoneVelocityModifierEnabled() const; - float chaperoneVelocityModifier() const; + bool isChaperoneVelocityModifierEnabled() const; + float chaperoneVelocityModifier() const; - void reloadChaperoneProfiles(); - void saveChaperoneProfiles(); + void reloadChaperoneProfiles(); + void saveChaperoneProfiles(); - Q_INVOKABLE unsigned getChaperoneProfileCount(); - Q_INVOKABLE QString getChaperoneProfileName(unsigned index); + Q_INVOKABLE unsigned getChaperoneProfileCount(); + Q_INVOKABLE QString getChaperoneProfileName( unsigned index ); - float getBoundsMaxY(); + float getBoundsMaxY(); public slots: - void setBoundsVisibility(float value, bool notify = true); - void setFadeDistance(float value, bool notify = true); - void setHeight(float value, bool notify = true); - void updateHeight(float value, bool notify = true); - void setCenterMarker(bool value, bool notify = true); - void setPlaySpaceMarker(bool value, bool notify = true); - void setForceBounds(bool value, bool notify = true); + void setBoundsVisibility( float value, bool notify = true ); + void setFadeDistance( float value, bool notify = true ); + void setHeight( float value, bool notify = true ); + void updateHeight( float value, bool notify = true ); + void setCenterMarker( bool value, bool notify = true ); + void setPlaySpaceMarker( bool value, bool notify = true ); + void setForceBounds( bool value, bool notify = true ); - void setChaperoneSwitchToBeginnerEnabled(bool value, bool notify = true); - void setChaperoneSwitchToBeginnerDistance(float value, bool notify = true); + void setChaperoneSwitchToBeginnerEnabled( bool value, bool notify = true ); + void setChaperoneSwitchToBeginnerDistance( float value, + bool notify = true ); - void setChaperoneHapticFeedbackEnabled(bool value, bool notify = true); - void setChaperoneHapticFeedbackDistance(float value, bool notify = true); + void setChaperoneHapticFeedbackEnabled( bool value, bool notify = true ); + void setChaperoneHapticFeedbackDistance( float value, bool notify = true ); - void setChaperoneAlarmSoundEnabled(bool value, bool notify = true); - void setChaperoneAlarmSoundLooping(bool value, bool notify = true); - void setChaperoneAlarmSoundAdjustVolume(bool value, bool notify = true); - void setChaperoneAlarmSoundDistance(float value, bool notify = true); + void setChaperoneAlarmSoundEnabled( bool value, bool notify = true ); + void setChaperoneAlarmSoundLooping( bool value, bool notify = true ); + void setChaperoneAlarmSoundAdjustVolume( bool value, bool notify = true ); + void setChaperoneAlarmSoundDistance( float value, bool notify = true ); - void setChaperoneShowDashboardEnabled(bool value, bool notify = true); - void setChaperoneShowDashboardDistance(float value, bool notify = true); + void setChaperoneShowDashboardEnabled( bool value, bool notify = true ); + void setChaperoneShowDashboardDistance( float value, bool notify = true ); - void setChaperoneVelocityModifierEnabled(bool value, bool notify = true); - void setChaperoneVelocityModifier(float value, bool notify = true); + void setChaperoneVelocityModifierEnabled( bool value, bool notify = true ); + void setChaperoneVelocityModifier( float value, bool notify = true ); - void flipOrientation(); - void reloadFromDisk(); + void flipOrientation(); + void reloadFromDisk(); - void addChaperoneProfile(QString name, bool includeGeometry, bool includeVisbility, bool includeFadeDistance, bool includeCenterMarker, - bool includePlaySpaceMarker, bool includeFloorBounds, bool includeBoundsColor, bool includeChaperoneStyle, bool includeForceBounds, - bool includesProximityWarningSettings); - void applyChaperoneProfile(unsigned index); - void deleteChaperoneProfile(unsigned index); + void addChaperoneProfile( QString name, + bool includeGeometry, + bool includeVisbility, + bool includeFadeDistance, + bool includeCenterMarker, + bool includePlaySpaceMarker, + bool includeFloorBounds, + bool includeBoundsColor, + bool includeChaperoneStyle, + bool includeForceBounds, + bool includesProximityWarningSettings ); + void applyChaperoneProfile( unsigned index ); + void deleteChaperoneProfile( unsigned index ); - void reset(); - - void shutdown(); + void reset(); + + void shutdown(); signals: - void boundsVisibilityChanged(float value); - void fadeDistanceChanged(float value); - void heightChanged(float value); - void centerMarkerChanged(bool value); - void playSpaceMarkerChanged(bool value); - void forceBoundsChanged(bool value); + void boundsVisibilityChanged( float value ); + void fadeDistanceChanged( float value ); + void heightChanged( float value ); + void centerMarkerChanged( bool value ); + void playSpaceMarkerChanged( bool value ); + void forceBoundsChanged( bool value ); - void chaperoneSwitchToBeginnerEnabledChanged(bool value); - void chaperoneSwitchToBeginnerDistanceChanged(float value); + void chaperoneSwitchToBeginnerEnabledChanged( bool value ); + void chaperoneSwitchToBeginnerDistanceChanged( float value ); - void chaperoneHapticFeedbackEnabledChanged(bool value); - void chaperoneHapticFeedbackDistanceChanged(float value); + void chaperoneHapticFeedbackEnabledChanged( bool value ); + void chaperoneHapticFeedbackDistanceChanged( float value ); - void chaperoneAlarmSoundEnabledChanged(bool value); - void chaperoneAlarmSoundLoopingChanged(bool value); - void chaperoneAlarmSoundAdjustVolumeChanged(bool value); - void chaperoneAlarmSoundDistanceChanged(float value); + void chaperoneAlarmSoundEnabledChanged( bool value ); + void chaperoneAlarmSoundLoopingChanged( bool value ); + void chaperoneAlarmSoundAdjustVolumeChanged( bool value ); + void chaperoneAlarmSoundDistanceChanged( float value ); - void chaperoneShowDashboardEnabledChanged(bool value); - void chaperoneShowDashboardDistanceChanged(float value); + void chaperoneShowDashboardEnabledChanged( bool value ); + void chaperoneShowDashboardDistanceChanged( float value ); - void chaperoneVelocityModifierEnabledChanged(bool value); - void chaperoneVelocityModifierChanged(float value); + void chaperoneVelocityModifierEnabledChanged( bool value ); + void chaperoneVelocityModifierChanged( float value ); - void chaperoneProfilesUpdated(); + void chaperoneProfilesUpdated(); }; } // namespace advsettings diff --git a/src/tabcontrollers/FixFloorTabController.cpp b/src/tabcontrollers/FixFloorTabController.cpp index 34d2e69..c9ff7dd 100644 --- a/src/tabcontrollers/FixFloorTabController.cpp +++ b/src/tabcontrollers/FixFloorTabController.cpp @@ -3,177 +3,234 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { +namespace advsettings +{ +void FixFloorTabController::initStage1() {} - -void FixFloorTabController::initStage1() { +void FixFloorTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } -void FixFloorTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void FixFloorTabController::eventLoopTick( + vr::TrackedDevicePose_t* devicePoses ) +{ + if ( state > 0 ) + { + if ( measurementCount == 0 ) + { + // Get Controller ids for left/right hand + auto leftId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_LeftHand ); + if ( leftId == vr::k_unTrackedDeviceIndexInvalid ) + { + statusMessage = "No left controller found."; + statusMessageTimeout = 2.0; + emit statusMessageSignal(); + emit measureEndSignal(); + state = 0; + return; + } + auto rightId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_RightHand ); + if ( rightId == vr::k_unTrackedDeviceIndexInvalid ) + { + statusMessage = "No right controller found."; + statusMessageTimeout = 2.0; + emit statusMessageSignal(); + emit measureEndSignal(); + state = 0; + return; + } + // Get poses + vr::TrackedDevicePose_t* leftPose = devicePoses + leftId; + vr::TrackedDevicePose_t* rightPose = devicePoses + rightId; + if ( !leftPose->bPoseIsValid || !leftPose->bDeviceIsConnected + || leftPose->eTrackingResult != vr::TrackingResult_Running_OK ) + { + statusMessage = "Left controller tracking problems."; + statusMessageTimeout = 2.0; + emit statusMessageSignal(); + emit measureEndSignal(); + state = 0; + return; + } + else if ( !rightPose->bPoseIsValid || !rightPose->bDeviceIsConnected + || rightPose->eTrackingResult + != vr::TrackingResult_Running_OK ) + { + statusMessage = "Right controller tracking problems."; + statusMessageTimeout = 2.0; + emit statusMessageSignal(); + emit measureEndSignal(); + state = 0; + return; + } + else + { + // The controller with the lowest y-pos is the floor fix + // reference + if ( leftPose->mDeviceToAbsoluteTracking.m[1][3] + < rightPose->mDeviceToAbsoluteTracking.m[1][3] ) + { + referenceController = leftId; + } + else + { + referenceController = rightId; + } + + auto& m = devicePoses[referenceController] + .mDeviceToAbsoluteTracking.m; + tempOffsetX = ( double ) m[0][3]; + tempOffsetY = ( double ) m[1][3]; + tempOffsetZ = ( double ) m[2][3]; + /* + | Intrinsic y-x'-z" rotation matrix: + | cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy | + | cp*sr | cp*cr |-sp | + | cy*sp*sr-cr*sy | cr*cy*sp+sr*sy | cp*cy | + + yaw = atan2(cp*sy, cp*cy) [pi, -pi], CCW + pitch = -asin(-sp) [pi/2, -pi/2] + roll = atan2(cp*sr, cp*cr) [pi, -pi], CW + */ + tempRoll = std::atan2( ( double ) m[1][0], ( double ) m[1][1] ); + measurementCount = 1; + } + } + else + { + measurementCount++; + auto& m + = devicePoses[referenceController].mDeviceToAbsoluteTracking.m; + + double rollDiff + = std::atan2( ( double ) m[1][0], ( double ) m[1][1] ) + - tempRoll; + if ( rollDiff > M_PI ) + { + rollDiff -= 2.0 * M_PI; + } + else if ( rollDiff < -M_PI ) + { + rollDiff += 2.0 * M_PI; + } + tempRoll += rollDiff / ( double ) measurementCount; + if ( tempRoll > M_PI ) + { + tempRoll -= 2.0 * M_PI; + } + else if ( tempRoll < -M_PI ) + { + tempRoll += 2.0 * M_PI; + } + + if ( measurementCount >= 25 ) + { + if ( std::abs( tempRoll ) <= M_PI_2 ) + { + floorOffsetY = tempOffsetY - controllerUpOffsetCorrection; + } + else + { + floorOffsetY = tempOffsetY - controllerDownOffsetCorrection; + } + + floorOffsetX = tempOffsetX; + floorOffsetZ = tempOffsetZ; + + LOG( INFO ) + << "Fix Floor and adjust playspace center: Floor Offset = [" + << floorOffsetX << ", " << floorOffsetY << ", " + << floorOffsetZ << "]"; + float offset[3] = { 0, 0, 0 }; + offset[1] = floorOffsetY; + if ( state == 2 ) + { + offset[0] = floorOffsetX; + offset[2] = floorOffsetZ; + } + parent->AddOffsetToUniverseCenter( + vr::TrackingUniverseStanding, offset, true ); + statusMessage + = ( state == 2 ) ? "Recentering ... Ok" : "Fixing ... OK"; + statusMessageTimeout = 1.0; + emit statusMessageSignal(); + emit measureEndSignal(); + setCanUndo( true ); + state = 0; + } + } + } } -void FixFloorTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses) { - if (state > 0) { - if (measurementCount == 0) { - // Get Controller ids for left/right hand - auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - if (leftId == vr::k_unTrackedDeviceIndexInvalid) { - statusMessage = "No left controller found."; - statusMessageTimeout = 2.0; - emit statusMessageSignal(); - emit measureEndSignal(); - state = 0; - return; - } - auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (rightId == vr::k_unTrackedDeviceIndexInvalid) { - statusMessage = "No right controller found."; - statusMessageTimeout = 2.0; - emit statusMessageSignal(); - emit measureEndSignal(); - state = 0; - return; - } - // Get poses - vr::TrackedDevicePose_t* leftPose = devicePoses + leftId; - vr::TrackedDevicePose_t* rightPose = devicePoses + rightId; - if (!leftPose->bPoseIsValid || !leftPose->bDeviceIsConnected || leftPose->eTrackingResult != vr::TrackingResult_Running_OK) { - statusMessage = "Left controller tracking problems."; - statusMessageTimeout = 2.0; - emit statusMessageSignal(); - emit measureEndSignal(); - state = 0; - return; - } else if (!rightPose->bPoseIsValid || !rightPose->bDeviceIsConnected || rightPose->eTrackingResult != vr::TrackingResult_Running_OK) { - statusMessage = "Right controller tracking problems."; - statusMessageTimeout = 2.0; - emit statusMessageSignal(); - emit measureEndSignal(); - state = 0; - return; - } else { - // The controller with the lowest y-pos is the floor fix reference - if (leftPose->mDeviceToAbsoluteTracking.m[1][3] < rightPose->mDeviceToAbsoluteTracking.m[1][3]) { - referenceController = leftId; - } else { - referenceController = rightId; - } - - auto& m = devicePoses[referenceController].mDeviceToAbsoluteTracking.m; - tempOffsetX = (double)m[0][3]; - tempOffsetY = (double)m[1][3]; - tempOffsetZ = (double)m[2][3]; - /* - | Intrinsic y-x'-z" rotation matrix: - | cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy | - | cp*sr | cp*cr |-sp | - | cy*sp*sr-cr*sy | cr*cy*sp+sr*sy | cp*cy | - - yaw = atan2(cp*sy, cp*cy) [pi, -pi], CCW - pitch = -asin(-sp) [pi/2, -pi/2] - roll = atan2(cp*sr, cp*cr) [pi, -pi], CW - */ - tempRoll = std::atan2((double)m[1][0], (double)m[1][1]); - measurementCount = 1; - } - - } else { - measurementCount++; - auto& m = devicePoses[referenceController].mDeviceToAbsoluteTracking.m; - - double rollDiff = std::atan2((double)m[1][0], (double)m[1][1]) - tempRoll; - if (rollDiff > M_PI) { - rollDiff -= 2.0 * M_PI; - } else if (rollDiff < -M_PI) { - rollDiff += 2.0 * M_PI; - } - tempRoll += rollDiff / (double)measurementCount; - if (tempRoll > M_PI) { - tempRoll -= 2.0 * M_PI; - } else if (tempRoll < -M_PI) { - tempRoll += 2.0 * M_PI; - } - - if (measurementCount >= 25) { - if (std::abs(tempRoll) <= M_PI_2) { - floorOffsetY = tempOffsetY - controllerUpOffsetCorrection; - } else { - floorOffsetY = tempOffsetY - controllerDownOffsetCorrection; - } - - floorOffsetX = tempOffsetX; - floorOffsetZ = tempOffsetZ; - - LOG(INFO) << "Fix Floor and adjust playspace center: Floor Offset = [" << floorOffsetX << ", " << floorOffsetY << ", " << floorOffsetZ << "]"; - float offset[3] = { 0, 0, 0 }; - offset[1] = floorOffsetY; - if (state == 2) { - offset[0] = floorOffsetX; - offset[2] = floorOffsetZ; - } - parent->AddOffsetToUniverseCenter(vr::TrackingUniverseStanding, offset, true); - statusMessage = (state == 2) ? "Recentering ... Ok" : "Fixing ... OK"; - statusMessageTimeout = 1.0; - emit statusMessageSignal(); - emit measureEndSignal(); - setCanUndo(true); - state = 0; - } - } - } +QString FixFloorTabController::currentStatusMessage() +{ + return statusMessage; } -QString FixFloorTabController::currentStatusMessage() { - return statusMessage; +float FixFloorTabController::currentStatusMessageTimeout() +{ + return statusMessageTimeout; } -float FixFloorTabController::currentStatusMessageTimeout() { - return statusMessageTimeout; +bool FixFloorTabController::canUndo() const +{ + return m_canUndo; } -bool FixFloorTabController::canUndo() const { - return m_canUndo; +void FixFloorTabController::setCanUndo( bool value, bool notify ) +{ + if ( m_canUndo != value ) + { + m_canUndo = value; + if ( notify ) + { + emit canUndoChanged( m_canUndo ); + } + } } -void FixFloorTabController::setCanUndo(bool value, bool notify) { - if (m_canUndo != value) { - m_canUndo = value; - if (notify) { - emit canUndoChanged(m_canUndo); - } - } +void FixFloorTabController::fixFloorClicked() +{ + statusMessage = "Fixing ..."; + statusMessageTimeout = 1.0; + emit statusMessageSignal(); + emit measureStartSignal(); + measurementCount = 0; + state = 1; } -void FixFloorTabController::fixFloorClicked() { - statusMessage = "Fixing ..."; - statusMessageTimeout = 1.0; - emit statusMessageSignal(); - emit measureStartSignal(); - measurementCount = 0; - state = 1; +void FixFloorTabController::recenterClicked() +{ + statusMessage = "Fixing ..."; + statusMessageTimeout = 1.0; + emit statusMessageSignal(); + emit measureStartSignal(); + measurementCount = 0; + state = 2; } -void FixFloorTabController::recenterClicked() { - statusMessage = "Fixing ..."; - statusMessageTimeout = 1.0; - emit statusMessageSignal(); - emit measureStartSignal(); - measurementCount = 0; - state = 2; +void FixFloorTabController::undoFixFloorClicked() +{ + parent->AddOffsetToUniverseCenter( + vr::TrackingUniverseStanding, 0, -floorOffsetX, false ); + parent->AddOffsetToUniverseCenter( + vr::TrackingUniverseStanding, 1, -floorOffsetY, false ); + parent->AddOffsetToUniverseCenter( + vr::TrackingUniverseStanding, 2, -floorOffsetZ, false ); + LOG( INFO ) << "Fix Floor: Undo Floor Offset = [" << -floorOffsetX << ", " + << -floorOffsetY << ", " << -floorOffsetZ << "]"; + floorOffsetY = 0.0f; + statusMessage = "Undo ... OK"; + statusMessageTimeout = 1.0; + emit statusMessageSignal(); + setCanUndo( false ); } -void FixFloorTabController::undoFixFloorClicked() { - parent->AddOffsetToUniverseCenter(vr::TrackingUniverseStanding, 0, -floorOffsetX, false); - parent->AddOffsetToUniverseCenter(vr::TrackingUniverseStanding, 1, -floorOffsetY, false); - parent->AddOffsetToUniverseCenter(vr::TrackingUniverseStanding, 2, -floorOffsetZ, false); - LOG(INFO) << "Fix Floor: Undo Floor Offset = [" << -floorOffsetX << ", " << -floorOffsetY << ", " << -floorOffsetZ << "]"; - floorOffsetY = 0.0f; - statusMessage = "Undo ... OK"; - statusMessageTimeout = 1.0; - emit statusMessageSignal(); - setCanUndo(false); -} - -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/FixFloorTabController.h b/src/tabcontrollers/FixFloorTabController.h index 2dec3bd..7178edf 100644 --- a/src/tabcontrollers/FixFloorTabController.h +++ b/src/tabcontrollers/FixFloorTabController.h @@ -6,60 +6,65 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; -class FixFloorTabController : public QObject { - Q_OBJECT - Q_PROPERTY(bool canUndo READ canUndo WRITE setCanUndo NOTIFY canUndoChanged) +class FixFloorTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( + bool canUndo READ canUndo WRITE setCanUndo NOTIFY canUndoChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - float controllerUpOffsetCorrection = 0.062f; // Controller touchpad facing upwards - float controllerDownOffsetCorrection = 0.006f; // Controller touchpad facing downwards - - int state = 0; // 0 .. idle, 1 .. floor fix in progress, 2 .. recenter in progress - vr::TrackedDeviceIndex_t referenceController = vr::k_unTrackedDeviceIndexInvalid; - unsigned measurementCount = 0; - double tempOffsetX = 0.0; - double tempOffsetY = 0.0; - double tempOffsetZ = 0.0; - double tempRoll = 0.0; - float floorOffsetX = 0.0f; - float floorOffsetY = 0.0f; - float floorOffsetZ = 0.0f; - QString statusMessage = ""; - float statusMessageTimeout = 0.0f; - bool m_canUndo = false; + float controllerUpOffsetCorrection + = 0.062f; // Controller touchpad facing upwards + float controllerDownOffsetCorrection + = 0.006f; // Controller touchpad facing downwards + int state + = 0; // 0 .. idle, 1 .. floor fix in progress, 2 .. recenter in progress + vr::TrackedDeviceIndex_t referenceController + = vr::k_unTrackedDeviceIndexInvalid; + unsigned measurementCount = 0; + double tempOffsetX = 0.0; + double tempOffsetY = 0.0; + double tempOffsetZ = 0.0; + double tempRoll = 0.0; + float floorOffsetX = 0.0f; + float floorOffsetY = 0.0f; + float floorOffsetZ = 0.0f; + QString statusMessage = ""; + float statusMessageTimeout = 0.0f; + bool m_canUndo = false; public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(vr::TrackedDevicePose_t* devicePoses); + void eventLoopTick( vr::TrackedDevicePose_t* devicePoses ); - Q_INVOKABLE QString currentStatusMessage(); - Q_INVOKABLE float currentStatusMessageTimeout(); + Q_INVOKABLE QString currentStatusMessage(); + Q_INVOKABLE float currentStatusMessageTimeout(); - bool canUndo() const; + bool canUndo() const; public slots: - void fixFloorClicked(); - void recenterClicked(); - void undoFixFloorClicked(); + void fixFloorClicked(); + void recenterClicked(); + void undoFixFloorClicked(); - void setCanUndo(bool value, bool notify = true); + void setCanUndo( bool value, bool notify = true ); signals: - void statusMessageSignal(); - void measureStartSignal(); - void measureEndSignal(); - void canUndoChanged(bool value); + void statusMessageSignal(); + void measureStartSignal(); + void measureEndSignal(); + void canUndoChanged( bool value ); }; } // namespace advsettings diff --git a/src/tabcontrollers/KeyboardInput.h b/src/tabcontrollers/KeyboardInput.h index 05fcfc0..f660eb3 100644 --- a/src/tabcontrollers/KeyboardInput.h +++ b/src/tabcontrollers/KeyboardInput.h @@ -4,20 +4,19 @@ #include // application namespace -namespace advsettings { - +namespace advsettings +{ class AudioTabController; class KeyboardInput { public: - virtual ~KeyboardInput() {}; + virtual ~KeyboardInput(){}; - virtual void sendKeyboardInput(QString input) = 0; + virtual void sendKeyboardInput( QString input ) = 0; virtual void sendKeyboardEnter() = 0; - virtual void sendKeyboardBackspace(int count) = 0; + virtual void sendKeyboardBackspace( int count ) = 0; virtual void sendKeyboardAltTab() = 0; }; -} - +} // namespace advsettings diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index 1dec969..e5c932c 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -2,465 +2,588 @@ #include #include "../overlaycontroller.h" -void rotateCoordinates(float coordinates[3], float angle) { - if (angle == 0) { - return; - } - float s = sin(angle); - float c = cos(angle); - float newX = coordinates[0] * c - coordinates[2] * s; - float newZ = coordinates[0] * s + coordinates[2] * c; - coordinates[0] = newX; - coordinates[2] = newZ; +void rotateCoordinates( float coordinates[3], float angle ) +{ + if ( angle == 0 ) + { + return; + } + float s = sin( angle ); + float c = cos( angle ); + float newX = coordinates[0] * c - coordinates[2] * s; + float newZ = coordinates[0] * s + coordinates[2] * c; + coordinates[0] = newX; + coordinates[2] = newZ; } // application namespace -namespace advsettings { - +namespace advsettings +{ using std::chrono::duration_cast; using std::chrono::milliseconds; typedef std::chrono::system_clock clock; -void MoveCenterTabController::initStage1() { - setTrackingUniverse(vr::VRCompositor()->GetTrackingSpace()); - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - auto value = settings->value("adjustChaperone", m_adjustChaperone); - if (value.isValid() && !value.isNull()) { - m_adjustChaperone = value.toBool(); - } - value = settings->value("moveShortcutRight", m_moveShortcutRightEnabled); - if (value.isValid() && !value.isNull()) { - m_moveShortcutRightEnabled = value.toBool(); - } - value = settings->value("moveShortcutLeft", m_moveShortcutLeftEnabled); - if (value.isValid() && !value.isNull()) { - m_moveShortcutLeftEnabled = value.toBool(); - } - value = settings->value("requireDoubleClick", m_requireDoubleClick); - if (value.isValid() && !value.isNull()) { +void MoveCenterTabController::initStage1() +{ + setTrackingUniverse( vr::VRCompositor()->GetTrackingSpace() ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + auto value = settings->value( "adjustChaperone", m_adjustChaperone ); + if ( value.isValid() && !value.isNull() ) + { + m_adjustChaperone = value.toBool(); + } + value = settings->value( "moveShortcutRight", m_moveShortcutRightEnabled ); + if ( value.isValid() && !value.isNull() ) + { + m_moveShortcutRightEnabled = value.toBool(); + } + value = settings->value( "moveShortcutLeft", m_moveShortcutLeftEnabled ); + if ( value.isValid() && !value.isNull() ) + { + m_moveShortcutLeftEnabled = value.toBool(); + } + value = settings->value( "requireDoubleClick", m_requireDoubleClick ); + if ( value.isValid() && !value.isNull() ) + { m_requireDoubleClick = value.toBool(); } - value = settings->value("lockXToggle", m_lockXToggle); - if (value.isValid() && !value.isNull()) { - m_lockXToggle = value.toBool(); - } - value = settings->value("lockYToggle", m_lockYToggle); - if (value.isValid() && !value.isNull()) { - m_lockYToggle = value.toBool(); - } - value = settings->value("lockZToggle", m_lockZToggle); - if (value.isValid() && !value.isNull()) { - m_lockZToggle = value.toBool(); - } - settings->endGroup(); + value = settings->value( "lockXToggle", m_lockXToggle ); + if ( value.isValid() && !value.isNull() ) + { + m_lockXToggle = value.toBool(); + } + value = settings->value( "lockYToggle", m_lockYToggle ); + if ( value.isValid() && !value.isNull() ) + { + m_lockYToggle = value.toBool(); + } + value = settings->value( "lockZToggle", m_lockZToggle ); + if ( value.isValid() && !value.isNull() ) + { + m_lockZToggle = value.toBool(); + } + settings->endGroup(); lastMoveButtonClick[0] = lastMoveButtonClick[1] = clock::now(); } -void MoveCenterTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void MoveCenterTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } - -int MoveCenterTabController::trackingUniverse() const { - return (int)m_trackingUniverse; +int MoveCenterTabController::trackingUniverse() const +{ + return ( int ) m_trackingUniverse; } -void MoveCenterTabController::setTrackingUniverse(int value, bool notify) { - if (m_trackingUniverse != value) { - reset(); - m_trackingUniverse = value; - if (notify) { - emit trackingUniverseChanged(m_trackingUniverse); - } - } -} - -float MoveCenterTabController::offsetX() const { - return m_offsetX; -} - -void MoveCenterTabController::setOffsetX(float value, bool notify) { - if (m_offsetX != value) { - modOffsetX(value - m_offsetX, notify); - } -} - -float MoveCenterTabController::offsetY() const { - return m_offsetY; -} - -void MoveCenterTabController::setOffsetY(float value, bool notify) { - if (m_offsetY != value) { - modOffsetY(value - m_offsetY, notify); - } -} - -float MoveCenterTabController::offsetZ() const { - return m_offsetZ; -} - -void MoveCenterTabController::setOffsetZ(float value, bool notify) { - if (m_offsetZ != value) { - modOffsetZ(value - m_offsetZ, notify); - } -} - -int MoveCenterTabController::rotation() const { - return m_rotation; -} - -void MoveCenterTabController::setRotation(int value, bool notify) { - if (m_rotation != value) { - //float angle = (value - m_rotation) * 2 * M_PI / 360.0; - //parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone); - m_rotation = value; - if (notify) { - emit rotationChanged(m_rotation); - } - } -} - -void MoveCenterTabController::applyRotation() { - if (m_rotation != m_rotationOld) { - float angle = (m_rotationOld - m_rotation) * 2 * M_PI / 360.0; - parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone); - m_rotationOld = m_rotation; - } -} - -bool MoveCenterTabController::adjustChaperone() const { - return m_adjustChaperone; -} - -void MoveCenterTabController::setAdjustChaperone(bool value, bool notify) { - if (m_adjustChaperone != value) { - m_adjustChaperone = value; - if (m_trackingUniverse == vr::TrackingUniverseStanding) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offsetdir = m_adjustChaperone ? -1.0 : 1.0; - float offset[3] = { - offsetdir * m_offsetX, - offsetdir * m_offsetY, - offsetdir * m_offsetZ - }; - rotateCoordinates(offset, angle); - - parent->AddOffsetToCollisionBounds(offset); - } - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("adjustChaperone", m_adjustChaperone); - settings->endGroup(); - settings->sync(); - if (notify) { - emit adjustChaperoneChanged(m_adjustChaperone); - } - } -} - - -bool MoveCenterTabController::moveShortcutRight() const { - return m_moveShortcutRightEnabled; -} - -void MoveCenterTabController::setMoveShortcutRight(bool value, bool notify) { - m_moveShortcutRightEnabled = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("moveShortcutRight", m_moveShortcutRightEnabled); - settings->endGroup(); - settings->sync(); - if (notify) { - emit moveShortcutRightChanged(m_moveShortcutRightEnabled); - } -} - -bool MoveCenterTabController::moveShortcutLeft() const { - return m_moveShortcutLeftEnabled; -} - -void MoveCenterTabController::setMoveShortcutLeft(bool value, bool notify) { - m_moveShortcutLeftEnabled = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("moveShortcutLeft", m_moveShortcutLeftEnabled); - settings->endGroup(); - settings->sync(); - if (notify) { - emit moveShortcutLeftChanged(m_moveShortcutLeftEnabled); - } -} - -bool MoveCenterTabController::requireDoubleClick() const { - return m_requireDoubleClick; -} - -void MoveCenterTabController::setRequireDoubleClick(bool value, bool notify) { - m_requireDoubleClick = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("requireDoubleClick", m_requireDoubleClick); - settings->endGroup(); - settings->sync(); - if (notify) { - emit requireDoubleClickChanged(m_requireDoubleClick); +void MoveCenterTabController::setTrackingUniverse( int value, bool notify ) +{ + if ( m_trackingUniverse != value ) + { + reset(); + m_trackingUniverse = value; + if ( notify ) + { + emit trackingUniverseChanged( m_trackingUniverse ); + } } } -bool MoveCenterTabController::lockXToggle() const { - return m_lockXToggle; +float MoveCenterTabController::offsetX() const +{ + return m_offsetX; } -void MoveCenterTabController::setLockX(bool value, bool notify) { - m_lockXToggle = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("lockXToggle", m_lockXToggle); - settings->endGroup(); - settings->sync(); - if (notify) { - emit requireLockXChanged(m_lockXToggle); - } +void MoveCenterTabController::setOffsetX( float value, bool notify ) +{ + if ( m_offsetX != value ) + { + modOffsetX( value - m_offsetX, notify ); + } } - -bool MoveCenterTabController::lockYToggle() const { - return m_lockYToggle; +float MoveCenterTabController::offsetY() const +{ + return m_offsetY; } -void MoveCenterTabController::setLockY(bool value, bool notify) { - m_lockYToggle = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("lockYToggle", m_lockYToggle); - settings->endGroup(); - settings->sync(); - if (notify) { - emit requireLockYChanged(m_lockYToggle); - } +void MoveCenterTabController::setOffsetY( float value, bool notify ) +{ + if ( m_offsetY != value ) + { + modOffsetY( value - m_offsetY, notify ); + } } -bool MoveCenterTabController::lockZToggle() const { - return m_lockZToggle; +float MoveCenterTabController::offsetZ() const +{ + return m_offsetZ; } -void MoveCenterTabController::setLockZ(bool value, bool notify) { - m_lockZToggle = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("playspaceSettings"); - settings->setValue("lockZToggle", m_lockZToggle); - settings->endGroup(); - settings->sync(); - if (notify) { - emit requireLockZChanged(m_lockZToggle); - } +void MoveCenterTabController::setOffsetZ( float value, bool notify ) +{ + if ( m_offsetZ != value ) + { + modOffsetZ( value - m_offsetZ, notify ); + } } - - -void MoveCenterTabController::modOffsetX(float value, bool notify) { - //TODO ? possible issue with locking position this way - if (!m_lockXToggle) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offset[3] = { value, 0, 0 }; - rotateCoordinates(offset, angle); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone); - m_offsetX += value; - if (notify) { - emit offsetXChanged(m_offsetX); - } - } +int MoveCenterTabController::rotation() const +{ + return m_rotation; } -void MoveCenterTabController::modOffsetY(float value, bool notify) { - if (!m_lockYToggle) { - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, 1, value, m_adjustChaperone); - m_offsetY += value; - if (notify) { - emit offsetYChanged(m_offsetY); - } - } +void MoveCenterTabController::setRotation( int value, bool notify ) +{ + if ( m_rotation != value ) + { + // float angle = (value - m_rotation) * 2 * M_PI / 360.0; + // parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, + // angle, m_adjustChaperone); + m_rotation = value; + if ( notify ) + { + emit rotationChanged( m_rotation ); + } + } } -void MoveCenterTabController::modOffsetZ(float value, bool notify) { - if (!m_lockZToggle) { - auto angle = m_rotation * 2 * M_PI / 360.0; - float offset[3] = { 0, 0, value }; - rotateCoordinates(offset, angle); - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone); - m_offsetZ += value; - if (notify) { - emit offsetZChanged(m_offsetZ); - } - } +void MoveCenterTabController::applyRotation() +{ + if ( m_rotation != m_rotationOld ) + { + float angle = ( m_rotationOld - m_rotation ) * 2 * M_PI / 360.0; + parent->RotateUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + angle, + m_adjustChaperone ); + m_rotationOld = m_rotation; + } } -void MoveCenterTabController::reset() { - vr::VRChaperoneSetup()->RevertWorkingCopy(); - parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, -m_rotation * 2 * M_PI / 360.0, m_adjustChaperone, false); - float offset[3] = { - -m_offsetX, - -m_offsetY, - -m_offsetZ - }; - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, offset, m_adjustChaperone, false); - vr::VRChaperoneSetup()->CommitWorkingCopy(vr::EChaperoneConfigFile_Live); - m_offsetX = 0.0f; - m_offsetY = 0.0f; - m_offsetZ = 0.0f; - m_rotation = 0; - emit offsetXChanged(m_offsetX); - emit offsetYChanged(m_offsetY); - emit offsetZChanged(m_offsetZ); - emit rotationChanged(m_rotation); +bool MoveCenterTabController::adjustChaperone() const +{ + return m_adjustChaperone; } -bool isMoveShortCutPressed(vr::ETrackedControllerRole hand) { - auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(hand); - if (handId == vr::k_unTrackedDeviceIndexInvalid || handId >= vr::k_unMaxTrackedDeviceCount) { - return false; - } +void MoveCenterTabController::setAdjustChaperone( bool value, bool notify ) +{ + if ( m_adjustChaperone != value ) + { + m_adjustChaperone = value; + if ( m_trackingUniverse == vr::TrackingUniverseStanding ) + { + auto angle = m_rotation * 2 * M_PI / 360.0; + float offsetdir = m_adjustChaperone ? -1.0 : 1.0; + float offset[3] = { offsetdir * m_offsetX, + offsetdir * m_offsetY, + offsetdir * m_offsetZ }; + rotateCoordinates( offset, angle ); - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(handId, &state, sizeof(vr::VRControllerState_t))) { - return state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu); - } - - return false; + parent->AddOffsetToCollisionBounds( offset ); + } + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "adjustChaperone", m_adjustChaperone ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit adjustChaperoneChanged( m_adjustChaperone ); + } + } } -vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() { - auto activeHand = m_activeMoveController; +bool MoveCenterTabController::moveShortcutRight() const +{ + return m_moveShortcutRightEnabled; +} - bool rightPressed = m_moveShortcutRightEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_RightHand); - bool leftPressed = m_moveShortcutLeftEnabled && isMoveShortCutPressed(vr::TrackedControllerRole_LeftHand); - bool checkDoubleClick = m_requireDoubleClick && activeHand == vr::TrackedControllerRole_Invalid; +void MoveCenterTabController::setMoveShortcutRight( bool value, bool notify ) +{ + m_moveShortcutRightEnabled = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "moveShortcutRight", m_moveShortcutRightEnabled ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit moveShortcutRightChanged( m_moveShortcutRightEnabled ); + } +} + +bool MoveCenterTabController::moveShortcutLeft() const +{ + return m_moveShortcutLeftEnabled; +} + +void MoveCenterTabController::setMoveShortcutLeft( bool value, bool notify ) +{ + m_moveShortcutLeftEnabled = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "moveShortcutLeft", m_moveShortcutLeftEnabled ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit moveShortcutLeftChanged( m_moveShortcutLeftEnabled ); + } +} + +bool MoveCenterTabController::requireDoubleClick() const +{ + return m_requireDoubleClick; +} + +void MoveCenterTabController::setRequireDoubleClick( bool value, bool notify ) +{ + m_requireDoubleClick = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "requireDoubleClick", m_requireDoubleClick ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit requireDoubleClickChanged( m_requireDoubleClick ); + } +} + +bool MoveCenterTabController::lockXToggle() const +{ + return m_lockXToggle; +} + +void MoveCenterTabController::setLockX( bool value, bool notify ) +{ + m_lockXToggle = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "lockXToggle", m_lockXToggle ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit requireLockXChanged( m_lockXToggle ); + } +} + +bool MoveCenterTabController::lockYToggle() const +{ + return m_lockYToggle; +} + +void MoveCenterTabController::setLockY( bool value, bool notify ) +{ + m_lockYToggle = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "lockYToggle", m_lockYToggle ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit requireLockYChanged( m_lockYToggle ); + } +} + +bool MoveCenterTabController::lockZToggle() const +{ + return m_lockZToggle; +} + +void MoveCenterTabController::setLockZ( bool value, bool notify ) +{ + m_lockZToggle = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "playspaceSettings" ); + settings->setValue( "lockZToggle", m_lockZToggle ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit requireLockZChanged( m_lockZToggle ); + } +} + +void MoveCenterTabController::modOffsetX( float value, bool notify ) +{ + // TODO ? possible issue with locking position this way + if ( !m_lockXToggle ) + { + auto angle = m_rotation * 2 * M_PI / 360.0; + float offset[3] = { value, 0, 0 }; + rotateCoordinates( offset, angle ); + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + offset, + m_adjustChaperone ); + m_offsetX += value; + if ( notify ) + { + emit offsetXChanged( m_offsetX ); + } + } +} + +void MoveCenterTabController::modOffsetY( float value, bool notify ) +{ + if ( !m_lockYToggle ) + { + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + 1, + value, + m_adjustChaperone ); + m_offsetY += value; + if ( notify ) + { + emit offsetYChanged( m_offsetY ); + } + } +} + +void MoveCenterTabController::modOffsetZ( float value, bool notify ) +{ + if ( !m_lockZToggle ) + { + auto angle = m_rotation * 2 * M_PI / 360.0; + float offset[3] = { 0, 0, value }; + rotateCoordinates( offset, angle ); + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + offset, + m_adjustChaperone ); + m_offsetZ += value; + if ( notify ) + { + emit offsetZChanged( m_offsetZ ); + } + } +} + +void MoveCenterTabController::reset() +{ + vr::VRChaperoneSetup()->RevertWorkingCopy(); + parent->RotateUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + -m_rotation * 2 * M_PI / 360.0, + m_adjustChaperone, + false ); + float offset[3] = { -m_offsetX, -m_offsetY, -m_offsetZ }; + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + offset, + m_adjustChaperone, + false ); + vr::VRChaperoneSetup()->CommitWorkingCopy( vr::EChaperoneConfigFile_Live ); + m_offsetX = 0.0f; + m_offsetY = 0.0f; + m_offsetZ = 0.0f; + m_rotation = 0; + emit offsetXChanged( m_offsetX ); + emit offsetYChanged( m_offsetY ); + emit offsetZChanged( m_offsetZ ); + emit rotationChanged( m_rotation ); +} + +bool isMoveShortCutPressed( vr::ETrackedControllerRole hand ) +{ + auto handId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( hand ); + if ( handId == vr::k_unTrackedDeviceIndexInvalid + || handId >= vr::k_unMaxTrackedDeviceCount ) + { + return false; + } + + vr::VRControllerState_t state; + if ( vr::VRSystem()->GetControllerState( + handId, &state, sizeof( vr::VRControllerState_t ) ) ) + { + return state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ApplicationMenu ); + } + + return false; +} + +vr::ETrackedControllerRole MoveCenterTabController::getMoveShortcutHand() +{ + auto activeHand = m_activeMoveController; + + bool rightPressed + = m_moveShortcutRightEnabled + && isMoveShortCutPressed( vr::TrackedControllerRole_RightHand ); + bool leftPressed + = m_moveShortcutLeftEnabled + && isMoveShortCutPressed( vr::TrackedControllerRole_LeftHand ); + bool checkDoubleClick = m_requireDoubleClick + && activeHand == vr::TrackedControllerRole_Invalid; auto now = clock::now(); - // if we start pressing the shortcut on a controller we set the active one to it - if (rightPressed && !m_moveShortcutRightPressed) { - auto elapsed = duration_cast(now - lastMoveButtonClick[0]).count(); - if (!checkDoubleClick || elapsed < 250) { + // if we start pressing the shortcut on a controller we set the active one + // to it + if ( rightPressed && !m_moveShortcutRightPressed ) + { + auto elapsed + = duration_cast( now - lastMoveButtonClick[0] ) + .count(); + if ( !checkDoubleClick || elapsed < 250 ) + { activeHand = vr::TrackedControllerRole_RightHand; } lastMoveButtonClick[0] = now; - } - if (leftPressed && !m_moveShortcutLeftPressed) { - auto elapsed = duration_cast(now - lastMoveButtonClick[1]).count(); - if (!checkDoubleClick || elapsed < 250) { + } + if ( leftPressed && !m_moveShortcutLeftPressed ) + { + auto elapsed + = duration_cast( now - lastMoveButtonClick[1] ) + .count(); + if ( !checkDoubleClick || elapsed < 250 ) + { activeHand = vr::TrackedControllerRole_LeftHand; } lastMoveButtonClick[1] = now; - } + } - // if we let down of a shortcut we set the active hand to any remaining pressed down hand - if (!rightPressed && m_moveShortcutRightPressed) { - activeHand = leftPressed ? vr::TrackedControllerRole_LeftHand : vr::TrackedControllerRole_Invalid; - } - if (!leftPressed && m_moveShortcutLeftPressed) { - activeHand = rightPressed ? vr::TrackedControllerRole_RightHand : vr::TrackedControllerRole_Invalid; - } + // if we let down of a shortcut we set the active hand to any remaining + // pressed down hand + if ( !rightPressed && m_moveShortcutRightPressed ) + { + activeHand = leftPressed ? vr::TrackedControllerRole_LeftHand + : vr::TrackedControllerRole_Invalid; + } + if ( !leftPressed && m_moveShortcutLeftPressed ) + { + activeHand = rightPressed ? vr::TrackedControllerRole_RightHand + : vr::TrackedControllerRole_Invalid; + } - if (!leftPressed && !rightPressed) { - activeHand = vr::TrackedControllerRole_Invalid; - if (m_activeMoveController != vr::TrackedControllerRole_Invalid) { + if ( !leftPressed && !rightPressed ) + { + activeHand = vr::TrackedControllerRole_Invalid; + if ( m_activeMoveController != vr::TrackedControllerRole_Invalid ) + { // grace period while switching hands lastMoveButtonClick[0] = lastMoveButtonClick[1] = now; } - } - - m_activeMoveController = activeHand; - m_moveShortcutRightPressed = rightPressed; - m_moveShortcutLeftPressed = leftPressed; - - return activeHand; + } + + m_activeMoveController = activeHand; + m_moveShortcutRightPressed = rightPressed; + m_moveShortcutLeftPressed = leftPressed; + + return activeHand; } - -void MoveCenterTabController::eventLoopTick(vr::ETrackingUniverseOrigin universe, vr::TrackedDevicePose_t* devicePoses) { - if (settingsUpdateCounter >= 50) { - setTrackingUniverse((int)universe); - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - auto oldMoveHand = m_activeMoveController; - auto newMoveHand = getMoveShortcutHand(); - if (newMoveHand == vr::TrackedControllerRole_Invalid) { - emit offsetXChanged(m_offsetX); - emit offsetYChanged(m_offsetY); - emit offsetZChanged(m_offsetZ); - return; - } - auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(newMoveHand); - if (newMoveHand == vr::TrackedControllerRole_Invalid || handId == vr::k_unTrackedDeviceIndexInvalid || handId >= vr::k_unMaxTrackedDeviceCount) { - if (oldMoveHand != vr::TrackedControllerRole_Invalid) { - emit offsetXChanged(m_offsetX); - emit offsetYChanged(m_offsetY); - emit offsetZChanged(m_offsetZ); - } - return; - } - vr::TrackedDevicePose_t* pose = devicePoses + handId; - if (!pose->bPoseIsValid || !pose->bDeviceIsConnected || pose->eTrackingResult != vr::TrackingResult_Running_OK) { - return; - } - float relativeControllerPosition[] = { - pose->mDeviceToAbsoluteTracking.m[0][3], - pose->mDeviceToAbsoluteTracking.m[1][3], - pose->mDeviceToAbsoluteTracking.m[2][3] - }; +void MoveCenterTabController::eventLoopTick( + vr::ETrackingUniverseOrigin universe, + vr::TrackedDevicePose_t* devicePoses ) +{ + if ( settingsUpdateCounter >= 50 ) + { + setTrackingUniverse( ( int ) universe ); + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + auto oldMoveHand = m_activeMoveController; + auto newMoveHand = getMoveShortcutHand(); + if ( newMoveHand == vr::TrackedControllerRole_Invalid ) + { + emit offsetXChanged( m_offsetX ); + emit offsetYChanged( m_offsetY ); + emit offsetZChanged( m_offsetZ ); + return; + } + auto handId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + newMoveHand ); + if ( newMoveHand == vr::TrackedControllerRole_Invalid + || handId == vr::k_unTrackedDeviceIndexInvalid + || handId >= vr::k_unMaxTrackedDeviceCount ) + { + if ( oldMoveHand != vr::TrackedControllerRole_Invalid ) + { + emit offsetXChanged( m_offsetX ); + emit offsetYChanged( m_offsetY ); + emit offsetZChanged( m_offsetZ ); + } + return; + } + vr::TrackedDevicePose_t* pose = devicePoses + handId; + if ( !pose->bPoseIsValid || !pose->bDeviceIsConnected + || pose->eTrackingResult != vr::TrackingResult_Running_OK ) + { + return; + } + float relativeControllerPosition[] + = { pose->mDeviceToAbsoluteTracking.m[0][3], + pose->mDeviceToAbsoluteTracking.m[1][3], + pose->mDeviceToAbsoluteTracking.m[2][3] }; auto angle = m_rotation * 2 * M_PI / 360.0; - rotateCoordinates(relativeControllerPosition, -angle); - float absoluteControllerPosition[] = { - relativeControllerPosition[0] + m_offsetX, - relativeControllerPosition[1] + m_offsetY, - relativeControllerPosition[2] + m_offsetZ, + rotateCoordinates( relativeControllerPosition, -angle ); + float absoluteControllerPosition[] = { + relativeControllerPosition[0] + m_offsetX, + relativeControllerPosition[1] + m_offsetY, + relativeControllerPosition[2] + m_offsetZ, }; - if (oldMoveHand == newMoveHand) { + if ( oldMoveHand == newMoveHand ) + { + float diff[3] = { + absoluteControllerPosition[0] - m_lastControllerPosition[0], + absoluteControllerPosition[1] - m_lastControllerPosition[1], + absoluteControllerPosition[2] - m_lastControllerPosition[2], + }; - float diff[3] = { - absoluteControllerPosition[0] - m_lastControllerPosition[0], - absoluteControllerPosition[1] - m_lastControllerPosition[1], - absoluteControllerPosition[2] - m_lastControllerPosition[2], - }; + // offset is un-rotated coordinates - // offset is un-rotated coordinates + // prevents UI from updating if axis movement is locked + if ( !m_lockXToggle ) + { + m_offsetX += diff[0]; + } + if ( !m_lockYToggle ) + { + m_offsetY += diff[1]; + } + if ( !m_lockZToggle ) + { + m_offsetZ += diff[2]; + } - //prevents UI from updating if axis movement is locked - if (!m_lockXToggle) { - m_offsetX += diff[0]; - } - if (!m_lockYToggle) { - m_offsetY += diff[1]; - } - if (!m_lockZToggle) { - m_offsetZ += diff[2]; - } + rotateCoordinates( diff, angle ); + // If locked removes movement + if ( m_lockXToggle ) + { + diff[0] = 0; + } + if ( m_lockYToggle ) + { + diff[1] = 0; + } + if ( m_lockZToggle ) + { + diff[2] = 0; + } - - - rotateCoordinates(diff, angle); - //If locked removes movement - if (m_lockXToggle) { - diff[0] = 0; - } - if (m_lockYToggle) { - diff[1] = 0; - } - if (m_lockZToggle) { - diff[2] = 0; - } - - parent->AddOffsetToUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, diff, m_adjustChaperone); + parent->AddOffsetToUniverseCenter( + ( vr::TrackingUniverseOrigin ) m_trackingUniverse, + diff, + m_adjustChaperone ); } - m_lastControllerPosition[0] = absoluteControllerPosition[0]; - m_lastControllerPosition[1] = absoluteControllerPosition[1]; - m_lastControllerPosition[2] = absoluteControllerPosition[2]; - } + m_lastControllerPosition[0] = absoluteControllerPosition[0]; + m_lastControllerPosition[1] = absoluteControllerPosition[1]; + m_lastControllerPosition[2] = absoluteControllerPosition[2]; + } } -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 0768e51..75af55d 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -7,112 +7,125 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; - -class MoveCenterTabController : public QObject { - Q_OBJECT - Q_PROPERTY(int trackingUniverse READ trackingUniverse WRITE setTrackingUniverse NOTIFY trackingUniverseChanged) - Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged) - Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged) - Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged) - Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged ) - Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) - Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) - Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) - Q_PROPERTY(bool requireDoubleClick READ requireDoubleClick WRITE setRequireDoubleClick NOTIFY requireDoubleClickChanged) - Q_PROPERTY(bool lockXToggle READ lockXToggle WRITE setLockX NOTIFY requireLockXChanged) - Q_PROPERTY(bool lockYToggle READ lockYToggle WRITE setLockY NOTIFY requireLockYChanged) - Q_PROPERTY(bool lockZToggle READ lockZToggle WRITE setLockZ NOTIFY requireLockZChanged) +class MoveCenterTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( int trackingUniverse READ trackingUniverse WRITE + setTrackingUniverse NOTIFY trackingUniverseChanged ) + Q_PROPERTY( + float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged ) + Q_PROPERTY( + float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged ) + Q_PROPERTY( + float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged ) + Q_PROPERTY( + int rotation READ rotation WRITE setRotation NOTIFY rotationChanged ) + Q_PROPERTY( bool adjustChaperone READ adjustChaperone WRITE + setAdjustChaperone NOTIFY adjustChaperoneChanged ) + Q_PROPERTY( bool moveShortcutRight READ moveShortcutRight WRITE + setMoveShortcutRight NOTIFY moveShortcutRightChanged ) + Q_PROPERTY( bool moveShortcutLeft READ moveShortcutLeft WRITE + setMoveShortcutLeft NOTIFY moveShortcutLeftChanged ) + Q_PROPERTY( bool requireDoubleClick READ requireDoubleClick WRITE + setRequireDoubleClick NOTIFY requireDoubleClickChanged ) + Q_PROPERTY( bool lockXToggle READ lockXToggle WRITE setLockX NOTIFY + requireLockXChanged ) + Q_PROPERTY( bool lockYToggle READ lockYToggle WRITE setLockY NOTIFY + requireLockYChanged ) + Q_PROPERTY( bool lockZToggle READ lockZToggle WRITE setLockZ NOTIFY + requireLockZChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - int m_trackingUniverse = (int)vr::TrackingUniverseStanding; - float m_offsetX = 0.0f; - float m_offsetY = 0.0f; + int m_trackingUniverse = ( int ) vr::TrackingUniverseStanding; + float m_offsetX = 0.0f; + float m_offsetY = 0.0f; float m_offsetZ = 0.0f; - int m_rotation = 0; - int m_rotationOld = 0; - bool m_adjustChaperone = true; - bool m_moveShortcutRightPressed = false; - bool m_moveShortcutLeftPressed = false; - vr::ETrackedControllerRole m_activeMoveController; + int m_rotation = 0; + int m_rotationOld = 0; + bool m_adjustChaperone = true; + bool m_moveShortcutRightPressed = false; + bool m_moveShortcutLeftPressed = false; + vr::ETrackedControllerRole m_activeMoveController; float m_lastControllerPosition[3]; - bool m_moveShortcutRightEnabled = false; - bool m_moveShortcutLeftEnabled = false; + bool m_moveShortcutRightEnabled = false; + bool m_moveShortcutLeftEnabled = false; bool m_requireDoubleClick = false; - bool m_lockXToggle = false; - bool m_lockYToggle = false; - bool m_lockZToggle = false; + bool m_lockXToggle = false; + bool m_lockYToggle = false; + bool m_lockZToggle = false; std::chrono::system_clock::time_point lastMoveButtonClick[2]; - unsigned settingsUpdateCounter = 0; + unsigned settingsUpdateCounter = 0; - vr::ETrackedControllerRole getMoveShortcutHand(); + vr::ETrackedControllerRole getMoveShortcutHand(); public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(vr::ETrackingUniverseOrigin universe, vr::TrackedDevicePose_t* devicePoses); + void eventLoopTick( vr::ETrackingUniverseOrigin universe, + vr::TrackedDevicePose_t* devicePoses ); - float offsetX() const; - float offsetY() const; - float offsetZ() const; - int rotation() const; - bool adjustChaperone() const; - bool moveShortcutRight() const; - bool moveShortcutLeft() const; + float offsetX() const; + float offsetY() const; + float offsetZ() const; + int rotation() const; + bool adjustChaperone() const; + bool moveShortcutRight() const; + bool moveShortcutLeft() const; bool requireDoubleClick() const; - bool lockXToggle() const; - bool lockYToggle() const; - bool lockZToggle() const; + bool lockXToggle() const; + bool lockYToggle() const; + bool lockZToggle() const; public slots: - int trackingUniverse() const; - void setTrackingUniverse(int value, bool notify = true); + int trackingUniverse() const; + void setTrackingUniverse( int value, bool notify = true ); - void setOffsetX(float value, bool notify = true); - void setOffsetY(float value, bool notify = true); - void setOffsetZ(float value, bool notify = true); + void setOffsetX( float value, bool notify = true ); + void setOffsetY( float value, bool notify = true ); + void setOffsetZ( float value, bool notify = true ); - void setRotation(int value , bool notify = true); + void setRotation( int value, bool notify = true ); - void setAdjustChaperone(bool value, bool notify = true); + void setAdjustChaperone( bool value, bool notify = true ); - void setMoveShortcutRight(bool value, bool notify = true); - void setMoveShortcutLeft(bool value, bool notify = true); - void setRequireDoubleClick(bool value, bool notify = true); + void setMoveShortcutRight( bool value, bool notify = true ); + void setMoveShortcutLeft( bool value, bool notify = true ); + void setRequireDoubleClick( bool value, bool notify = true ); - void modOffsetX(float value, bool notify = true); - void modOffsetY(float value, bool notify = true); - void modOffsetZ(float value, bool notify = true); + void modOffsetX( float value, bool notify = true ); + void modOffsetY( float value, bool notify = true ); + void modOffsetZ( float value, bool notify = true ); - void setLockX(bool value, bool notify = true); - void setLockY(bool value, bool notify = true); - void setLockZ(bool value, bool notify = true); + void setLockX( bool value, bool notify = true ); + void setLockY( bool value, bool notify = true ); + void setLockZ( bool value, bool notify = true ); - void applyRotation(); - void reset(); + void applyRotation(); + void reset(); signals: - void trackingUniverseChanged(int value); - void offsetXChanged(float value); - void offsetYChanged(float value); - void offsetZChanged(float value); - void rotationChanged(int value); - void adjustChaperoneChanged(bool value); - void moveShortcutRightChanged(bool value); - void moveShortcutLeftChanged(bool value); - void requireDoubleClickChanged(bool value); - void requireLockXChanged(bool value); - void requireLockYChanged(bool value); - void requireLockZChanged(bool value); + void trackingUniverseChanged( int value ); + void offsetXChanged( float value ); + void offsetYChanged( float value ); + void offsetZChanged( float value ); + void rotationChanged( int value ); + void adjustChaperoneChanged( bool value ); + void moveShortcutRightChanged( bool value ); + void moveShortcutLeftChanged( bool value ); + void requireDoubleClickChanged( bool value ); + void requireLockXChanged( bool value ); + void requireLockYChanged( bool value ); + void requireLockZChanged( bool value ); }; } // namespace advsettings diff --git a/src/tabcontrollers/PttController.cpp b/src/tabcontrollers/PttController.cpp index 2fa0a30..a904e4e 100644 --- a/src/tabcontrollers/PttController.cpp +++ b/src/tabcontrollers/PttController.cpp @@ -4,488 +4,823 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { - - bool PttController::pttEnabled() const { +namespace advsettings +{ +bool PttController::pttEnabled() const +{ return m_pttEnabled; - } +} - - bool PttController::pttActive() const { +bool PttController::pttActive() const +{ return m_pttActive; - } +} - - bool PttController::pttShowNotification() const { +bool PttController::pttShowNotification() const +{ return m_pttShowNotification; - } +} - - bool PttController::pttLeftControllerEnabled() const { +bool PttController::pttLeftControllerEnabled() const +{ return m_pttLeftControllerEnabled; - } +} - - bool PttController::pttRightControllerEnabled() const { +bool PttController::pttRightControllerEnabled() const +{ return m_pttRightControllerEnabled; - } +} - void PttController::setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas) { - std::lock_guard lock(eventLoopMutex); - if (controller < 2) { - uint64_t buttonMask = 0; - for (auto b : buttons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - m_pttControllerConfigs[controller].digitalButtons = buttons; - m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; - m_pttControllerConfigs[controller].triggerMode = triggerMode; - m_pttControllerConfigs[controller].touchpadMode = padMode; - m_pttControllerConfigs[controller].touchpadAreas = padAreas; - savePttConfig(); +void PttController::setPttControllerConfig( unsigned controller, + QVariantList buttons, + unsigned triggerMode, + unsigned padMode, + unsigned padAreas ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( controller < 2 ) + { + uint64_t buttonMask = 0; + for ( auto b : buttons ) + { + buttonMask |= vr::ButtonMaskFromId( ( vr::EVRButtonId ) b.toInt() ); + } + m_pttControllerConfigs[controller].digitalButtons = buttons; + m_pttControllerConfigs[controller].digitalButtonMask = buttonMask; + m_pttControllerConfigs[controller].triggerMode = triggerMode; + m_pttControllerConfigs[controller].touchpadMode = padMode; + m_pttControllerConfigs[controller].touchpadAreas = padAreas; + savePttConfig(); } - } +} - void PttController::reloadPttProfiles() { +void PttController::reloadPttProfiles() +{ pttProfiles.clear(); auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - auto profileCount = settings->beginReadArray("pttProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - pttProfiles.emplace_back(); - auto& entry = pttProfiles[i]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.showNotification = settings->value("showNotification", true).toBool(); - entry.leftControllerEnabled = settings->value("leftControllerEnabled", false).toBool(); - entry.rightControllerEnabled = settings->value("rightControllerEnabled", false).toBool(); - entry.controllerConfigs[0].digitalButtons = settings->value("digitalButtons_0").toList(); - uint64_t buttonMask = 0; - for (auto b : entry.controllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - entry.controllerConfigs[0].digitalButtonMask = buttonMask; - entry.controllerConfigs[0].triggerMode = settings->value("triggerMode_0", 0).toUInt(); - entry.controllerConfigs[0].touchpadMode = settings->value("touchpadMode_0", 0).toUInt(); - entry.controllerConfigs[0].touchpadAreas = settings->value("touchPadAreas_0", 0).toUInt(); - entry.controllerConfigs[1].digitalButtons = settings->value("digitalButtons_1").toList(); - buttonMask = 0; - for (auto b : entry.controllerConfigs[1].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); - } - entry.controllerConfigs[1].digitalButtonMask = buttonMask; - entry.controllerConfigs[1].triggerMode = settings->value("triggerMode_1", 0).toUInt(); - entry.controllerConfigs[1].touchpadMode = settings->value("touchpadMode_1", 0).toUInt(); - entry.controllerConfigs[1].touchpadAreas = settings->value("touchPadAreas_1", 0).toUInt(); + settings->beginGroup( getSettingsName() ); + auto profileCount = settings->beginReadArray( "pttProfiles" ); + for ( int i = 0; i < profileCount; i++ ) + { + settings->setArrayIndex( i ); + pttProfiles.emplace_back(); + auto& entry = pttProfiles[i]; + entry.profileName + = settings->value( "profileName" ).toString().toStdString(); + entry.showNotification + = settings->value( "showNotification", true ).toBool(); + entry.leftControllerEnabled + = settings->value( "leftControllerEnabled", false ).toBool(); + entry.rightControllerEnabled + = settings->value( "rightControllerEnabled", false ).toBool(); + entry.controllerConfigs[0].digitalButtons + = settings->value( "digitalButtons_0" ).toList(); + uint64_t buttonMask = 0; + for ( auto b : entry.controllerConfigs[0].digitalButtons ) + { + buttonMask |= vr::ButtonMaskFromId( ( vr::EVRButtonId ) b.toInt() ); + } + entry.controllerConfigs[0].digitalButtonMask = buttonMask; + entry.controllerConfigs[0].triggerMode + = settings->value( "triggerMode_0", 0 ).toUInt(); + entry.controllerConfigs[0].touchpadMode + = settings->value( "touchpadMode_0", 0 ).toUInt(); + entry.controllerConfigs[0].touchpadAreas + = settings->value( "touchPadAreas_0", 0 ).toUInt(); + entry.controllerConfigs[1].digitalButtons + = settings->value( "digitalButtons_1" ).toList(); + buttonMask = 0; + for ( auto b : entry.controllerConfigs[1].digitalButtons ) + { + buttonMask |= vr::ButtonMaskFromId( ( vr::EVRButtonId ) b.toInt() ); + } + entry.controllerConfigs[1].digitalButtonMask = buttonMask; + entry.controllerConfigs[1].triggerMode + = settings->value( "triggerMode_1", 0 ).toUInt(); + entry.controllerConfigs[1].touchpadMode + = settings->value( "touchpadMode_1", 0 ).toUInt(); + entry.controllerConfigs[1].touchpadAreas + = settings->value( "touchPadAreas_1", 0 ).toUInt(); } settings->endArray(); settings->endGroup(); - } +} - void PttController::savePttProfiles() { +void PttController::savePttProfiles() +{ auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - settings->beginWriteArray("pttProfiles"); + settings->beginGroup( getSettingsName() ); + settings->beginWriteArray( "pttProfiles" ); unsigned i = 0; - for (auto& p : pttProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("showNotification", p.showNotification); - settings->setValue("leftControllerEnabled", p.leftControllerEnabled); - settings->setValue("rightControllerEnabled", p.rightControllerEnabled); - settings->setValue("digitalButtons_0", p.controllerConfigs[0].digitalButtons); - settings->setValue("triggerMode_0", p.controllerConfigs[0].triggerMode); - settings->setValue("touchpadMode_0", p.controllerConfigs[0].touchpadMode); - settings->setValue("touchPadAreas_0", p.controllerConfigs[0].touchpadAreas); - settings->setValue("digitalButtons_1", p.controllerConfigs[1].digitalButtons); - settings->setValue("triggerMode_1", p.controllerConfigs[1].triggerMode); - settings->setValue("touchpadMode_1", p.controllerConfigs[1].touchpadMode); - settings->setValue("touchPadAreas_1", p.controllerConfigs[1].touchpadAreas); - i++; + for ( auto& p : pttProfiles ) + { + settings->setArrayIndex( i ); + settings->setValue( "profileName", + QString::fromStdString( p.profileName ) ); + settings->setValue( "showNotification", p.showNotification ); + settings->setValue( "leftControllerEnabled", p.leftControllerEnabled ); + settings->setValue( "rightControllerEnabled", + p.rightControllerEnabled ); + settings->setValue( "digitalButtons_0", + p.controllerConfigs[0].digitalButtons ); + settings->setValue( "triggerMode_0", + p.controllerConfigs[0].triggerMode ); + settings->setValue( "touchpadMode_0", + p.controllerConfigs[0].touchpadMode ); + settings->setValue( "touchPadAreas_0", + p.controllerConfigs[0].touchpadAreas ); + settings->setValue( "digitalButtons_1", + p.controllerConfigs[1].digitalButtons ); + settings->setValue( "triggerMode_1", + p.controllerConfigs[1].triggerMode ); + settings->setValue( "touchpadMode_1", + p.controllerConfigs[1].touchpadMode ); + settings->setValue( "touchPadAreas_1", + p.controllerConfigs[1].touchpadAreas ); + i++; } settings->endArray(); settings->endGroup(); - } +} - - void PttController::reloadPttConfig() { - std::lock_guard lock(eventLoopMutex); +void PttController::reloadPttConfig() +{ + std::lock_guard lock( eventLoopMutex ); auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - setPttEnabled(settings->value("pttEnabled", false).toBool(), true, false); - setPttLeftControllerEnabled(settings->value("pttLeftControllerEnabled", false).toBool(), true, false); - setPttRightControllerEnabled(settings->value("pttRightControllerEnabled", false).toBool(), true, false); - setPttShowNotification(settings->value("pttShowNotification", true).toBool(), true, false); - m_pttControllerConfigs[0].digitalButtons = settings->value("pttDigitalButtons_0").toList(); + settings->beginGroup( getSettingsName() ); + setPttEnabled( + settings->value( "pttEnabled", false ).toBool(), true, false ); + setPttLeftControllerEnabled( + settings->value( "pttLeftControllerEnabled", false ).toBool(), + true, + false ); + setPttRightControllerEnabled( + settings->value( "pttRightControllerEnabled", false ).toBool(), + true, + false ); + setPttShowNotification( + settings->value( "pttShowNotification", true ).toBool(), true, false ); + m_pttControllerConfigs[0].digitalButtons + = settings->value( "pttDigitalButtons_0" ).toList(); uint64_t buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + for ( auto b : m_pttControllerConfigs[0].digitalButtons ) + { + buttonMask |= vr::ButtonMaskFromId( ( vr::EVRButtonId ) b.toInt() ); } m_pttControllerConfigs[0].digitalButtonMask = buttonMask; - m_pttControllerConfigs[0].triggerMode = settings->value("pttTriggerMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadMode = settings->value("pttTouchpadMode_0", 0).toUInt(); - m_pttControllerConfigs[0].touchpadAreas = settings->value("pttTouchPadAreas_0", 0).toUInt(); - m_pttControllerConfigs[1].digitalButtons = settings->value("pttDigitalButtons_1").toList(); + m_pttControllerConfigs[0].triggerMode + = settings->value( "pttTriggerMode_0", 0 ).toUInt(); + m_pttControllerConfigs[0].touchpadMode + = settings->value( "pttTouchpadMode_0", 0 ).toUInt(); + m_pttControllerConfigs[0].touchpadAreas + = settings->value( "pttTouchPadAreas_0", 0 ).toUInt(); + m_pttControllerConfigs[1].digitalButtons + = settings->value( "pttDigitalButtons_1" ).toList(); buttonMask = 0; - for (auto b : m_pttControllerConfigs[0].digitalButtons) { - buttonMask |= vr::ButtonMaskFromId((vr::EVRButtonId)b.toInt()); + for ( auto b : m_pttControllerConfigs[0].digitalButtons ) + { + buttonMask |= vr::ButtonMaskFromId( ( vr::EVRButtonId ) b.toInt() ); } m_pttControllerConfigs[1].digitalButtonMask = buttonMask; - m_pttControllerConfigs[1].triggerMode = settings->value("pttTriggerMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadMode = settings->value("pttTouchpadMode_1", 0).toUInt(); - m_pttControllerConfigs[1].touchpadAreas = settings->value("pttTouchPadAreas_1", 0).toUInt(); + m_pttControllerConfigs[1].triggerMode + = settings->value( "pttTriggerMode_1", 0 ).toUInt(); + m_pttControllerConfigs[1].touchpadMode + = settings->value( "pttTouchpadMode_1", 0 ).toUInt(); + m_pttControllerConfigs[1].touchpadAreas + = settings->value( "pttTouchPadAreas_1", 0 ).toUInt(); settings->endGroup(); - } +} - void PttController::savePttConfig() { +void PttController::savePttConfig() +{ auto settings = OverlayController::appSettings(); - settings->beginGroup(getSettingsName()); - settings->setValue("pttEnabled", pttEnabled()); - settings->setValue("pttLeftControllerEnabled", pttLeftControllerEnabled()); - settings->setValue("pttRightControllerEnabled", pttRightControllerEnabled()); - settings->setValue("pttShowNotification", pttShowNotification()); - settings->setValue("pttDigitalButtons_0", m_pttControllerConfigs[0].digitalButtons); - settings->setValue("pttTriggerMode_0", m_pttControllerConfigs[0].triggerMode); - settings->setValue("pttTouchpadMode_0", m_pttControllerConfigs[0].touchpadMode); - settings->setValue("pttTouchPadAreas_0", m_pttControllerConfigs[0].touchpadAreas); - settings->setValue("pttDigitalButtons_1", m_pttControllerConfigs[1].digitalButtons); - settings->setValue("pttTriggerMode_1", m_pttControllerConfigs[1].triggerMode); - settings->setValue("pttTouchpadMode_1", m_pttControllerConfigs[1].touchpadMode); - settings->setValue("pttTouchPadAreas_1", m_pttControllerConfigs[1].touchpadAreas); + settings->beginGroup( getSettingsName() ); + settings->setValue( "pttEnabled", pttEnabled() ); + settings->setValue( "pttLeftControllerEnabled", + pttLeftControllerEnabled() ); + settings->setValue( "pttRightControllerEnabled", + pttRightControllerEnabled() ); + settings->setValue( "pttShowNotification", pttShowNotification() ); + settings->setValue( "pttDigitalButtons_0", + m_pttControllerConfigs[0].digitalButtons ); + settings->setValue( "pttTriggerMode_0", + m_pttControllerConfigs[0].triggerMode ); + settings->setValue( "pttTouchpadMode_0", + m_pttControllerConfigs[0].touchpadMode ); + settings->setValue( "pttTouchPadAreas_0", + m_pttControllerConfigs[0].touchpadAreas ); + settings->setValue( "pttDigitalButtons_1", + m_pttControllerConfigs[1].digitalButtons ); + settings->setValue( "pttTriggerMode_1", + m_pttControllerConfigs[1].triggerMode ); + settings->setValue( "pttTouchpadMode_1", + m_pttControllerConfigs[1].touchpadMode ); + settings->setValue( "pttTouchPadAreas_1", + m_pttControllerConfigs[1].touchpadAreas ); settings->endGroup(); - } +} - void PttController::checkPttStatus() { - static auto handleControllerState = [](const vr::VRControllerState_t& state, PttControllerConfig* config) -> bool { - if (state.ulButtonPressed & config->digitalButtonMask) { - return true; - } - if (config->triggerMode) { - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger) - || state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) { - return true; - } - } - if (config->touchpadMode) { - if (((config->touchpadMode & 1) && (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad))) - || ((config->touchpadMode & 2) && (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)))) { - if (config->touchpadAreas == (PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + PAD_AREA_BOTTOM)) { +void PttController::checkPttStatus() +{ + static auto handleControllerState + = []( const vr::VRControllerState_t& state, + PttControllerConfig* config ) -> bool { + if ( state.ulButtonPressed & config->digitalButtonMask ) + { return true; - } else { - float x = state.rAxis[0].x; - float y = state.rAxis[0].y; - if (std::abs(x) >= 0.2 || std::abs(y) >= 0.2) { // deadzone in the middle - if (x < 0 && std::abs(y) < -x && (config->touchpadAreas & PAD_AREA_LEFT)) { + } + if ( config->triggerMode ) + { + if ( state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_SteamVR_Trigger ) + || state.ulButtonTouched + & vr::ButtonMaskFromId( + vr::k_EButton_SteamVR_Trigger ) ) + { return true; - } else if (y > 0 && std::abs(x) < y && (config->touchpadAreas & PAD_AREA_TOP)) { - return true; - } else if (x > 0 && std::abs(y) < x && (config->touchpadAreas & PAD_AREA_RIGHT)) { - return true; - } else if (y < 0 && std::abs(x) < -y && (config->touchpadAreas & PAD_AREA_BOTTOM)) { - return true; - } } - } } - } - return false; + if ( config->touchpadMode ) + { + if ( ( ( config->touchpadMode & 1 ) + && ( state.ulButtonTouched + & vr::ButtonMaskFromId( + vr::k_EButton_SteamVR_Touchpad ) ) ) + || ( ( config->touchpadMode & 2 ) + && ( state.ulButtonPressed + & vr::ButtonMaskFromId( + vr::k_EButton_SteamVR_Touchpad ) ) ) ) + { + if ( config->touchpadAreas + == ( PAD_AREA_LEFT + PAD_AREA_TOP + PAD_AREA_RIGHT + + PAD_AREA_BOTTOM ) ) + { + return true; + } + else + { + float x = state.rAxis[0].x; + float y = state.rAxis[0].y; + if ( std::abs( x ) >= 0.2 || std::abs( y ) >= 0.2 ) + { // deadzone in the middle + if ( x < 0 && std::abs( y ) < -x + && ( config->touchpadAreas & PAD_AREA_LEFT ) ) + { + return true; + } + else if ( y > 0 && std::abs( x ) < y + && ( config->touchpadAreas & PAD_AREA_TOP ) ) + { + return true; + } + else if ( x > 0 && std::abs( y ) < x + && ( config->touchpadAreas + & PAD_AREA_RIGHT ) ) + { + return true; + } + else if ( y < 0 && std::abs( x ) < -y + && ( config->touchpadAreas + & PAD_AREA_BOTTOM ) ) + { + return true; + } + } + } + } + } + return false; }; - if (m_pttEnabled) { - bool newState = false; - if (m_pttLeftControllerEnabled) { - auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); - if (leftId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(leftId, &state, sizeof(vr::VRControllerState_t))) { - //logControllerState(state, "Left "); - newState |= handleControllerState(state, m_pttControllerConfigs); - } + if ( m_pttEnabled ) + { + bool newState = false; + if ( m_pttLeftControllerEnabled ) + { + auto leftId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_LeftHand ); + if ( leftId != vr::k_unTrackedDeviceIndexInvalid ) + { + vr::VRControllerState_t state; + if ( vr::VRSystem()->GetControllerState( + leftId, &state, sizeof( vr::VRControllerState_t ) ) ) + { + // logControllerState(state, "Left "); + newState |= handleControllerState( state, + m_pttControllerConfigs ); + } + } } - } - if (m_pttRightControllerEnabled) { - auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (rightId != vr::k_unTrackedDeviceIndexInvalid) { - vr::VRControllerState_t state; - if (vr::VRSystem()->GetControllerState(rightId, &state, sizeof(vr::VRControllerState_t))) { - //logControllerState(state, "Right "); - newState |= handleControllerState(state, m_pttControllerConfigs + 1); - } + if ( m_pttRightControllerEnabled ) + { + auto rightId + = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( + vr::TrackedControllerRole_RightHand ); + if ( rightId != vr::k_unTrackedDeviceIndexInvalid ) + { + vr::VRControllerState_t state; + if ( vr::VRSystem()->GetControllerState( + rightId, &state, sizeof( vr::VRControllerState_t ) ) ) + { + // logControllerState(state, "Right "); + newState |= handleControllerState( + state, m_pttControllerConfigs + 1 ); + } + } + } + if ( newState && !m_pttActive && pttChangeValid() ) + { + startPtt(); + } + else if ( !newState && m_pttActive && pttChangeValid() ) + { + stopPtt(); } - } - if (newState && !m_pttActive && pttChangeValid()) { - startPtt(); - } else if (!newState && m_pttActive && pttChangeValid()) { - stopPtt(); - } } - } +} - void PttController::startPtt() { +void PttController::startPtt() +{ m_pttActive = true; onPttStart(); - if (m_pttShowNotification && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid) { - vr::VROverlay()->ShowOverlay(getNotificationOverlayHandle()); + if ( m_pttShowNotification + && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid ) + { + vr::VROverlay()->ShowOverlay( getNotificationOverlayHandle() ); } - emit pttActiveChanged(m_pttActive); - } + emit pttActiveChanged( m_pttActive ); +} - void PttController::stopPtt() { +void PttController::stopPtt() +{ m_pttActive = false; onPttStop(); - if (m_pttShowNotification && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid) { - vr::VROverlay()->HideOverlay(getNotificationOverlayHandle()); + if ( m_pttShowNotification + && getNotificationOverlayHandle() != vr::k_ulOverlayHandleInvalid ) + { + vr::VROverlay()->HideOverlay( getNotificationOverlayHandle() ); } - emit pttActiveChanged(m_pttActive); - } + emit pttActiveChanged( m_pttActive ); +} - void PttController::addPttProfile(QString name) { +void PttController::addPttProfile( QString name ) +{ PttProfile* profile = nullptr; - for (auto& p : pttProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } + for ( auto& p : pttProfiles ) + { + if ( p.profileName.compare( name.toStdString() ) == 0 ) + { + profile = &p; + break; + } } - if (!profile) { - auto i = pttProfiles.size(); - pttProfiles.emplace_back(); - profile = &pttProfiles[i]; + if ( !profile ) + { + auto i = pttProfiles.size(); + pttProfiles.emplace_back(); + profile = &pttProfiles[i]; } profile->profileName = name.toStdString(); profile->showNotification = m_pttShowNotification; profile->leftControllerEnabled = m_pttLeftControllerEnabled; profile->rightControllerEnabled = m_pttRightControllerEnabled; - profile->controllerConfigs[0].digitalButtons = m_pttControllerConfigs[0].digitalButtons; - profile->controllerConfigs[0].digitalButtonMask = m_pttControllerConfigs[0].digitalButtonMask; - profile->controllerConfigs[0].triggerMode = m_pttControllerConfigs[0].triggerMode; - profile->controllerConfigs[0].touchpadMode = m_pttControllerConfigs[0].touchpadMode; - profile->controllerConfigs[0].touchpadAreas = m_pttControllerConfigs[0].touchpadAreas; - profile->controllerConfigs[1].digitalButtons = m_pttControllerConfigs[1].digitalButtons; - profile->controllerConfigs[1].digitalButtonMask = m_pttControllerConfigs[1].digitalButtonMask; - profile->controllerConfigs[1].triggerMode = m_pttControllerConfigs[1].triggerMode; - profile->controllerConfigs[1].touchpadMode = m_pttControllerConfigs[1].touchpadMode; - profile->controllerConfigs[1].touchpadAreas = m_pttControllerConfigs[1].touchpadAreas; + profile->controllerConfigs[0].digitalButtons + = m_pttControllerConfigs[0].digitalButtons; + profile->controllerConfigs[0].digitalButtonMask + = m_pttControllerConfigs[0].digitalButtonMask; + profile->controllerConfigs[0].triggerMode + = m_pttControllerConfigs[0].triggerMode; + profile->controllerConfigs[0].touchpadMode + = m_pttControllerConfigs[0].touchpadMode; + profile->controllerConfigs[0].touchpadAreas + = m_pttControllerConfigs[0].touchpadAreas; + profile->controllerConfigs[1].digitalButtons + = m_pttControllerConfigs[1].digitalButtons; + profile->controllerConfigs[1].digitalButtonMask + = m_pttControllerConfigs[1].digitalButtonMask; + profile->controllerConfigs[1].triggerMode + = m_pttControllerConfigs[1].triggerMode; + profile->controllerConfigs[1].touchpadMode + = m_pttControllerConfigs[1].touchpadMode; + profile->controllerConfigs[1].touchpadAreas + = m_pttControllerConfigs[1].touchpadAreas; savePttProfiles(); OverlayController::appSettings()->sync(); emit pttProfilesUpdated(); - } +} - void PttController::applyPttProfile(unsigned index) { - std::lock_guard lock(eventLoopMutex); - if (index < pttProfiles.size()) { - auto& profile = pttProfiles[index]; - setPttShowNotification(profile.showNotification); - setPttLeftControllerEnabled(profile.leftControllerEnabled); - setPttRightControllerEnabled(profile.rightControllerEnabled); - m_pttControllerConfigs[0].digitalButtons = profile.controllerConfigs[0].digitalButtons; - m_pttControllerConfigs[0].digitalButtonMask = profile.controllerConfigs[0].digitalButtonMask; - m_pttControllerConfigs[0].triggerMode = profile.controllerConfigs[0].triggerMode; - m_pttControllerConfigs[0].touchpadMode = profile.controllerConfigs[0].touchpadMode; - m_pttControllerConfigs[0].touchpadAreas = profile.controllerConfigs[0].touchpadAreas; - m_pttControllerConfigs[1].digitalButtons = profile.controllerConfigs[1].digitalButtons; - m_pttControllerConfigs[1].digitalButtonMask = profile.controllerConfigs[1].digitalButtonMask; - m_pttControllerConfigs[1].triggerMode = profile.controllerConfigs[1].triggerMode; - m_pttControllerConfigs[1].touchpadMode = profile.controllerConfigs[1].touchpadMode; - m_pttControllerConfigs[1].touchpadAreas = profile.controllerConfigs[1].touchpadAreas; +void PttController::applyPttProfile( unsigned index ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( index < pttProfiles.size() ) + { + auto& profile = pttProfiles[index]; + setPttShowNotification( profile.showNotification ); + setPttLeftControllerEnabled( profile.leftControllerEnabled ); + setPttRightControllerEnabled( profile.rightControllerEnabled ); + m_pttControllerConfigs[0].digitalButtons + = profile.controllerConfigs[0].digitalButtons; + m_pttControllerConfigs[0].digitalButtonMask + = profile.controllerConfigs[0].digitalButtonMask; + m_pttControllerConfigs[0].triggerMode + = profile.controllerConfigs[0].triggerMode; + m_pttControllerConfigs[0].touchpadMode + = profile.controllerConfigs[0].touchpadMode; + m_pttControllerConfigs[0].touchpadAreas + = profile.controllerConfigs[0].touchpadAreas; + m_pttControllerConfigs[1].digitalButtons + = profile.controllerConfigs[1].digitalButtons; + m_pttControllerConfigs[1].digitalButtonMask + = profile.controllerConfigs[1].digitalButtonMask; + m_pttControllerConfigs[1].triggerMode + = profile.controllerConfigs[1].triggerMode; + m_pttControllerConfigs[1].touchpadMode + = profile.controllerConfigs[1].touchpadMode; + m_pttControllerConfigs[1].touchpadAreas + = profile.controllerConfigs[1].touchpadAreas; } - } +} - void PttController::deletePttProfile(unsigned index) { - if (index < pttProfiles.size()) { - auto pos = pttProfiles.begin() + index; - pttProfiles.erase(pos); - savePttProfiles(); - OverlayController::appSettings()->sync(); - emit pttProfilesUpdated(); +void PttController::deletePttProfile( unsigned index ) +{ + if ( index < pttProfiles.size() ) + { + auto pos = pttProfiles.begin() + index; + pttProfiles.erase( pos ); + savePttProfiles(); + OverlayController::appSettings()->sync(); + emit pttProfilesUpdated(); } - } +} - QVariantList PttController::pttDigitalButtons(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtons; +QVariantList PttController::pttDigitalButtons( unsigned controller ) +{ + if ( controller < 2 ) + { + return m_pttControllerConfigs[controller].digitalButtons; } return QVariantList(); - } +} - unsigned long PttController::pttDigitalButtonMask(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].digitalButtonMask; +unsigned long PttController::pttDigitalButtonMask( unsigned controller ) +{ + if ( controller < 2 ) + { + return m_pttControllerConfigs[controller].digitalButtonMask; } return 0; - } +} - unsigned PttController::pttTouchpadMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadMode; +unsigned PttController::pttTouchpadMode( unsigned controller ) +{ + if ( controller < 2 ) + { + return m_pttControllerConfigs[controller].touchpadMode; } return 0; - } +} - unsigned PttController::pttTriggerMode(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].triggerMode; +unsigned PttController::pttTriggerMode( unsigned controller ) +{ + if ( controller < 2 ) + { + return m_pttControllerConfigs[controller].triggerMode; } return 0; - } +} - unsigned PttController::pttTouchpadArea(unsigned controller) { - if (controller < 2) { - return m_pttControllerConfigs[controller].touchpadAreas; +unsigned PttController::pttTouchpadArea( unsigned controller ) +{ + if ( controller < 2 ) + { + return m_pttControllerConfigs[controller].touchpadAreas; } return 0; - } +} - unsigned PttController::getPttProfileCount() { - return (unsigned)pttProfiles.size(); - } +unsigned PttController::getPttProfileCount() +{ + return ( unsigned ) pttProfiles.size(); +} - QString PttController::getPttProfileName(unsigned index) { - if (index < pttProfiles.size()) { - return QString::fromStdString(pttProfiles[index].profileName); +QString PttController::getPttProfileName( unsigned index ) +{ + if ( index < pttProfiles.size() ) + { + return QString::fromStdString( pttProfiles[index].profileName ); } return ""; - } +} - void PttController::setPttEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttEnabled) { - m_pttEnabled = value; - if (value) { - onPttEnabled(); - } else { - onPttDisabled(); - } - if (notify) { - emit pttEnabledChanged(value); - } - if (save) { - savePttConfig(); - } +void PttController::setPttEnabled( bool value, bool notify, bool save ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_pttEnabled ) + { + m_pttEnabled = value; + if ( value ) + { + onPttEnabled(); + } + else + { + onPttDisabled(); + } + if ( notify ) + { + emit pttEnabledChanged( value ); + } + if ( save ) + { + savePttConfig(); + } } - } +} - void PttController::setPttShowNotification(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttShowNotification) { - m_pttShowNotification = value; - if (notify) { - emit pttShowNotificationChanged(value); - } - if (save) { - savePttConfig(); - } +void PttController::setPttShowNotification( bool value, bool notify, bool save ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_pttShowNotification ) + { + m_pttShowNotification = value; + if ( notify ) + { + emit pttShowNotificationChanged( value ); + } + if ( save ) + { + savePttConfig(); + } } - } +} - void PttController::setPttLeftControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttLeftControllerEnabled) { - m_pttLeftControllerEnabled = value; - if (notify) { - emit pttLeftControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } +void PttController::setPttLeftControllerEnabled( bool value, + bool notify, + bool save ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_pttLeftControllerEnabled ) + { + m_pttLeftControllerEnabled = value; + if ( notify ) + { + emit pttLeftControllerEnabledChanged( value ); + } + if ( save ) + { + savePttConfig(); + } } - } +} - void PttController::setPttRightControllerEnabled(bool value, bool notify, bool save) { - std::lock_guard lock(eventLoopMutex); - if (value != m_pttRightControllerEnabled) { - m_pttRightControllerEnabled = value; - if (notify) { - emit pttRightControllerEnabledChanged(value); - } - if (save) { - savePttConfig(); - } +void PttController::setPttRightControllerEnabled( bool value, + bool notify, + bool save ) +{ + std::lock_guard lock( eventLoopMutex ); + if ( value != m_pttRightControllerEnabled ) + { + m_pttRightControllerEnabled = value; + if ( notify ) + { + emit pttRightControllerEnabledChanged( value ); + } + if ( save ) + { + savePttConfig(); + } } - } +} - void logControllerState(const vr::VRControllerState_t& state, const std::string& prefix) { - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " pressed"; +void logControllerState( const vr::VRControllerState_t& state, + const std::string& prefix ) +{ + if ( state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_ApplicationMenu ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_ApplicationMenu ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_ApplicationMenu)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_ApplicationMenu) << " touched"; + if ( state.ulButtonTouched + & vr::ButtonMaskFromId( vr::k_EButton_ApplicationMenu ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_ApplicationMenu ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " pressed"; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Grip ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Grip ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Grip)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Grip) << " touched"; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Grip ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Grip ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " pressed"; + if ( state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Left ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Left ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Left)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Left) << " touched"; + if ( state.ulButtonTouched + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Left ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Left ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " pressed"; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_DPad_Up ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Up ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Up)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Up) << " touched"; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_DPad_Up ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Up ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " pressed"; + if ( state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Right ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Right ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Right)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Right) << " touched"; + if ( state.ulButtonTouched + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Right ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Right ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " pressed"; + if ( state.ulButtonPressed + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Down ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Down ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_DPad_Down)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_DPad_Down) << " touched"; + if ( state.ulButtonTouched + & vr::ButtonMaskFromId( vr::k_EButton_DPad_Down ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_DPad_Down ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_A)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " pressed"; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_A ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_A ) + << " pressed"; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_A)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_A) << " touched"; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_A ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_A ) + << " touched"; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Axis0 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis0 ) + << " pressed"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis0 ) + << " x: " << state.rAxis[0].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis0)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis0) << " x: " << state.rAxis[0].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Axis0 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis0 ) + << " touched"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis0 ) + << " x: " << state.rAxis[0].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Axis1 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis1 ) + << " pressed"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis1 ) + << " x: " << state.rAxis[1].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis1)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis1) << " x: " << state.rAxis[1].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Axis1 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis1 ) + << " touched"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis1 ) + << " x: " << state.rAxis[1].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Axis2 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis2 ) + << " pressed"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis2 ) + << " x: " << state.rAxis[2].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis2)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis2) << " x: " << state.rAxis[2].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Axis2 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis2 ) + << " touched"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis2 ) + << " x: " << state.rAxis[2].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Axis3 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis3 ) + << " pressed"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis3 ) + << " x: " << state.rAxis[3].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis3)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis3) << " x: " << state.rAxis[3].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Axis3 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis3 ) + << " touched"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis3 ) + << " x: " << state.rAxis[3].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " pressed"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonPressed & vr::ButtonMaskFromId( vr::k_EButton_Axis4 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis4 ) + << " pressed"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis4 ) + << " x: " << state.rAxis[4].x + << " y: " << state.rAxis[0].y; } - if (state.ulButtonTouched & vr::ButtonMaskFromId(vr::k_EButton_Axis4)) { - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " touched"; - LOG(INFO) << prefix << vr::VRSystem()->GetButtonIdNameFromEnum(vr::k_EButton_Axis4) << " x: " << state.rAxis[4].x << " y: " << state.rAxis[0].y; + if ( state.ulButtonTouched & vr::ButtonMaskFromId( vr::k_EButton_Axis4 ) ) + { + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis4 ) + << " touched"; + LOG( INFO ) << prefix + << vr::VRSystem()->GetButtonIdNameFromEnum( + vr::k_EButton_Axis4 ) + << " x: " << state.rAxis[4].x + << " y: " << state.rAxis[0].y; } - } +} -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/PttController.h b/src/tabcontrollers/PttController.h index cad777c..6032fc5 100644 --- a/src/tabcontrollers/PttController.h +++ b/src/tabcontrollers/PttController.h @@ -10,45 +10,55 @@ class QQuickWindow; // application namespace -namespace advsettings { +namespace advsettings +{ +// forward declaration +class OverlayController; - // forward declaration - class OverlayController; +enum TouchPadArea +{ + PAD_AREA_LEFT = ( 1 << 0 ), + PAD_AREA_TOP = ( 1 << 1 ), + PAD_AREA_RIGHT = ( 1 << 2 ), + PAD_AREA_BOTTOM = ( 1 << 3 ), +}; - enum TouchPadArea { - PAD_AREA_LEFT = (1 << 0), - PAD_AREA_TOP = (1 << 1), - PAD_AREA_RIGHT = (1 << 2), - PAD_AREA_BOTTOM = (1 << 3), - }; - - struct PttControllerConfig { +struct PttControllerConfig +{ QVariantList digitalButtons; uint64_t digitalButtonMask = 0; unsigned triggerMode = 0; // 0 .. disabled, 1 .. enabled - unsigned touchpadMode = 0; // 0 .. disabled, 1 .. only touch, 2 .. only press, 3 .. both + unsigned touchpadMode + = 0; // 0 .. disabled, 1 .. only touch, 2 .. only press, 3 .. both unsigned touchpadAreas = 0; - }; +}; - struct PttProfile { +struct PttProfile +{ std::string profileName; bool showNotification = false; bool leftControllerEnabled = false; bool rightControllerEnabled = false; PttControllerConfig controllerConfigs[2]; - }; +}; - - class PttController : public QObject { +class PttController : public QObject +{ Q_OBJECT - Q_PROPERTY(bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY pttEnabledChanged) - Q_PROPERTY(bool pttActive READ pttActive NOTIFY pttActiveChanged) - Q_PROPERTY(bool pttShowNotification READ pttShowNotification WRITE setPttShowNotification NOTIFY pttShowNotificationChanged) - Q_PROPERTY(bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged) - Q_PROPERTY(bool pttRightControllerEnabled READ pttRightControllerEnabled WRITE setPttRightControllerEnabled NOTIFY pttRightControllerEnabledChanged) + Q_PROPERTY( bool pttEnabled READ pttEnabled WRITE setPttEnabled NOTIFY + pttEnabledChanged ) + Q_PROPERTY( bool pttActive READ pttActive NOTIFY pttActiveChanged ) + Q_PROPERTY( bool pttShowNotification READ pttShowNotification WRITE + setPttShowNotification NOTIFY pttShowNotificationChanged ) + Q_PROPERTY( + bool pttLeftControllerEnabled READ pttLeftControllerEnabled WRITE + setPttLeftControllerEnabled NOTIFY pttLeftControllerEnabledChanged ) + Q_PROPERTY( bool pttRightControllerEnabled READ pttRightControllerEnabled + WRITE setPttRightControllerEnabled NOTIFY + pttRightControllerEnabledChanged ) - protected: +protected: bool m_pttEnabled = false; bool m_pttActive = false; bool m_pttShowNotification = false; @@ -58,18 +68,24 @@ namespace advsettings { std::vector pttProfiles; - protected: +protected: void checkPttStatus(); - virtual QString getSettingsName() = 0; - virtual void onPttStart() {}; - virtual void onPttStop() {}; - virtual void onPttEnabled() {}; - virtual void onPttDisabled() {}; - virtual bool pttChangeValid() { return true; } - virtual vr::VROverlayHandle_t getNotificationOverlayHandle() { return vr::k_ulOverlayHandleInvalid; } + virtual QString getSettingsName() = 0; + virtual void onPttStart(){}; + virtual void onPttStop(){}; + virtual void onPttEnabled(){}; + virtual void onPttDisabled(){}; + virtual bool pttChangeValid() + { + return true; + } + virtual vr::VROverlayHandle_t getNotificationOverlayHandle() + { + return vr::k_ulOverlayHandleInvalid; + } std::recursive_mutex eventLoopMutex; - public: +public: bool pttEnabled() const; bool pttActive() const; bool pttShowNotification() const; @@ -84,36 +100,45 @@ namespace advsettings { void savePttProfiles(); void savePttConfig(); - - Q_INVOKABLE QVariantList pttDigitalButtons(unsigned controller); - Q_INVOKABLE unsigned long pttDigitalButtonMask(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadMode(unsigned controller); - Q_INVOKABLE unsigned pttTriggerMode(unsigned controller); - Q_INVOKABLE unsigned pttTouchpadArea(unsigned controller); + Q_INVOKABLE QVariantList pttDigitalButtons( unsigned controller ); + Q_INVOKABLE unsigned long pttDigitalButtonMask( unsigned controller ); + Q_INVOKABLE unsigned pttTouchpadMode( unsigned controller ); + Q_INVOKABLE unsigned pttTriggerMode( unsigned controller ); + Q_INVOKABLE unsigned pttTouchpadArea( unsigned controller ); Q_INVOKABLE unsigned getPttProfileCount(); - Q_INVOKABLE QString getPttProfileName(unsigned index); + Q_INVOKABLE QString getPttProfileName( unsigned index ); - public slots: - void setPttEnabled(bool value, bool notify = true, bool save = true); - void setPttShowNotification(bool value, bool notify = true, bool save = true); - void setPttLeftControllerEnabled(bool value, bool notify = true, bool save = true); - void setPttRightControllerEnabled(bool value, bool notify = true, bool save = true); +public slots: + void setPttEnabled( bool value, bool notify = true, bool save = true ); + void setPttShowNotification( bool value, + bool notify = true, + bool save = true ); + void setPttLeftControllerEnabled( bool value, + bool notify = true, + bool save = true ); + void setPttRightControllerEnabled( bool value, + bool notify = true, + bool save = true ); - void setPttControllerConfig(unsigned controller, QVariantList buttons, unsigned triggerMode, unsigned padMode, unsigned padAreas); + void setPttControllerConfig( unsigned controller, + QVariantList buttons, + unsigned triggerMode, + unsigned padMode, + unsigned padAreas ); - void addPttProfile(QString name); - void applyPttProfile(unsigned index); - void deletePttProfile(unsigned index); + void addPttProfile( QString name ); + void applyPttProfile( unsigned index ); + void deletePttProfile( unsigned index ); - signals: - void pttEnabledChanged(bool value); - void pttActiveChanged(bool value); - void pttShowNotificationChanged(bool value); - void pttLeftControllerEnabledChanged(bool value); - void pttRightControllerEnabledChanged(bool value); +signals: + void pttEnabledChanged( bool value ); + void pttActiveChanged( bool value ); + void pttShowNotificationChanged( bool value ); + void pttLeftControllerEnabledChanged( bool value ); + void pttRightControllerEnabledChanged( bool value ); void pttProfilesUpdated(); - }; +}; } // namespace advsettings diff --git a/src/tabcontrollers/ReviveTabController.cpp b/src/tabcontrollers/ReviveTabController.cpp index 78c7d80..8f5f6e8 100644 --- a/src/tabcontrollers/ReviveTabController.cpp +++ b/src/tabcontrollers/ReviveTabController.cpp @@ -3,849 +3,1320 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { - - const char* appkey_overlay = "revive.dashboard.overlay"; - const char* section_revive = "revive"; - const char* key_pixelsPerDisplayPixel = "pixelsPerDisplayPixel"; - const char* key_toggleGrip = "ToggleGrip"; - const char* key_triggerAsGrip = "TriggerAsGrip"; - const char* key_toggleDelay = "ToggleDelay"; - const char* key_thumbDeadzone = "ThumbDeadzone"; - const char* key_thumbSensitivity = "ThumbSensitivity"; - const char* key_touchPitch = "TouchPitch"; - const char* key_touchYaw = "TouchYaw"; - const char* key_touchRoll = "TouchRoll"; - const char* key_touchX = "TouchX"; - const char* key_touchY = "TouchY"; - const char* key_touchZ = "TouchZ"; - const char* key_playerHeight = "PlayerHeight"; - const char* key_eyeHeight = "EyeHeight"; - const char* key_piUser = "User"; - const char* key_piName = "Name"; - const char* key_piGender = "Gender"; - - - void ReviveTabController::initStage1(bool forceRevivePage) { - m_isOverlayInstalled = vr::VRApplications()->IsApplicationInstalled(appkey_overlay); - if (m_isOverlayInstalled || forceRevivePage) { - vr::EVRSettingsError vrSettingsError; - - float valuef = vr::VRSettings()->GetFloat(section_revive, key_pixelsPerDisplayPixel, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_pixelsPerDisplayPixel << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - if (valuef == 0.0) { - m_pixelsPerDisplayPixelOverrideEnabled = false; - m_pixelsPerDisplayPixelOverride = 1.0; - } else { - m_pixelsPerDisplayPixelOverrideEnabled = true; - m_pixelsPerDisplayPixelOverride = valuef; - } - } - - int valuei = vr::VRSettings()->GetInt32(section_revive, key_toggleGrip, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_toggleGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_gripButtonMode = valuei; - } - - bool valueb = vr::VRSettings()->GetBool(section_revive, key_triggerAsGrip, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_triggerAsGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_triggerAsGrip = valueb; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_toggleDelay, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_toggleDelay << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_toggleDelay = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_thumbDeadzone, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_thumbDeadzone << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_thumbDeadzone = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_thumbSensitivity, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_thumbSensitivity << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_thumbRange = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchPitch, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchPitch << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchPitch = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchYaw, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchYaw << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchYaw = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchRoll, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchRoll << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchRoll = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchX, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchX << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchX = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchY, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchY << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchY = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchZ, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_touchZ << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_touchZ = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_playerHeight, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_playerHeight << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_piPlayerHeight = valuef; - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_eyeHeight, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_eyeHeight << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_piEyeHeight = valuef; - } - - char buffer[1024]; - vr::VRSettings()->GetString(section_revive, key_piUser, buffer, 1024, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_piUser << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_piUsername = buffer; - } - - vr::VRSettings()->GetString(section_revive, key_piName, buffer, 1024, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_piName << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - m_piName = buffer; - } - - vr::VRSettings()->GetString(section_revive, key_piGender, buffer, 1024, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"revive::" << key_piGender << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } else { - if (QString(buffer).compare("male", Qt::CaseInsensitive) == 0) { - m_piGender = 1; - } else if (QString(buffer).compare("female", Qt::CaseInsensitive) == 0) { - m_piGender = 2; - } else { - m_piGender = 0; - } - } - - reloadControllerProfiles(); - } - } - - void ReviveTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; - } - - void ReviveTabController::eventLoopTick() { - if (m_isOverlayInstalled || parent->settingsTabController.forceRevivePage()) { - if (settingsUpdateCounter >= 50) { - settingsUpdateCounter = 0; - vr::EVRSettingsError vrSettingsError; - - float valuef = vr::VRSettings()->GetFloat(section_revive, key_pixelsPerDisplayPixel, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - if (valuef == 0.0) { - setPixelsPerDisplayPixelOverrideEnabled(false); - } else { - setPixelsPerDisplayPixelOverrideEnabled(true); - setPixelsPerDisplayPixelOverride(valuef); - } - } - - int valuei = vr::VRSettings()->GetInt32(section_revive, key_toggleGrip, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setGripButtonMode(valuei); - } - - bool valueb = vr::VRSettings()->GetBool(section_revive, key_triggerAsGrip, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTriggerAsGrip(valueb); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_toggleDelay, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setToggleDelay(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_thumbDeadzone, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setThumbDeadzone(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_thumbSensitivity, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setThumbRange(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchPitch, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchPitch(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchYaw, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchYaw(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchRoll, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchRoll(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchX, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchX(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchY, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchY(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_touchZ, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setTouchZ(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_playerHeight, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setPiPlayerHeight(valuef); - } - - valuef = vr::VRSettings()->GetFloat(section_revive, key_eyeHeight, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setPiEyeHeight(valuef); - } - - char buffer[1024]; - vr::VRSettings()->GetString(section_revive, key_piUser, buffer, 1024, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setPiUsername(buffer); - } - - vr::VRSettings()->GetString(section_revive, key_piName, buffer, 1024, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - setPiName(buffer); - } - - vr::VRSettings()->GetString(section_revive, key_piGender, buffer, 1024, &vrSettingsError); - if (vrSettingsError == vr::VRSettingsError_None) { - if (QString(buffer).compare("male", Qt::CaseInsensitive) == 0) { - valuei = 1; - } else if (QString(buffer).compare("female", Qt::CaseInsensitive) == 0) { - valuei = 2; - } else { - valuei = 0; - } - setPiGender(valuei); - } - } else { - settingsUpdateCounter++; - } - } - } - - bool ReviveTabController::isOverlayInstalled() const { - return m_isOverlayInstalled; - } - - int ReviveTabController::gripButtonMode() const { - return m_gripButtonMode; - } - - bool ReviveTabController::triggerAsGrip() const { - return m_triggerAsGrip; - } - - float ReviveTabController::toggleDelay() const { - return m_toggleDelay; - } - - bool ReviveTabController::isPixelsPerDisplayPixelOverrideEnabled() const { - return m_pixelsPerDisplayPixelOverrideEnabled; - } - - float ReviveTabController::pixelsPerDisplayPixelOverride() const { - return m_pixelsPerDisplayPixelOverride; - } - - float ReviveTabController::thumbDeadzone() const { - return m_thumbDeadzone; - } - - float ReviveTabController::thumbRange() const { - return m_thumbRange; - } - - float ReviveTabController::touchPitch() const { - return m_touchPitch; - } - - float ReviveTabController::touchYaw() const { - return m_touchYaw; - } - - float ReviveTabController::touchRoll() const { - return m_touchRoll; - } - - float ReviveTabController::touchX() const { - return m_touchX; - } - - float ReviveTabController::touchY() const { - return m_touchY; - } - - float ReviveTabController::touchZ() const { - return m_touchZ; - } - - float ReviveTabController::piPlayerHeight() const { - return m_piPlayerHeight; - } - - float ReviveTabController::piEyeHeight() const { - return m_piEyeHeight; - } - - const QString& ReviveTabController::piUsername() const { - return m_piUsername; - } - - const QString& ReviveTabController::piName() const { - return m_piName; - } - - int ReviveTabController::piGender() const { - return m_piGender; - } - - void ReviveTabController::setGripButtonMode(int value, bool notify) { - if (m_gripButtonMode != value) { - m_gripButtonMode = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetInt32(section_revive, key_toggleGrip, m_gripButtonMode, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_toggleGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit gripButtonModeChanged(m_gripButtonMode); - } - } - } - - void ReviveTabController::setTriggerAsGrip(bool value, bool notify) { - if (m_triggerAsGrip != value) { - m_triggerAsGrip = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetBool(section_revive, key_triggerAsGrip, m_triggerAsGrip, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_toggleGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit triggerAsGripChanged(m_triggerAsGrip); - } - } - } - - void ReviveTabController::setToggleDelay(float value, bool notify) { - if (m_toggleDelay != value) { - m_toggleDelay = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_toggleDelay, m_toggleDelay, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_toggleDelay << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit toggleDelayChanged(m_toggleDelay); - } - } - } - - void ReviveTabController::setPixelsPerDisplayPixelOverrideEnabled(bool value, bool notify) { - if (m_pixelsPerDisplayPixelOverrideEnabled != value) { - m_pixelsPerDisplayPixelOverrideEnabled = value; - if (m_pixelsPerDisplayPixelOverrideEnabled) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_pixelsPerDisplayPixel, m_pixelsPerDisplayPixelOverride, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_pixelsPerDisplayPixel << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - } else { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->RemoveKeyInSection(section_revive, key_pixelsPerDisplayPixel, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_pixelsPerDisplayPixel << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - } - vr::VRSettings()->Sync(); - if (notify) { - emit pixelsPerDisplayPixelOverrideEnabledChanged(m_pixelsPerDisplayPixelOverrideEnabled); - } - } - } - - void ReviveTabController::setPixelsPerDisplayPixelOverride(float value, bool notify) { - if (m_pixelsPerDisplayPixelOverride != value) { - m_pixelsPerDisplayPixelOverride = value; - if (m_pixelsPerDisplayPixelOverrideEnabled) { - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_pixelsPerDisplayPixel, m_pixelsPerDisplayPixelOverride, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_pixelsPerDisplayPixel << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - } - if (notify) { - emit pixelsPerDisplayPixelOverrideChanged(m_pixelsPerDisplayPixelOverride); - } - } - } - - void ReviveTabController::setThumbDeadzone(float value, bool notify) { - if (m_thumbDeadzone != value) { - m_thumbDeadzone = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_thumbDeadzone, m_thumbDeadzone, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_thumbDeadzone << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit thumbDeadzoneChanged(m_thumbDeadzone); - } - } - } - - void ReviveTabController::setThumbRange(float value, bool notify) { - if (m_thumbRange != value) { - m_thumbRange = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_thumbSensitivity, m_thumbRange, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_thumbSensitivity << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit thumbRangeChanged(m_thumbRange); - } - } - } - - void ReviveTabController::setTouchPitch(float value, bool notify) { - if (m_touchPitch != value) { - m_touchPitch = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchPitch, m_touchPitch, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchPitch << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchPitchChanged(m_touchPitch); - } - } - } - - void ReviveTabController::setTouchYaw(float value, bool notify) { - if (m_touchYaw != value) { - m_touchYaw = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchYaw, m_touchYaw, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchYaw << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchYawChanged(m_touchYaw); - } - } - } - - void ReviveTabController::setTouchRoll(float value, bool notify) { - if (m_touchRoll != value) { - m_touchRoll = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchRoll, m_touchRoll, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchRoll << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchRollChanged(m_touchRoll); - } - } - } - - void ReviveTabController::setTouchX(float value, bool notify) { - if (m_touchX != value) { - m_touchX = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchX, m_touchX, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchX << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchXChanged(m_touchX); - } - } - } - - void ReviveTabController::setTouchY(float value, bool notify) { - if (m_touchY != value) { - m_touchY = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchY, m_touchY, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchY << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchYChanged(m_touchY); - } - } - } - - void ReviveTabController::setTouchZ(float value, bool notify) { - if (m_touchZ != value) { - m_touchZ = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_touchZ, m_touchZ, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_touchZ << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit touchZChanged(m_touchZ); - } - } - } - - void ReviveTabController::setPiPlayerHeight(float value, bool notify) { - if (m_piPlayerHeight != value) { - m_piPlayerHeight = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_playerHeight, m_piPlayerHeight, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_playerHeight << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit piPlayerHeightChanged(m_piPlayerHeight); - } - } - } - - void ReviveTabController::setPiEyeHeight(float value, bool notify) { - if (m_piEyeHeight != value) { - m_piEyeHeight = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetFloat(section_revive, key_eyeHeight, m_piEyeHeight, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_eyeHeight << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit piEyeHeightChanged(m_piEyeHeight); - } - } - } - - void ReviveTabController::setPiUsername(const QString& value, bool notify) { - if (m_piUsername.compare(value) != 0) { - m_piUsername = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetString(section_revive, key_piUser, m_piUsername.toStdString().c_str(), &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_piUser << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit piUsernameChanged(m_piUsername); - } - } - } - - void ReviveTabController::setPiName(const QString& value, bool notify) { - if (m_piName.compare(value) != 0) { - m_piName = value; - vr::EVRSettingsError vrSettingsError; - vr::VRSettings()->SetString(section_revive, key_piName, m_piName.toStdString().c_str(), &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_piName << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit piNameChanged(m_piName); - } - } - } - - void ReviveTabController::setPiGender(int value, bool notify) { - if (m_piGender != value) { - m_piGender = value; - vr::EVRSettingsError vrSettingsError; - char* txt; - switch (value) { - case 1: - txt = (char*)"Male"; - break; - case 2: - txt = (char*)"Female"; - break; - default: - txt = (char*)"Unknown"; - break; - } - vr::VRSettings()->SetString(section_revive, key_piGender, txt, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not set \"revive::" << key_piGender << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - vr::VRSettings()->Sync(); - if (notify) { - emit piGenderChanged(m_piGender); - } - } - } - - - void ReviveTabController::reset() { - vr::EVRSettingsError vrSettingsError; - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_pixelsPerDisplayPixel, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_pixelsPerDisplayPixel << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_toggleGrip, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_toggleGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_triggerAsGrip, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_triggerAsGrip << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_toggleDelay, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_toggleDelay << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_thumbDeadzone, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_thumbDeadzone << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_thumbSensitivity, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_thumbSensitivity << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchPitch, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchPitch << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchYaw, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchYaw << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchRoll, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchRoll << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchX, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchX << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchY, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchY << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->RemoveKeyInSection(section_revive, key_touchZ, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"revive::" << key_touchZ << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->Sync(); - settingsUpdateCounter = 999; // Easiest way to get default values - } - - float ReviveTabController::getCurrentHMDHeight() { - float hmdHeight = 0.0f; - vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount]; - vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0.0f, devicePoses, vr::k_unMaxTrackedDeviceCount); - vr::TrackedDevicePose_t& hmdPose = devicePoses[vr::k_unTrackedDeviceIndex_Hmd]; - if (hmdPose.eTrackingResult == vr::TrackingResult_Running_OK) { - hmdHeight = hmdPose.mDeviceToAbsoluteTracking.m[1][3]; - } else { - LOG(WARNING) << "Error while getting HMD pose: Tracking result (" << hmdPose.eTrackingResult << ") is not TrackingResult_Running_OK"; - } - return hmdHeight; - } - - - void ReviveTabController::reloadControllerProfiles() { - controllerProfiles.clear(); - auto settings = OverlayController::appSettings(); - settings->beginGroup("reviveSettings"); - auto profileCount = settings->beginReadArray("controllerProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - controllerProfiles.emplace_back(); - auto& entry = controllerProfiles[i]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.gripButtonMode = settings->value("gripButtonMode", 0).toInt(); - entry.triggerAsGrip = settings->value("triggerAsGrip", 0).toBool(); - entry.thumbDeadzone = settings->value("thumbDeadzone", 0.3f).toFloat(); - entry.thumbRange = settings->value("thumbRange", 2.0f).toFloat(); - entry.touchPitch = settings->value("touchPitch", -28.0f).toFloat(); - entry.touchYaw = settings->value("touchYaw", 0.0f).toFloat(); - entry.touchRoll = settings->value("touchRoll", -14.0f).toFloat(); - entry.touchX = settings->value("touchX", 0.016f).toFloat(); - entry.touchY = settings->value("touchY", 0.0f).toFloat(); - entry.touchZ = settings->value("touchZ", 0.016f).toFloat(); - } - settings->endArray(); - settings->endGroup(); - } - - - void ReviveTabController::saveControllerProfiles() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("reviveSettings"); - settings->beginWriteArray("controllerProfiles"); - unsigned i = 0; - for (auto& p : controllerProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("gripButtonMode", p.gripButtonMode); - settings->setValue("triggerAsGrip", p.triggerAsGrip); - settings->setValue("thumbDeadzone", p.thumbDeadzone); - settings->setValue("thumbRange", p.thumbRange); - settings->setValue("touchPitch", p.touchPitch); - settings->setValue("touchYaw", p.touchYaw); - settings->setValue("touchRoll", p.touchRoll); - settings->setValue("touchX", p.touchX); - settings->setValue("touchY", p.touchY); - settings->setValue("touchZ", p.touchZ); - i++; - } - settings->endArray(); - settings->endGroup(); - } - - Q_INVOKABLE unsigned ReviveTabController::getControllerProfileCount() { - return (unsigned)controllerProfiles.size(); - } - - Q_INVOKABLE QString ReviveTabController::getControllerProfileName(unsigned index) { - if (index >= controllerProfiles.size()) { - return QString(); - } else { - return QString::fromStdString(controllerProfiles[index].profileName); - } - } - - void ReviveTabController::addControllerProfile(QString name) { - ReviveControllerProfile* profile = nullptr; - for (auto& p : controllerProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } - } - if (!profile) { - auto i = controllerProfiles.size(); - controllerProfiles.emplace_back(); - profile = &controllerProfiles[i]; - } - profile->profileName = name.toStdString(); - profile->gripButtonMode = gripButtonMode(); - profile->triggerAsGrip = triggerAsGrip(); - profile->thumbDeadzone = thumbDeadzone(); - profile->thumbRange = thumbRange(); - profile->touchPitch = touchPitch(); - profile->touchYaw = touchYaw(); - profile->touchRoll = touchRoll(); - profile->touchX = touchX(); - profile->touchY = touchY(); - profile->touchZ = touchZ(); - saveControllerProfiles(); - OverlayController::appSettings()->sync(); - emit controllerProfilesUpdated(); - } - - void ReviveTabController::applyControllerProfile(unsigned index) { - if (index < controllerProfiles.size()) { - auto& profile = controllerProfiles[index]; - setGripButtonMode(profile.gripButtonMode); - setTriggerAsGrip(profile.triggerAsGrip); - setThumbDeadzone(profile.thumbDeadzone); - setThumbRange(profile.thumbRange); - setTouchPitch(profile.touchPitch); - setTouchYaw(profile.touchYaw); - setTouchRoll(profile.touchRoll); - setTouchX(profile.touchX); - setTouchY(profile.touchY); - setTouchZ(profile.touchZ); - } - } - - void ReviveTabController::deleteControllerProfile(unsigned index) { - if (index < controllerProfiles.size()) { - auto pos = controllerProfiles.begin() + index; - controllerProfiles.erase(pos); - saveControllerProfiles(); - OverlayController::appSettings()->sync(); - emit controllerProfilesUpdated(); - } - } - -} // namespace advconfig +namespace advsettings +{ +const char* appkey_overlay = "revive.dashboard.overlay"; +const char* section_revive = "revive"; +const char* key_pixelsPerDisplayPixel = "pixelsPerDisplayPixel"; +const char* key_toggleGrip = "ToggleGrip"; +const char* key_triggerAsGrip = "TriggerAsGrip"; +const char* key_toggleDelay = "ToggleDelay"; +const char* key_thumbDeadzone = "ThumbDeadzone"; +const char* key_thumbSensitivity = "ThumbSensitivity"; +const char* key_touchPitch = "TouchPitch"; +const char* key_touchYaw = "TouchYaw"; +const char* key_touchRoll = "TouchRoll"; +const char* key_touchX = "TouchX"; +const char* key_touchY = "TouchY"; +const char* key_touchZ = "TouchZ"; +const char* key_playerHeight = "PlayerHeight"; +const char* key_eyeHeight = "EyeHeight"; +const char* key_piUser = "User"; +const char* key_piName = "Name"; +const char* key_piGender = "Gender"; + +void ReviveTabController::initStage1( bool forceRevivePage ) +{ + m_isOverlayInstalled + = vr::VRApplications()->IsApplicationInstalled( appkey_overlay ); + if ( m_isOverlayInstalled || forceRevivePage ) + { + vr::EVRSettingsError vrSettingsError; + + float valuef = vr::VRSettings()->GetFloat( + section_revive, key_pixelsPerDisplayPixel, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" + << key_pixelsPerDisplayPixel << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + if ( valuef == 0.0 ) + { + m_pixelsPerDisplayPixelOverrideEnabled = false; + m_pixelsPerDisplayPixelOverride = 1.0; + } + else + { + m_pixelsPerDisplayPixelOverrideEnabled = true; + m_pixelsPerDisplayPixelOverride = valuef; + } + } + + int valuei = vr::VRSettings()->GetInt32( + section_revive, key_toggleGrip, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_toggleGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_gripButtonMode = valuei; + } + + bool valueb = vr::VRSettings()->GetBool( + section_revive, key_triggerAsGrip, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_triggerAsGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_triggerAsGrip = valueb; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_toggleDelay, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_toggleDelay + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_toggleDelay = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_thumbDeadzone, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_thumbDeadzone + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_thumbDeadzone = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_thumbSensitivity, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" + << key_thumbSensitivity << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_thumbRange = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchPitch, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchPitch + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchPitch = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchYaw, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchYaw + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchYaw = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchRoll, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchRoll + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchRoll = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchX, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchX + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchX = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchY, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchY + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchY = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchZ, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_touchZ + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_touchZ = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_playerHeight, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_playerHeight + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_piPlayerHeight = valuef; + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_eyeHeight, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_eyeHeight + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_piEyeHeight = valuef; + } + + char buffer[1024]; + vr::VRSettings()->GetString( + section_revive, key_piUser, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_piUser + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_piUsername = buffer; + } + + vr::VRSettings()->GetString( + section_revive, key_piName, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_piName + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + m_piName = buffer; + } + + vr::VRSettings()->GetString( + section_revive, key_piGender, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"revive::" << key_piGender + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + else + { + if ( QString( buffer ).compare( "male", Qt::CaseInsensitive ) == 0 ) + { + m_piGender = 1; + } + else if ( QString( buffer ).compare( "female", Qt::CaseInsensitive ) + == 0 ) + { + m_piGender = 2; + } + else + { + m_piGender = 0; + } + } + + reloadControllerProfiles(); + } +} + +void ReviveTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; +} + +void ReviveTabController::eventLoopTick() +{ + if ( m_isOverlayInstalled + || parent->settingsTabController.forceRevivePage() ) + { + if ( settingsUpdateCounter >= 50 ) + { + settingsUpdateCounter = 0; + vr::EVRSettingsError vrSettingsError; + + float valuef = vr::VRSettings()->GetFloat( + section_revive, key_pixelsPerDisplayPixel, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + if ( valuef == 0.0 ) + { + setPixelsPerDisplayPixelOverrideEnabled( false ); + } + else + { + setPixelsPerDisplayPixelOverrideEnabled( true ); + setPixelsPerDisplayPixelOverride( valuef ); + } + } + + int valuei = vr::VRSettings()->GetInt32( + section_revive, key_toggleGrip, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setGripButtonMode( valuei ); + } + + bool valueb = vr::VRSettings()->GetBool( + section_revive, key_triggerAsGrip, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTriggerAsGrip( valueb ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_toggleDelay, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setToggleDelay( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_thumbDeadzone, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setThumbDeadzone( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_thumbSensitivity, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setThumbRange( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchPitch, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchPitch( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchYaw, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchYaw( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchRoll, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchRoll( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchX, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchX( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchY, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchY( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_touchZ, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setTouchZ( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_playerHeight, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setPiPlayerHeight( valuef ); + } + + valuef = vr::VRSettings()->GetFloat( + section_revive, key_eyeHeight, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setPiEyeHeight( valuef ); + } + + char buffer[1024]; + vr::VRSettings()->GetString( + section_revive, key_piUser, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setPiUsername( buffer ); + } + + vr::VRSettings()->GetString( + section_revive, key_piName, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + setPiName( buffer ); + } + + vr::VRSettings()->GetString( + section_revive, key_piGender, buffer, 1024, &vrSettingsError ); + if ( vrSettingsError == vr::VRSettingsError_None ) + { + if ( QString( buffer ).compare( "male", Qt::CaseInsensitive ) + == 0 ) + { + valuei = 1; + } + else if ( QString( buffer ).compare( "female", + Qt::CaseInsensitive ) + == 0 ) + { + valuei = 2; + } + else + { + valuei = 0; + } + setPiGender( valuei ); + } + } + else + { + settingsUpdateCounter++; + } + } +} + +bool ReviveTabController::isOverlayInstalled() const +{ + return m_isOverlayInstalled; +} + +int ReviveTabController::gripButtonMode() const +{ + return m_gripButtonMode; +} + +bool ReviveTabController::triggerAsGrip() const +{ + return m_triggerAsGrip; +} + +float ReviveTabController::toggleDelay() const +{ + return m_toggleDelay; +} + +bool ReviveTabController::isPixelsPerDisplayPixelOverrideEnabled() const +{ + return m_pixelsPerDisplayPixelOverrideEnabled; +} + +float ReviveTabController::pixelsPerDisplayPixelOverride() const +{ + return m_pixelsPerDisplayPixelOverride; +} + +float ReviveTabController::thumbDeadzone() const +{ + return m_thumbDeadzone; +} + +float ReviveTabController::thumbRange() const +{ + return m_thumbRange; +} + +float ReviveTabController::touchPitch() const +{ + return m_touchPitch; +} + +float ReviveTabController::touchYaw() const +{ + return m_touchYaw; +} + +float ReviveTabController::touchRoll() const +{ + return m_touchRoll; +} + +float ReviveTabController::touchX() const +{ + return m_touchX; +} + +float ReviveTabController::touchY() const +{ + return m_touchY; +} + +float ReviveTabController::touchZ() const +{ + return m_touchZ; +} + +float ReviveTabController::piPlayerHeight() const +{ + return m_piPlayerHeight; +} + +float ReviveTabController::piEyeHeight() const +{ + return m_piEyeHeight; +} + +const QString& ReviveTabController::piUsername() const +{ + return m_piUsername; +} + +const QString& ReviveTabController::piName() const +{ + return m_piName; +} + +int ReviveTabController::piGender() const +{ + return m_piGender; +} + +void ReviveTabController::setGripButtonMode( int value, bool notify ) +{ + if ( m_gripButtonMode != value ) + { + m_gripButtonMode = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetInt32( section_revive, + key_toggleGrip, + m_gripButtonMode, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_toggleGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit gripButtonModeChanged( m_gripButtonMode ); + } + } +} + +void ReviveTabController::setTriggerAsGrip( bool value, bool notify ) +{ + if ( m_triggerAsGrip != value ) + { + m_triggerAsGrip = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetBool( section_revive, + key_triggerAsGrip, + m_triggerAsGrip, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_toggleGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit triggerAsGripChanged( m_triggerAsGrip ); + } + } +} + +void ReviveTabController::setToggleDelay( float value, bool notify ) +{ + if ( m_toggleDelay != value ) + { + m_toggleDelay = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_toggleDelay, m_toggleDelay, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_toggleDelay + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit toggleDelayChanged( m_toggleDelay ); + } + } +} + +void ReviveTabController::setPixelsPerDisplayPixelOverrideEnabled( bool value, + bool notify ) +{ + if ( m_pixelsPerDisplayPixelOverrideEnabled != value ) + { + m_pixelsPerDisplayPixelOverrideEnabled = value; + if ( m_pixelsPerDisplayPixelOverrideEnabled ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( section_revive, + key_pixelsPerDisplayPixel, + m_pixelsPerDisplayPixelOverride, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not set \"revive::" << key_pixelsPerDisplayPixel + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + } + else + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_pixelsPerDisplayPixel, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not remove \"revive::" + << key_pixelsPerDisplayPixel << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit pixelsPerDisplayPixelOverrideEnabledChanged( + m_pixelsPerDisplayPixelOverrideEnabled ); + } + } +} + +void ReviveTabController::setPixelsPerDisplayPixelOverride( float value, + bool notify ) +{ + if ( m_pixelsPerDisplayPixelOverride != value ) + { + m_pixelsPerDisplayPixelOverride = value; + if ( m_pixelsPerDisplayPixelOverrideEnabled ) + { + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( section_revive, + key_pixelsPerDisplayPixel, + m_pixelsPerDisplayPixelOverride, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) + << "Could not set \"revive::" << key_pixelsPerDisplayPixel + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + } + if ( notify ) + { + emit pixelsPerDisplayPixelOverrideChanged( + m_pixelsPerDisplayPixelOverride ); + } + } +} + +void ReviveTabController::setThumbDeadzone( float value, bool notify ) +{ + if ( m_thumbDeadzone != value ) + { + m_thumbDeadzone = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( section_revive, + key_thumbDeadzone, + m_thumbDeadzone, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_thumbDeadzone + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit thumbDeadzoneChanged( m_thumbDeadzone ); + } + } +} + +void ReviveTabController::setThumbRange( float value, bool notify ) +{ + if ( m_thumbRange != value ) + { + m_thumbRange = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( section_revive, + key_thumbSensitivity, + m_thumbRange, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_thumbSensitivity + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit thumbRangeChanged( m_thumbRange ); + } + } +} + +void ReviveTabController::setTouchPitch( float value, bool notify ) +{ + if ( m_touchPitch != value ) + { + m_touchPitch = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchPitch, m_touchPitch, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchPitch + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchPitchChanged( m_touchPitch ); + } + } +} + +void ReviveTabController::setTouchYaw( float value, bool notify ) +{ + if ( m_touchYaw != value ) + { + m_touchYaw = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchYaw, m_touchYaw, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchYaw + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchYawChanged( m_touchYaw ); + } + } +} + +void ReviveTabController::setTouchRoll( float value, bool notify ) +{ + if ( m_touchRoll != value ) + { + m_touchRoll = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchRoll, m_touchRoll, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchRoll + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchRollChanged( m_touchRoll ); + } + } +} + +void ReviveTabController::setTouchX( float value, bool notify ) +{ + if ( m_touchX != value ) + { + m_touchX = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchX, m_touchX, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchX + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchXChanged( m_touchX ); + } + } +} + +void ReviveTabController::setTouchY( float value, bool notify ) +{ + if ( m_touchY != value ) + { + m_touchY = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchY, m_touchY, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchY + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchYChanged( m_touchY ); + } + } +} + +void ReviveTabController::setTouchZ( float value, bool notify ) +{ + if ( m_touchZ != value ) + { + m_touchZ = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_touchZ, m_touchZ, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_touchZ + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit touchZChanged( m_touchZ ); + } + } +} + +void ReviveTabController::setPiPlayerHeight( float value, bool notify ) +{ + if ( m_piPlayerHeight != value ) + { + m_piPlayerHeight = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( section_revive, + key_playerHeight, + m_piPlayerHeight, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_playerHeight + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit piPlayerHeightChanged( m_piPlayerHeight ); + } + } +} + +void ReviveTabController::setPiEyeHeight( float value, bool notify ) +{ + if ( m_piEyeHeight != value ) + { + m_piEyeHeight = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetFloat( + section_revive, key_eyeHeight, m_piEyeHeight, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_eyeHeight + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit piEyeHeightChanged( m_piEyeHeight ); + } + } +} + +void ReviveTabController::setPiUsername( const QString& value, bool notify ) +{ + if ( m_piUsername.compare( value ) != 0 ) + { + m_piUsername = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetString( section_revive, + key_piUser, + m_piUsername.toStdString().c_str(), + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_piUser + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit piUsernameChanged( m_piUsername ); + } + } +} + +void ReviveTabController::setPiName( const QString& value, bool notify ) +{ + if ( m_piName.compare( value ) != 0 ) + { + m_piName = value; + vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->SetString( section_revive, + key_piName, + m_piName.toStdString().c_str(), + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_piName + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit piNameChanged( m_piName ); + } + } +} + +void ReviveTabController::setPiGender( int value, bool notify ) +{ + if ( m_piGender != value ) + { + m_piGender = value; + vr::EVRSettingsError vrSettingsError; + char* txt; + switch ( value ) + { + case 1: + txt = ( char* ) "Male"; + break; + case 2: + txt = ( char* ) "Female"; + break; + default: + txt = ( char* ) "Unknown"; + break; + } + vr::VRSettings()->SetString( + section_revive, key_piGender, txt, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not set \"revive::" << key_piGender + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + vr::VRSettings()->Sync(); + if ( notify ) + { + emit piGenderChanged( m_piGender ); + } + } +} + +void ReviveTabController::reset() +{ + vr::EVRSettingsError vrSettingsError; + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_pixelsPerDisplayPixel, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" + << key_pixelsPerDisplayPixel << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_toggleGrip, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_toggleGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_triggerAsGrip, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_triggerAsGrip + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_toggleDelay, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_toggleDelay + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_thumbDeadzone, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_thumbDeadzone + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_thumbSensitivity, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_thumbSensitivity + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchPitch, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchPitch + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchYaw, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchYaw + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchRoll, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchRoll + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchX, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchX + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchY, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchY + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->RemoveKeyInSection( + section_revive, key_touchZ, &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"revive::" << key_touchZ + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + + vr::VRSettings()->Sync(); + settingsUpdateCounter = 999; // Easiest way to get default values +} + +float ReviveTabController::getCurrentHMDHeight() +{ + float hmdHeight = 0.0f; + vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount]; + vr::VRSystem()->GetDeviceToAbsoluteTrackingPose( + vr::TrackingUniverseStanding, + 0.0f, + devicePoses, + vr::k_unMaxTrackedDeviceCount ); + vr::TrackedDevicePose_t& hmdPose + = devicePoses[vr::k_unTrackedDeviceIndex_Hmd]; + if ( hmdPose.eTrackingResult == vr::TrackingResult_Running_OK ) + { + hmdHeight = hmdPose.mDeviceToAbsoluteTracking.m[1][3]; + } + else + { + LOG( WARNING ) << "Error while getting HMD pose: Tracking result (" + << hmdPose.eTrackingResult + << ") is not TrackingResult_Running_OK"; + } + return hmdHeight; +} + +void ReviveTabController::reloadControllerProfiles() +{ + controllerProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "reviveSettings" ); + auto profileCount = settings->beginReadArray( "controllerProfiles" ); + for ( int i = 0; i < profileCount; i++ ) + { + settings->setArrayIndex( i ); + controllerProfiles.emplace_back(); + auto& entry = controllerProfiles[i]; + entry.profileName + = settings->value( "profileName" ).toString().toStdString(); + entry.gripButtonMode = settings->value( "gripButtonMode", 0 ).toInt(); + entry.triggerAsGrip = settings->value( "triggerAsGrip", 0 ).toBool(); + entry.thumbDeadzone + = settings->value( "thumbDeadzone", 0.3f ).toFloat(); + entry.thumbRange = settings->value( "thumbRange", 2.0f ).toFloat(); + entry.touchPitch = settings->value( "touchPitch", -28.0f ).toFloat(); + entry.touchYaw = settings->value( "touchYaw", 0.0f ).toFloat(); + entry.touchRoll = settings->value( "touchRoll", -14.0f ).toFloat(); + entry.touchX = settings->value( "touchX", 0.016f ).toFloat(); + entry.touchY = settings->value( "touchY", 0.0f ).toFloat(); + entry.touchZ = settings->value( "touchZ", 0.016f ).toFloat(); + } + settings->endArray(); + settings->endGroup(); +} + +void ReviveTabController::saveControllerProfiles() +{ + auto settings = OverlayController::appSettings(); + settings->beginGroup( "reviveSettings" ); + settings->beginWriteArray( "controllerProfiles" ); + unsigned i = 0; + for ( auto& p : controllerProfiles ) + { + settings->setArrayIndex( i ); + settings->setValue( "profileName", + QString::fromStdString( p.profileName ) ); + settings->setValue( "gripButtonMode", p.gripButtonMode ); + settings->setValue( "triggerAsGrip", p.triggerAsGrip ); + settings->setValue( "thumbDeadzone", p.thumbDeadzone ); + settings->setValue( "thumbRange", p.thumbRange ); + settings->setValue( "touchPitch", p.touchPitch ); + settings->setValue( "touchYaw", p.touchYaw ); + settings->setValue( "touchRoll", p.touchRoll ); + settings->setValue( "touchX", p.touchX ); + settings->setValue( "touchY", p.touchY ); + settings->setValue( "touchZ", p.touchZ ); + i++; + } + settings->endArray(); + settings->endGroup(); +} + +Q_INVOKABLE unsigned ReviveTabController::getControllerProfileCount() +{ + return ( unsigned ) controllerProfiles.size(); +} + +Q_INVOKABLE QString + ReviveTabController::getControllerProfileName( unsigned index ) +{ + if ( index >= controllerProfiles.size() ) + { + return QString(); + } + else + { + return QString::fromStdString( controllerProfiles[index].profileName ); + } +} + +void ReviveTabController::addControllerProfile( QString name ) +{ + ReviveControllerProfile* profile = nullptr; + for ( auto& p : controllerProfiles ) + { + if ( p.profileName.compare( name.toStdString() ) == 0 ) + { + profile = &p; + break; + } + } + if ( !profile ) + { + auto i = controllerProfiles.size(); + controllerProfiles.emplace_back(); + profile = &controllerProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->gripButtonMode = gripButtonMode(); + profile->triggerAsGrip = triggerAsGrip(); + profile->thumbDeadzone = thumbDeadzone(); + profile->thumbRange = thumbRange(); + profile->touchPitch = touchPitch(); + profile->touchYaw = touchYaw(); + profile->touchRoll = touchRoll(); + profile->touchX = touchX(); + profile->touchY = touchY(); + profile->touchZ = touchZ(); + saveControllerProfiles(); + OverlayController::appSettings()->sync(); + emit controllerProfilesUpdated(); +} + +void ReviveTabController::applyControllerProfile( unsigned index ) +{ + if ( index < controllerProfiles.size() ) + { + auto& profile = controllerProfiles[index]; + setGripButtonMode( profile.gripButtonMode ); + setTriggerAsGrip( profile.triggerAsGrip ); + setThumbDeadzone( profile.thumbDeadzone ); + setThumbRange( profile.thumbRange ); + setTouchPitch( profile.touchPitch ); + setTouchYaw( profile.touchYaw ); + setTouchRoll( profile.touchRoll ); + setTouchX( profile.touchX ); + setTouchY( profile.touchY ); + setTouchZ( profile.touchZ ); + } +} + +void ReviveTabController::deleteControllerProfile( unsigned index ) +{ + if ( index < controllerProfiles.size() ) + { + auto pos = controllerProfiles.begin() + index; + controllerProfiles.erase( pos ); + saveControllerProfiles(); + OverlayController::appSettings()->sync(); + emit controllerProfilesUpdated(); + } +} + +} // namespace advsettings diff --git a/src/tabcontrollers/ReviveTabController.h b/src/tabcontrollers/ReviveTabController.h index 7f4b3ff..0530e84 100644 --- a/src/tabcontrollers/ReviveTabController.h +++ b/src/tabcontrollers/ReviveTabController.h @@ -5,174 +5,196 @@ class QQuickWindow; // application namespace -namespace advsettings { +namespace advsettings +{ +// forward declaration +class OverlayController; +struct ReviveControllerProfile +{ + std::string profileName; + int gripButtonMode; + bool triggerAsGrip; + float thumbDeadzone; + float thumbRange; + float touchPitch; + float touchYaw; + float touchRoll; + float touchX; + float touchY; + float touchZ; +}; - // forward declaration - class OverlayController; +class ReviveTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( int isOverlayInstalled READ isOverlayInstalled NOTIFY + isOverlayInstalledChanged ) + Q_PROPERTY( int gripButtonMode READ gripButtonMode WRITE setGripButtonMode + NOTIFY gripButtonModeChanged ) + Q_PROPERTY( int triggerAsGrip READ triggerAsGrip WRITE setTriggerAsGrip + NOTIFY triggerAsGripChanged ) + Q_PROPERTY( bool pixelsPerDisplayPixelOverrideEnabled READ + isPixelsPerDisplayPixelOverrideEnabled WRITE + setPixelsPerDisplayPixelOverrideEnabled NOTIFY + pixelsPerDisplayPixelOverrideEnabledChanged ) + Q_PROPERTY( float toggleDelay READ toggleDelay WRITE setToggleDelay NOTIFY + toggleDelayChanged ) + Q_PROPERTY( + float pixelsPerDisplayPixelOverride READ pixelsPerDisplayPixelOverride + WRITE setPixelsPerDisplayPixelOverride NOTIFY + pixelsPerDisplayPixelOverrideChanged ) + Q_PROPERTY( float thumbDeadzone READ thumbDeadzone WRITE setThumbDeadzone + NOTIFY thumbDeadzoneChanged ) + Q_PROPERTY( float thumbRange READ thumbRange WRITE setThumbRange NOTIFY + thumbRangeChanged ) + Q_PROPERTY( float touchPitch READ touchPitch WRITE setTouchPitch NOTIFY + touchPitchChanged ) + Q_PROPERTY( + float touchYaw READ touchYaw WRITE setTouchYaw NOTIFY touchYawChanged ) + Q_PROPERTY( float touchRoll READ touchRoll WRITE setTouchRoll NOTIFY + touchRollChanged ) + Q_PROPERTY( float touchX READ touchX WRITE setTouchX NOTIFY touchXChanged ) + Q_PROPERTY( float touchY READ touchY WRITE setTouchY NOTIFY touchYChanged ) + Q_PROPERTY( float touchZ READ touchZ WRITE setTouchZ NOTIFY touchZChanged ) + Q_PROPERTY( float piPlayerHeight READ piPlayerHeight WRITE setPiPlayerHeight + NOTIFY piPlayerHeightChanged ) + Q_PROPERTY( float piEyeHeight READ piEyeHeight WRITE setPiEyeHeight NOTIFY + piEyeHeightChanged ) + Q_PROPERTY( QString piUsername READ piUsername WRITE setPiUsername NOTIFY + piUsernameChanged ) + Q_PROPERTY( + QString piName READ piName WRITE setPiName NOTIFY piNameChanged ) + Q_PROPERTY( + int piGender READ piGender WRITE setPiGender NOTIFY piGenderChanged ) +private: + OverlayController* parent; + QQuickWindow* widget; - struct ReviveControllerProfile { - std::string profileName; - int gripButtonMode; - bool triggerAsGrip; - float thumbDeadzone; - float thumbRange; - float touchPitch; - float touchYaw; - float touchRoll; - float touchX; - float touchY; - float touchZ; - }; + bool m_isOverlayInstalled = false; + int m_gripButtonMode = 0; + float m_toggleDelay = 0.5f; + bool m_triggerAsGrip = false; + bool m_pixelsPerDisplayPixelOverrideEnabled = false; + float m_pixelsPerDisplayPixelOverride = 1.0f; + float m_thumbDeadzone = 0.3f; + float m_thumbRange = 2.0f; + float m_touchPitch = -28.0f; + float m_touchYaw = 0.0f; + float m_touchRoll = -14.0f; + float m_touchX = 0.016f; + float m_touchY = -0.036f; + float m_touchZ = 0.016f; + float m_piPlayerHeight = 1.778f; + float m_piEyeHeight = 1.675f; + QString m_piUsername = ""; + QString m_piName = ""; + int m_piGender = 0; // 0 .. Unknown, 1 .. Male, 2 .. Female + unsigned settingsUpdateCounter = 0; - class ReviveTabController : public QObject { - Q_OBJECT - Q_PROPERTY(int isOverlayInstalled READ isOverlayInstalled NOTIFY isOverlayInstalledChanged) - Q_PROPERTY(int gripButtonMode READ gripButtonMode WRITE setGripButtonMode NOTIFY gripButtonModeChanged) - Q_PROPERTY(int triggerAsGrip READ triggerAsGrip WRITE setTriggerAsGrip NOTIFY triggerAsGripChanged) - Q_PROPERTY(bool pixelsPerDisplayPixelOverrideEnabled READ isPixelsPerDisplayPixelOverrideEnabled WRITE setPixelsPerDisplayPixelOverrideEnabled NOTIFY pixelsPerDisplayPixelOverrideEnabledChanged) - Q_PROPERTY(float toggleDelay READ toggleDelay WRITE setToggleDelay NOTIFY toggleDelayChanged) - Q_PROPERTY(float pixelsPerDisplayPixelOverride READ pixelsPerDisplayPixelOverride WRITE setPixelsPerDisplayPixelOverride NOTIFY pixelsPerDisplayPixelOverrideChanged) - Q_PROPERTY(float thumbDeadzone READ thumbDeadzone WRITE setThumbDeadzone NOTIFY thumbDeadzoneChanged) - Q_PROPERTY(float thumbRange READ thumbRange WRITE setThumbRange NOTIFY thumbRangeChanged) - Q_PROPERTY(float touchPitch READ touchPitch WRITE setTouchPitch NOTIFY touchPitchChanged) - Q_PROPERTY(float touchYaw READ touchYaw WRITE setTouchYaw NOTIFY touchYawChanged) - Q_PROPERTY(float touchRoll READ touchRoll WRITE setTouchRoll NOTIFY touchRollChanged) - Q_PROPERTY(float touchX READ touchX WRITE setTouchX NOTIFY touchXChanged) - Q_PROPERTY(float touchY READ touchY WRITE setTouchY NOTIFY touchYChanged) - Q_PROPERTY(float touchZ READ touchZ WRITE setTouchZ NOTIFY touchZChanged) - Q_PROPERTY(float piPlayerHeight READ piPlayerHeight WRITE setPiPlayerHeight NOTIFY piPlayerHeightChanged) - Q_PROPERTY(float piEyeHeight READ piEyeHeight WRITE setPiEyeHeight NOTIFY piEyeHeightChanged) - Q_PROPERTY(QString piUsername READ piUsername WRITE setPiUsername NOTIFY piUsernameChanged) - Q_PROPERTY(QString piName READ piName WRITE setPiName NOTIFY piNameChanged) - Q_PROPERTY(int piGender READ piGender WRITE setPiGender NOTIFY piGenderChanged) + std::vector controllerProfiles; - private: - OverlayController* parent; - QQuickWindow* widget; +public: + void initStage1( bool forceRevivePage ); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - bool m_isOverlayInstalled = false; - int m_gripButtonMode = 0; - float m_toggleDelay = 0.5f; - bool m_triggerAsGrip = false; - bool m_pixelsPerDisplayPixelOverrideEnabled = false; - float m_pixelsPerDisplayPixelOverride = 1.0f; - float m_thumbDeadzone = 0.3f; - float m_thumbRange = 2.0f; - float m_touchPitch = -28.0f; - float m_touchYaw = 0.0f; - float m_touchRoll = -14.0f; - float m_touchX = 0.016f; - float m_touchY = -0.036f; - float m_touchZ = 0.016f; - float m_piPlayerHeight = 1.778f; - float m_piEyeHeight = 1.675f; - QString m_piUsername = ""; - QString m_piName = ""; - int m_piGender = 0; // 0 .. Unknown, 1 .. Male, 2 .. Female + void eventLoopTick(); - unsigned settingsUpdateCounter = 0; + bool isOverlayInstalled() const; - std::vector controllerProfiles; + int gripButtonMode() const; + bool triggerAsGrip() const; + float toggleDelay() const; - public: - void initStage1(bool forceRevivePage); - void initStage2(OverlayController* parent, QQuickWindow* widget); + bool isPixelsPerDisplayPixelOverrideEnabled() const; + float pixelsPerDisplayPixelOverride() const; - void eventLoopTick(); + float thumbDeadzone() const; + float thumbRange() const; - bool isOverlayInstalled() const; + float touchPitch() const; + float touchYaw() const; + float touchRoll() const; + float touchX() const; + float touchY() const; + float touchZ() const; - int gripButtonMode() const; - bool triggerAsGrip() const; - float toggleDelay() const; + float piPlayerHeight() const; + float piEyeHeight() const; + const QString& piUsername() const; + const QString& piName() const; + int piGender() const; // 0 .. Unknown, 1 .. Male, 2 .. Female - bool isPixelsPerDisplayPixelOverrideEnabled() const; - float pixelsPerDisplayPixelOverride() const; + Q_INVOKABLE float getCurrentHMDHeight(); - float thumbDeadzone() const; - float thumbRange() const; + void reloadControllerProfiles(); + void saveControllerProfiles(); - float touchPitch() const; - float touchYaw() const; - float touchRoll() const; - float touchX() const; - float touchY() const; - float touchZ() const; + Q_INVOKABLE unsigned getControllerProfileCount(); + Q_INVOKABLE QString getControllerProfileName( unsigned index ); - float piPlayerHeight() const; - float piEyeHeight() const; - const QString& piUsername() const; - const QString& piName() const; - int piGender() const; // 0 .. Unknown, 1 .. Male, 2 .. Female +public slots: + void setGripButtonMode( int value, bool notify = true ); + void setTriggerAsGrip( bool value, bool notify = true ); + void setToggleDelay( float value, bool notify = true ); - Q_INVOKABLE float getCurrentHMDHeight(); + void setPixelsPerDisplayPixelOverrideEnabled( bool value, + bool notify = true ); + void setPixelsPerDisplayPixelOverride( float value, bool notify = true ); - void reloadControllerProfiles(); - void saveControllerProfiles(); + void setThumbDeadzone( float value, bool notify = true ); + void setThumbRange( float value, bool notify = true ); - Q_INVOKABLE unsigned getControllerProfileCount(); - Q_INVOKABLE QString getControllerProfileName(unsigned index); + void setTouchPitch( float value, bool notify = true ); + void setTouchYaw( float value, bool notify = true ); + void setTouchRoll( float value, bool notify = true ); + void setTouchX( float value, bool notify = true ); + void setTouchY( float value, bool notify = true ); + void setTouchZ( float value, bool notify = true ); - public slots: - void setGripButtonMode(int value, bool notify = true); - void setTriggerAsGrip(bool value, bool notify = true); - void setToggleDelay(float value, bool notify = true); + void setPiPlayerHeight( float value, bool notify = true ); + void setPiEyeHeight( float value, bool notify = true ); + void setPiUsername( const QString& value, bool notify = true ); + void setPiName( const QString& value, bool notify = true ); + void setPiGender( int value, + bool notify + = true ); // 0 .. Unknown, 1 .. Male, 2 .. Female - void setPixelsPerDisplayPixelOverrideEnabled(bool value, bool notify = true); - void setPixelsPerDisplayPixelOverride(float value, bool notify = true); + void addControllerProfile( QString name ); + void applyControllerProfile( unsigned index ); + void deleteControllerProfile( unsigned index ); - void setThumbDeadzone(float value, bool notify = true); - void setThumbRange(float value, bool notify = true); + void reset(); - void setTouchPitch(float value, bool notify = true); - void setTouchYaw(float value, bool notify = true); - void setTouchRoll(float value, bool notify = true); - void setTouchX(float value, bool notify = true); - void setTouchY(float value, bool notify = true); - void setTouchZ(float value, bool notify = true); +signals: + void isOverlayInstalledChanged( bool value ); - void setPiPlayerHeight(float value, bool notify = true); - void setPiEyeHeight(float value, bool notify = true); - void setPiUsername(const QString& value, bool notify = true); - void setPiName(const QString& value, bool notify = true); - void setPiGender(int value, bool notify = true); // 0 .. Unknown, 1 .. Male, 2 .. Female + void gripButtonModeChanged( int value ); + void triggerAsGripChanged( bool value ); + void toggleDelayChanged( float value ); - void addControllerProfile(QString name); - void applyControllerProfile(unsigned index); - void deleteControllerProfile(unsigned index); + void pixelsPerDisplayPixelOverrideEnabledChanged( bool value ); + void pixelsPerDisplayPixelOverrideChanged( float value ); - void reset(); + void thumbDeadzoneChanged( float value ); + void thumbRangeChanged( float value ); - signals: - void isOverlayInstalledChanged(bool value); + void touchPitchChanged( float value ); + void touchYawChanged( float value ); + void touchRollChanged( float value ); + void touchXChanged( float value ); + void touchYChanged( float value ); + void touchZChanged( float value ); - void gripButtonModeChanged(int value); - void triggerAsGripChanged(bool value); - void toggleDelayChanged(float value); + void piPlayerHeightChanged( float value ); + void piEyeHeightChanged( float value ); + void piUsernameChanged( const QString& value ); + void piNameChanged( const QString& value ); + void piGenderChanged( int value ); - void pixelsPerDisplayPixelOverrideEnabledChanged(bool value); - void pixelsPerDisplayPixelOverrideChanged(float value); - - void thumbDeadzoneChanged(float value); - void thumbRangeChanged(float value); - - void touchPitchChanged(float value); - void touchYawChanged(float value); - void touchRollChanged(float value); - void touchXChanged(float value); - void touchYChanged(float value); - void touchZChanged(float value); - - void piPlayerHeightChanged(float value); - void piEyeHeightChanged(float value); - void piUsernameChanged(const QString& value); - void piNameChanged(const QString& value); - void piGenderChanged(int value); - - void controllerProfilesUpdated(); - }; + void controllerProfilesUpdated(); +}; } // namespace advsettings diff --git a/src/tabcontrollers/SettingsTabController.cpp b/src/tabcontrollers/SettingsTabController.cpp index ae747c5..ca9f701 100644 --- a/src/tabcontrollers/SettingsTabController.cpp +++ b/src/tabcontrollers/SettingsTabController.cpp @@ -3,69 +3,88 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { - - -void SettingsTabController::initStage1() { - m_autoStartEnabled = vr::VRApplications()->GetApplicationAutoLaunch(OverlayController::applicationKey); - auto settings = OverlayController::appSettings(); - settings->beginGroup("applicationSettings"); - auto value = settings->value("forceRevivePage", m_forceRevivePage); - settings->endGroup(); - if (value.isValid() && !value.isNull()) { - m_forceRevivePage = value.toBool(); - } +namespace advsettings +{ +void SettingsTabController::initStage1() +{ + m_autoStartEnabled = vr::VRApplications()->GetApplicationAutoLaunch( + OverlayController::applicationKey ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "applicationSettings" ); + auto value = settings->value( "forceRevivePage", m_forceRevivePage ); + settings->endGroup(); + if ( value.isValid() && !value.isNull() ) + { + m_forceRevivePage = value.toBool(); + } } -void SettingsTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void SettingsTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } -void SettingsTabController::eventLoopTick() { - if (settingsUpdateCounter >= 50) { - setAutoStartEnabled(vr::VRApplications()->GetApplicationAutoLaunch(OverlayController::applicationKey)); - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } +void SettingsTabController::eventLoopTick() +{ + if ( settingsUpdateCounter >= 50 ) + { + setAutoStartEnabled( vr::VRApplications()->GetApplicationAutoLaunch( + OverlayController::applicationKey ) ); + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + } } -bool SettingsTabController::autoStartEnabled() const { - return m_autoStartEnabled; +bool SettingsTabController::autoStartEnabled() const +{ + return m_autoStartEnabled; } -void SettingsTabController::setAutoStartEnabled(bool value, bool notify) { - if (m_autoStartEnabled != value) { - m_autoStartEnabled = value; - auto apperror = vr::VRApplications()->SetApplicationAutoLaunch(OverlayController::applicationKey, m_autoStartEnabled); - if (apperror != vr::VRApplicationError_None) { - LOG(ERROR) << "Could not set auto start: " << vr::VRApplications()->GetApplicationsErrorNameFromEnum(apperror); - } - if (notify) { - emit autoStartEnabledChanged(m_autoStartEnabled); - } - } +void SettingsTabController::setAutoStartEnabled( bool value, bool notify ) +{ + if ( m_autoStartEnabled != value ) + { + m_autoStartEnabled = value; + auto apperror = vr::VRApplications()->SetApplicationAutoLaunch( + OverlayController::applicationKey, m_autoStartEnabled ); + if ( apperror != vr::VRApplicationError_None ) + { + LOG( ERROR ) << "Could not set auto start: " + << vr::VRApplications() + ->GetApplicationsErrorNameFromEnum( apperror ); + } + if ( notify ) + { + emit autoStartEnabledChanged( m_autoStartEnabled ); + } + } } - -bool SettingsTabController::forceRevivePage() const { - return m_forceRevivePage; +bool SettingsTabController::forceRevivePage() const +{ + return m_forceRevivePage; } - -void SettingsTabController::setForceRevivePage(bool value, bool notify) { - if (m_forceRevivePage != value) { - m_forceRevivePage = value; - auto settings = OverlayController::appSettings(); - settings->beginGroup("applicationSettings"); - settings->setValue("forceRevivePage", m_forceRevivePage); - settings->endGroup(); - settings->sync(); - if (notify) { - emit forceRevivePageChanged(m_forceRevivePage); - } - } +void SettingsTabController::setForceRevivePage( bool value, bool notify ) +{ + if ( m_forceRevivePage != value ) + { + m_forceRevivePage = value; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "applicationSettings" ); + settings->setValue( "forceRevivePage", m_forceRevivePage ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit forceRevivePageChanged( m_forceRevivePage ); + } + } } -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/SettingsTabController.h b/src/tabcontrollers/SettingsTabController.h index c3f91d3..a67fc7d 100644 --- a/src/tabcontrollers/SettingsTabController.h +++ b/src/tabcontrollers/SettingsTabController.h @@ -5,42 +5,44 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; - -class SettingsTabController : public QObject { - Q_OBJECT - Q_PROPERTY(bool autoStartEnabled READ autoStartEnabled WRITE setAutoStartEnabled NOTIFY autoStartEnabledChanged) - Q_PROPERTY(bool forceRevivePage READ forceRevivePage WRITE setForceRevivePage NOTIFY forceRevivePageChanged) +class SettingsTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( bool autoStartEnabled READ autoStartEnabled WRITE + setAutoStartEnabled NOTIFY autoStartEnabledChanged ) + Q_PROPERTY( bool forceRevivePage READ forceRevivePage WRITE + setForceRevivePage NOTIFY forceRevivePageChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - unsigned settingsUpdateCounter = 0; + unsigned settingsUpdateCounter = 0; - bool m_autoStartEnabled = false; - bool m_forceRevivePage = false; + bool m_autoStartEnabled = false; + bool m_forceRevivePage = false; public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(); + void eventLoopTick(); - bool autoStartEnabled() const; - bool forceRevivePage() const; + bool autoStartEnabled() const; + bool forceRevivePage() const; public slots: - void setAutoStartEnabled(bool value, bool notify = true); - void setForceRevivePage(bool value, bool notify = true); + void setAutoStartEnabled( bool value, bool notify = true ); + void setForceRevivePage( bool value, bool notify = true ); signals: - void autoStartEnabledChanged(bool value); - void forceRevivePageChanged(bool value); + void autoStartEnabledChanged( bool value ); + void forceRevivePageChanged( bool value ); }; } // namespace advsettings diff --git a/src/tabcontrollers/StatisticsTabController.cpp b/src/tabcontrollers/StatisticsTabController.cpp index 6ee28d6..a0d3c9f 100644 --- a/src/tabcontrollers/StatisticsTabController.cpp +++ b/src/tabcontrollers/StatisticsTabController.cpp @@ -3,232 +3,319 @@ #include "../overlaycontroller.h" // application namespace -namespace advsettings { +namespace advsettings +{ +void StatisticsTabController::initStage1() {} -void StatisticsTabController::initStage1() { +void StatisticsTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } -void StatisticsTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void StatisticsTabController::eventLoopTick( + vr::TrackedDevicePose_t* devicePoses, + float leftSpeed, + float rightSpeed ) +{ + vr::Compositor_CumulativeStats pStats; + vr::VRCompositor()->GetCumulativeStats( + &pStats, sizeof( vr::Compositor_CumulativeStats ) ); + if ( pStats.m_nPid != m_cumStats.m_nPid ) + { + m_cumStats = pStats; + m_droppedFramesOffset = 0; + m_reprojectedFramesOffset = 0; + m_timedOutOffset = 0; + m_totalRatioPresentedOffset = 0; + m_totalRatioReprojectedOffset = 0; + } + m_cumStats = pStats; + + auto& m = devicePoses->mDeviceToAbsoluteTracking.m; + + // Hmd Distance // + if ( lastPosTimer == 0 ) + { + if ( devicePoses[0].bPoseIsValid + && devicePoses[0].eTrackingResult + == vr::TrackingResult_Running_OK ) + { + if ( !lastHmdPosValid ) + { + lastHmdPosValid = true; + } + else + { + auto delta = std::sqrt( + std::pow( m[0][3] - lastHmdPos[0], + 2 ) /*+ std::pow(m[1][3] - lastHmdPos[1], 2)*/ + + std::pow( m[2][3] - lastHmdPos[2], 2 ) ); + if ( delta >= 0.01f ) + { + m_hmdDistanceMoved += delta; + } + } + lastHmdPos[0] = m[0][3]; + lastHmdPos[1] = m[1][3]; + lastHmdPos[2] = m[2][3]; + } + else + { + lastHmdPosValid = false; + } + } + + // Controller speeds // + if ( leftSpeed > m_leftControllerMaxSpeed ) + { + m_leftControllerMaxSpeed = leftSpeed; + } + if ( rightSpeed > m_rightControllerMaxSpeed ) + { + m_rightControllerMaxSpeed = rightSpeed; + } + + // Hmd Rotation // + /* + | Intrinsic y-x'-z" rotation matrix: + | cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy | + | cp*sr | cp*cr |-sp | + | cy*sp*sr-cr*sy | cr*cy*sp+sr*sy | cp*cy | + + yaw = atan2(cp*sy, cp*cy) [pi, -pi], CCW + pitch = -asin(-sp) [pi/2, -pi/2] + roll = atan2(cp*sr, cp*cr) [pi, -pi], CW + */ + + double yawRaw = 0.0; + double yaw = 0.0; + bool rotationChanged = false; + if ( devicePoses[0].bPoseIsValid + && devicePoses[0].eTrackingResult == vr::TrackingResult_Running_OK ) + { + yawRaw = std::atan2( m[0][2], m[2][2] ); + if ( yawRaw < 0.0f ) + { + yawRaw += 2 * M_PI; // map to [0, 2*pi], CCW + } + yaw = yawRaw - rotationOffset; + if ( yaw < 0.0 ) + { + yaw = 2 * M_PI + yaw; + } + if ( rotationResetFlag ) + { + rotationDir = 0; + rotationCounter = 0; + rotationOffset = yawRaw; + rotationResetFlag = false; + lastYaw = -1.0f; + rotationChanged = true; + } + else if ( lastYaw < 0.0f && yaw > 0.0 ) + { + lastYaw = yaw; + rotationChanged = true; + if ( yaw <= M_PI ) + { + rotationDir = 1; + } + else + { + rotationDir = -1; + } + } + else if ( std::abs( lastYaw - yaw ) >= 0.01 && yaw > 0.0 ) + { + auto diff = yaw - lastYaw; + int mode = 0; + if ( std::abs( diff ) > M_PI ) + { + if ( diff < -M_PI ) + { // CCW overflow + mode = 1; + } + else if ( diff > M_PI ) + { // CW overflow + mode = -1; + } + } + else + { + if ( lastYaw < 0.0 && yaw > 0.0 ) + { + mode = 1; + } + else if ( lastYaw > 0.0 && yaw < 0.0 ) + { + mode = -1; + } + } + if ( mode > 0 ) + { + if ( rotationCounter == 0 && rotationDir <= 0 ) + { + rotationDir = 1; + } + else + { + rotationCounter++; + } + } + else if ( mode < 0 ) + { + if ( rotationCounter == 0 && rotationDir >= 0 ) + { + rotationDir = -1; + } + else + { + rotationCounter--; + } + } + lastYaw = yaw; + rotationChanged = true; + } + } + else + { + lastYaw = -1; + } + + if ( rotationChanged ) + { + m_hmdRotation = ( float ) rotationCounter; + if ( rotationDir > 0 ) + { + m_hmdRotation += yaw / ( 2 * M_PI ); + } + else if ( rotationDir < 0 ) + { + m_hmdRotation += -1.0f + yaw / ( 2 * M_PI ); + } + } + if ( lastPosTimer == 0 ) + { + lastPosTimer = 10; + } + else + { + lastPosTimer--; + } } -void StatisticsTabController::eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed) { - vr::Compositor_CumulativeStats pStats; - vr::VRCompositor()->GetCumulativeStats(&pStats, sizeof(vr::Compositor_CumulativeStats)); - if (pStats.m_nPid != m_cumStats.m_nPid) { - m_cumStats = pStats; - m_droppedFramesOffset = 0; - m_reprojectedFramesOffset = 0; - m_timedOutOffset = 0; - m_totalRatioPresentedOffset = 0; - m_totalRatioReprojectedOffset = 0; - } - m_cumStats = pStats; - - auto& m = devicePoses->mDeviceToAbsoluteTracking.m; - - // Hmd Distance // - if (lastPosTimer == 0) { - if (devicePoses[0].bPoseIsValid && devicePoses[0].eTrackingResult == vr::TrackingResult_Running_OK) { - if (!lastHmdPosValid) { - lastHmdPosValid = true; - } else { - auto delta = std::sqrt(std::pow(m[0][3] - lastHmdPos[0], 2) /*+ std::pow(m[1][3] - lastHmdPos[1], 2)*/ + std::pow(m[2][3] - lastHmdPos[2], 2)); - if (delta >= 0.01f) { - m_hmdDistanceMoved += delta; - } - } - lastHmdPos[0] = m[0][3]; - lastHmdPos[1] = m[1][3]; - lastHmdPos[2] = m[2][3]; - } else { - lastHmdPosValid = false; - } - } - - // Controller speeds // - if (leftSpeed > m_leftControllerMaxSpeed) { - m_leftControllerMaxSpeed = leftSpeed; - } - if (rightSpeed > m_rightControllerMaxSpeed) { - m_rightControllerMaxSpeed = rightSpeed; - } - - // Hmd Rotation // - /* - | Intrinsic y-x'-z" rotation matrix: - | cr*cy+sp*sr*sy | cr*sp*sy-cy*sr | cp*sy | - | cp*sr | cp*cr |-sp | - | cy*sp*sr-cr*sy | cr*cy*sp+sr*sy | cp*cy | - - yaw = atan2(cp*sy, cp*cy) [pi, -pi], CCW - pitch = -asin(-sp) [pi/2, -pi/2] - roll = atan2(cp*sr, cp*cr) [pi, -pi], CW - */ - - double yawRaw = 0.0; - double yaw = 0.0; - bool rotationChanged = false; - if (devicePoses[0].bPoseIsValid && devicePoses[0].eTrackingResult == vr::TrackingResult_Running_OK) { - yawRaw = std::atan2(m[0][2], m[2][2]); - if (yawRaw < 0.0f) { - yawRaw += 2 * M_PI; // map to [0, 2*pi], CCW - } - yaw = yawRaw - rotationOffset; - if (yaw < 0.0) { - yaw = 2 * M_PI + yaw; - } - if (rotationResetFlag) { - rotationDir = 0; - rotationCounter = 0; - rotationOffset = yawRaw; - rotationResetFlag = false; - lastYaw = -1.0f; - rotationChanged = true; - } else if (lastYaw < 0.0f && yaw > 0.0) { - lastYaw = yaw; - rotationChanged = true; - if (yaw <= M_PI) { - rotationDir = 1; - } else { - rotationDir = -1; - } - } else if (std::abs(lastYaw - yaw) >= 0.01 && yaw > 0.0) { - auto diff = yaw - lastYaw; - int mode = 0; - if (std::abs(diff) > M_PI) { - if (diff < -M_PI) { // CCW overflow - mode = 1; - } else if (diff > M_PI) { // CW overflow - mode = -1; - } - } else { - if (lastYaw < 0.0 && yaw > 0.0) { - mode = 1; - } else if (lastYaw > 0.0 && yaw < 0.0) { - mode = -1; - } - } - if (mode > 0) { - if (rotationCounter == 0 && rotationDir <= 0) { - rotationDir = 1; - } else { - rotationCounter++; - } - } else if (mode < 0) { - if (rotationCounter == 0 && rotationDir >= 0) { - rotationDir = -1; - } else { - rotationCounter--; - } - } - lastYaw = yaw; - rotationChanged = true; - } - } else { - lastYaw = -1; - } - - if (rotationChanged) { - m_hmdRotation = (float)rotationCounter; - if (rotationDir > 0) { - m_hmdRotation += yaw / (2 * M_PI); - } else if (rotationDir < 0) { - m_hmdRotation += -1.0f + yaw / (2 * M_PI); - } - } - if (lastPosTimer == 0) { - lastPosTimer = 10; - } else { - lastPosTimer--; - } +float StatisticsTabController::hmdDistanceMoved() const +{ + return m_hmdDistanceMoved; } -float StatisticsTabController::hmdDistanceMoved() const { - return m_hmdDistanceMoved; +float StatisticsTabController::hmdRotations() const +{ + return m_hmdRotation; } -float StatisticsTabController::hmdRotations() const { - return m_hmdRotation; +float StatisticsTabController::rightControllerMaxSpeed() const +{ + return m_rightControllerMaxSpeed; } -float StatisticsTabController::rightControllerMaxSpeed() const { - return m_rightControllerMaxSpeed; +float StatisticsTabController::leftControllerMaxSpeed() const +{ + return m_leftControllerMaxSpeed; } -float StatisticsTabController::leftControllerMaxSpeed() const { - return m_leftControllerMaxSpeed; +unsigned StatisticsTabController::presentedFrames() const +{ + return m_cumStats.m_nNumFramePresents - m_presentedFramesOffset; } -unsigned StatisticsTabController::presentedFrames() const { - return m_cumStats.m_nNumFramePresents - m_presentedFramesOffset; +unsigned StatisticsTabController::droppedFrames() const +{ + return m_cumStats.m_nNumDroppedFrames - m_droppedFramesOffset; } -unsigned StatisticsTabController::droppedFrames() const { - return m_cumStats.m_nNumDroppedFrames - m_droppedFramesOffset; +unsigned StatisticsTabController::reprojectedFrames() const +{ + return m_cumStats.m_nNumReprojectedFrames - m_reprojectedFramesOffset; } -unsigned StatisticsTabController::reprojectedFrames() const { - return m_cumStats.m_nNumReprojectedFrames - m_reprojectedFramesOffset; +unsigned StatisticsTabController::timedOut() const +{ + return m_cumStats.m_nNumTimedOut - m_timedOutOffset; } -unsigned StatisticsTabController::timedOut() const { - return m_cumStats.m_nNumTimedOut - m_timedOutOffset; +float StatisticsTabController::totalReprojectedRatio() const +{ + float totalFrames = ( float ) ( m_cumStats.m_nNumFramePresents + - m_totalRatioPresentedOffset ); + float reprojectedFrames = ( float ) ( m_cumStats.m_nNumReprojectedFrames + - m_totalRatioReprojectedOffset ); + if ( totalFrames != 0.0f ) + { + return reprojectedFrames / totalFrames; + } + else + { + return 0.0; + } } -float StatisticsTabController::totalReprojectedRatio() const { - float totalFrames = (float)(m_cumStats.m_nNumFramePresents - m_totalRatioPresentedOffset); - float reprojectedFrames = (float)(m_cumStats.m_nNumReprojectedFrames - m_totalRatioReprojectedOffset); - if (totalFrames != 0.0f) { - return reprojectedFrames / totalFrames; - } else { - return 0.0; - } +void StatisticsTabController::statsDistanceResetClicked() +{ + lastHmdPosValid = false; + if ( m_hmdDistanceMoved != 0.0 ) + { + m_hmdDistanceMoved = 0.0; + } } -void StatisticsTabController::statsDistanceResetClicked() { - lastHmdPosValid = false; - if (m_hmdDistanceMoved != 0.0) { - m_hmdDistanceMoved = 0.0; - } +void StatisticsTabController::statsRotationResetClicked() +{ + rotationResetFlag = true; } -void StatisticsTabController::statsRotationResetClicked() { - rotationResetFlag = true; +void StatisticsTabController::statsLeftControllerSpeedResetClicked() +{ + if ( m_leftControllerMaxSpeed != 0.0 ) + { + m_leftControllerMaxSpeed = 0.0; + } } -void StatisticsTabController::statsLeftControllerSpeedResetClicked() { - if (m_leftControllerMaxSpeed != 0.0) { - m_leftControllerMaxSpeed = 0.0; - } +void StatisticsTabController::statsRightControllerSpeedResetClicked() +{ + if ( m_rightControllerMaxSpeed != 0.0 ) + { + m_rightControllerMaxSpeed = 0.0; + } } -void StatisticsTabController::statsRightControllerSpeedResetClicked() { - if (m_rightControllerMaxSpeed != 0.0) { - m_rightControllerMaxSpeed = 0.0; - } +void StatisticsTabController::presentedFramesResetClicked() +{ + m_presentedFramesOffset = m_cumStats.m_nNumFramePresents; } -void StatisticsTabController::presentedFramesResetClicked() { - m_presentedFramesOffset = m_cumStats.m_nNumFramePresents; +void StatisticsTabController::droppedFramesResetClicked() +{ + m_droppedFramesOffset = m_cumStats.m_nNumDroppedFrames; } -void StatisticsTabController::droppedFramesResetClicked() { - m_droppedFramesOffset = m_cumStats.m_nNumDroppedFrames; +void StatisticsTabController::reprojectedFramesResetClicked() +{ + m_reprojectedFramesOffset = m_cumStats.m_nNumReprojectedFrames; } -void StatisticsTabController::reprojectedFramesResetClicked() { - m_reprojectedFramesOffset = m_cumStats.m_nNumReprojectedFrames; +void StatisticsTabController::timedOutResetClicked() +{ + m_timedOutOffset = m_cumStats.m_nNumTimedOut; } -void StatisticsTabController::timedOutResetClicked() { - m_timedOutOffset = m_cumStats.m_nNumTimedOut; +void StatisticsTabController::totalRatioResetClicked() +{ + m_totalRatioPresentedOffset = m_cumStats.m_nNumFramePresents; + m_totalRatioReprojectedOffset = m_cumStats.m_nNumReprojectedFrames; } -void StatisticsTabController::totalRatioResetClicked() { - m_totalRatioPresentedOffset = m_cumStats.m_nNumFramePresents; - m_totalRatioReprojectedOffset = m_cumStats.m_nNumReprojectedFrames; -} - -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/StatisticsTabController.h b/src/tabcontrollers/StatisticsTabController.h index 48f698a..b2d9872 100644 --- a/src/tabcontrollers/StatisticsTabController.h +++ b/src/tabcontrollers/StatisticsTabController.h @@ -6,79 +6,80 @@ class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; - -class StatisticsTabController : public QObject { - Q_OBJECT - Q_PROPERTY(float hmdDistanceMoved READ hmdDistanceMoved) - Q_PROPERTY(float hmdRotations READ hmdRotations) - Q_PROPERTY(float leftControllerMaxSpeed READ leftControllerMaxSpeed) - Q_PROPERTY(float rightControllerMaxSpeed READ rightControllerMaxSpeed) - Q_PROPERTY(int presentedFrames READ presentedFrames) - Q_PROPERTY(int droppedFrames READ droppedFrames) - Q_PROPERTY(int reprojectedFrames READ reprojectedFrames) - Q_PROPERTY(int timedOut READ timedOut) - Q_PROPERTY(float totalReprojectedRatio READ totalReprojectedRatio) +class StatisticsTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( float hmdDistanceMoved READ hmdDistanceMoved ) + Q_PROPERTY( float hmdRotations READ hmdRotations ) + Q_PROPERTY( float leftControllerMaxSpeed READ leftControllerMaxSpeed ) + Q_PROPERTY( float rightControllerMaxSpeed READ rightControllerMaxSpeed ) + Q_PROPERTY( int presentedFrames READ presentedFrames ) + Q_PROPERTY( int droppedFrames READ droppedFrames ) + Q_PROPERTY( int reprojectedFrames READ reprojectedFrames ) + Q_PROPERTY( int timedOut READ timedOut ) + Q_PROPERTY( float totalReprojectedRatio READ totalReprojectedRatio ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - bool rotationResetFlag = false; - float rotationOffset = 0.0f; - int rotationDir = 0; - int64_t rotationCounter = 0; - float lastYaw = -1.0f; - unsigned lastPosTimer = 0; - float lastHmdPos[3]; - bool lastHmdPosValid = false; + bool rotationResetFlag = false; + float rotationOffset = 0.0f; + int rotationDir = 0; + int64_t rotationCounter = 0; + float lastYaw = -1.0f; + unsigned lastPosTimer = 0; + float lastHmdPos[3]; + bool lastHmdPosValid = false; - float m_hmdRotation = 0.0f; - double m_hmdDistanceMoved = 0.0; + float m_hmdRotation = 0.0f; + double m_hmdDistanceMoved = 0.0; - float m_leftControllerMaxSpeed = 0.0f; - float m_rightControllerMaxSpeed = 0.0f; + float m_leftControllerMaxSpeed = 0.0f; + float m_rightControllerMaxSpeed = 0.0f; - vr::Compositor_CumulativeStats m_cumStats; - unsigned m_presentedFramesOffset = 0; - unsigned m_droppedFramesOffset = 0; - unsigned m_reprojectedFramesOffset = 0; - unsigned m_timedOutOffset = 0; - unsigned m_totalRatioPresentedOffset = 0; - unsigned m_totalRatioReprojectedOffset = 0; + vr::Compositor_CumulativeStats m_cumStats; + unsigned m_presentedFramesOffset = 0; + unsigned m_droppedFramesOffset = 0; + unsigned m_reprojectedFramesOffset = 0; + unsigned m_timedOutOffset = 0; + unsigned m_totalRatioPresentedOffset = 0; + unsigned m_totalRatioReprojectedOffset = 0; public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(vr::TrackedDevicePose_t* devicePoses, float leftSpeed, float rightSpeed); + void eventLoopTick( vr::TrackedDevicePose_t* devicePoses, + float leftSpeed, + float rightSpeed ); - float hmdDistanceMoved() const; - float hmdRotations() const; - float rightControllerMaxSpeed() const; - float leftControllerMaxSpeed() const; + float hmdDistanceMoved() const; + float hmdRotations() const; + float rightControllerMaxSpeed() const; + float leftControllerMaxSpeed() const; - unsigned presentedFrames() const; - unsigned droppedFrames() const; - unsigned reprojectedFrames() const; - unsigned timedOut() const; - float totalReprojectedRatio() const; + unsigned presentedFrames() const; + unsigned droppedFrames() const; + unsigned reprojectedFrames() const; + unsigned timedOut() const; + float totalReprojectedRatio() const; public slots: - void statsDistanceResetClicked(); - void statsRotationResetClicked(); - void statsLeftControllerSpeedResetClicked(); - void statsRightControllerSpeedResetClicked(); - void presentedFramesResetClicked(); - void droppedFramesResetClicked(); - void reprojectedFramesResetClicked(); - void timedOutResetClicked(); - void totalRatioResetClicked(); + void statsDistanceResetClicked(); + void statsRotationResetClicked(); + void statsLeftControllerSpeedResetClicked(); + void statsRightControllerSpeedResetClicked(); + void presentedFramesResetClicked(); + void droppedFramesResetClicked(); + void reprojectedFramesResetClicked(); + void timedOutResetClicked(); + void totalRatioResetClicked(); }; - } // namespace advsettings diff --git a/src/tabcontrollers/SteamVRTabController.cpp b/src/tabcontrollers/SteamVRTabController.cpp index d3cfaba..d13e198 100644 --- a/src/tabcontrollers/SteamVRTabController.cpp +++ b/src/tabcontrollers/SteamVRTabController.cpp @@ -2,386 +2,588 @@ #include #include "../overlaycontroller.h" -namespace vr { - // this was removed from openvr_api.h in 1.0.8 - static const char* const k_pch_SteamVR_RenderTargetMultiplier_Float = "renderTargetMultiplier"; -} +namespace vr +{ +// this was removed from openvr_api.h in 1.0.8 +static const char* const k_pch_SteamVR_RenderTargetMultiplier_Float + = "renderTargetMultiplier"; +} // namespace vr // application namespace -namespace advsettings { - -// openvr's github repo hasn't been updated yet to reflect changes in beta 1477423729. -//static const char* vrsettings_steamvr_allowAsyncReprojection = "allowAsyncReprojection"; -//static const char* vrsettings_steamvr_allowInterleavedReprojection = "allowInterleavedReprojection"; +namespace advsettings +{ +// openvr's github repo hasn't been updated yet to reflect changes in beta +// 1477423729. +// static const char* vrsettings_steamvr_allowAsyncReprojection = +// "allowAsyncReprojection"; static const char* +// vrsettings_steamvr_allowInterleavedReprojection = +// "allowInterleavedReprojection"; static const char* vrsettings_steamvr_supersampleScale = "supersampleScale"; -static const char* vrsettings_steamvr_allowSupersampleFiltering = "allowSupersampleFiltering"; +static const char* vrsettings_steamvr_allowSupersampleFiltering + = "allowSupersampleFiltering"; static const char* vrsettings_compositor_category = "compositor"; -void SteamVRTabController::initStage1() { - eventLoopTick(); - reloadSteamVRProfiles(); +void SteamVRTabController::initStage1() +{ + eventLoopTick(); + reloadSteamVRProfiles(); } - -void SteamVRTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; +void SteamVRTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; } - -void SteamVRTabController::reloadSteamVRProfiles() { - steamvrProfiles.clear(); - auto settings = OverlayController::appSettings(); - settings->beginGroup("steamVRSettings"); - auto profileCount = settings->beginReadArray("steamVRProfiles"); - for (int i = 0; i < profileCount; i++) { - settings->setArrayIndex(i); - steamvrProfiles.emplace_back(); - auto& entry = steamvrProfiles[i]; - entry.profileName = settings->value("profileName").toString().toStdString(); - entry.includesSupersampling = settings->value("includesSupersampling", false).toBool(); - if (entry.includesSupersampling) { - entry.supersampling = settings->value("supersampling", 1.0f).toFloat(); - } - entry.includesSupersampleFiltering = settings->value("includesSupersampleFiltering", false).toBool(); - if (entry.includesSupersampleFiltering) { - entry.supersampleFiltering = settings->value("supersampleFiltering", true).toBool(); - } - entry.includesReprojectionSettings = settings->value("includesReprojectionSettings", false).toBool(); - if (entry.includesReprojectionSettings) { - entry.asynchronousReprojection = settings->value("asynchronousReprojection", true).toBool(); - entry.interleavedReprojection = settings->value("interleavedReprojection", true).toBool(); - entry.alwaysOnReprojection = settings->value("alwaysOnReprojection", true).toBool(); - } - } - settings->endArray(); - settings->endGroup(); +void SteamVRTabController::reloadSteamVRProfiles() +{ + steamvrProfiles.clear(); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "steamVRSettings" ); + auto profileCount = settings->beginReadArray( "steamVRProfiles" ); + for ( int i = 0; i < profileCount; i++ ) + { + settings->setArrayIndex( i ); + steamvrProfiles.emplace_back(); + auto& entry = steamvrProfiles[i]; + entry.profileName + = settings->value( "profileName" ).toString().toStdString(); + entry.includesSupersampling + = settings->value( "includesSupersampling", false ).toBool(); + if ( entry.includesSupersampling ) + { + entry.supersampling + = settings->value( "supersampling", 1.0f ).toFloat(); + } + entry.includesSupersampleFiltering + = settings->value( "includesSupersampleFiltering", false ).toBool(); + if ( entry.includesSupersampleFiltering ) + { + entry.supersampleFiltering + = settings->value( "supersampleFiltering", true ).toBool(); + } + entry.includesReprojectionSettings + = settings->value( "includesReprojectionSettings", false ).toBool(); + if ( entry.includesReprojectionSettings ) + { + entry.asynchronousReprojection + = settings->value( "asynchronousReprojection", true ).toBool(); + entry.interleavedReprojection + = settings->value( "interleavedReprojection", true ).toBool(); + entry.alwaysOnReprojection + = settings->value( "alwaysOnReprojection", true ).toBool(); + } + } + settings->endArray(); + settings->endGroup(); } - -void SteamVRTabController::saveSteamVRProfiles() { - auto settings = OverlayController::appSettings(); - settings->beginGroup("steamVRSettings"); - settings->beginWriteArray("steamVRProfiles"); - unsigned i = 0; - for (auto& p : steamvrProfiles) { - settings->setArrayIndex(i); - settings->setValue("profileName", QString::fromStdString(p.profileName)); - settings->setValue("includesSupersampling", p.includesSupersampling); - if (p.includesSupersampling) { - settings->setValue("supersampling", p.supersampling); - } - settings->setValue("includesSupersampleFiltering", p.includesSupersampleFiltering); - if (p.includesSupersampleFiltering) { - settings->setValue("supersampleFiltering", p.supersampleFiltering); - } - settings->setValue("includesReprojectionSettings", p.includesReprojectionSettings); - if (p.includesReprojectionSettings) { - settings->setValue("asynchronousReprojection", p.asynchronousReprojection); - settings->setValue("interleavedReprojection", p.interleavedReprojection); - settings->setValue("alwaysOnReprojection", p.alwaysOnReprojection); - } - i++; - } - settings->endArray(); - settings->endGroup(); - +void SteamVRTabController::saveSteamVRProfiles() +{ + auto settings = OverlayController::appSettings(); + settings->beginGroup( "steamVRSettings" ); + settings->beginWriteArray( "steamVRProfiles" ); + unsigned i = 0; + for ( auto& p : steamvrProfiles ) + { + settings->setArrayIndex( i ); + settings->setValue( "profileName", + QString::fromStdString( p.profileName ) ); + settings->setValue( "includesSupersampling", p.includesSupersampling ); + if ( p.includesSupersampling ) + { + settings->setValue( "supersampling", p.supersampling ); + } + settings->setValue( "includesSupersampleFiltering", + p.includesSupersampleFiltering ); + if ( p.includesSupersampleFiltering ) + { + settings->setValue( "supersampleFiltering", + p.supersampleFiltering ); + } + settings->setValue( "includesReprojectionSettings", + p.includesReprojectionSettings ); + if ( p.includesReprojectionSettings ) + { + settings->setValue( "asynchronousReprojection", + p.asynchronousReprojection ); + settings->setValue( "interleavedReprojection", + p.interleavedReprojection ); + settings->setValue( "alwaysOnReprojection", + p.alwaysOnReprojection ); + } + i++; + } + settings->endArray(); + settings->endGroup(); } - -Q_INVOKABLE unsigned SteamVRTabController::getSteamVRProfileCount() { - return (unsigned)steamvrProfiles.size(); +Q_INVOKABLE unsigned SteamVRTabController::getSteamVRProfileCount() +{ + return ( unsigned ) steamvrProfiles.size(); } -Q_INVOKABLE QString SteamVRTabController::getSteamVRProfileName(unsigned index) { - if (index >= steamvrProfiles.size()) { - return QString(); - } else { - return QString::fromStdString(steamvrProfiles[index].profileName); - } +Q_INVOKABLE QString + SteamVRTabController::getSteamVRProfileName( unsigned index ) +{ + if ( index >= steamvrProfiles.size() ) + { + return QString(); + } + else + { + return QString::fromStdString( steamvrProfiles[index].profileName ); + } } - -void SteamVRTabController::eventLoopTick() { - if (settingsUpdateCounter >= 50) { - vr::EVRSettingsError vrSettingsError; - auto ss = vr::VRSettings()->GetFloat(vr::k_pch_SteamVR_Section, vrsettings_steamvr_supersampleScale, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vrsettings_steamvr_supersampleScale << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - if (m_superSampling != 1.0) { - LOG(DEBUG) << "OpenVR returns an error and we have a custom supersampling value: " << m_superSampling; - setSuperSampling(1.0); - } - } else if (m_superSampling != ss) { - LOG(DEBUG) << "OpenVR reports a changed supersampling value: " << m_superSampling << " => " << ss; - setSuperSampling(ss); - } - auto css = vr::VRSettings()->GetFloat(vrsettings_compositor_category, vr::k_pch_SteamVR_RenderTargetMultiplier_Float, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - if (vrSettingsError != vr::VRSettingsError_UnsetSettingHasNoDefault) { // does not appear in the default settings file as of beta 1477423729 - LOG(WARNING) << "Could not read \"compositor::" << vr::k_pch_SteamVR_RenderTargetMultiplier_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - if (m_compositorSuperSampling != 1.0) { - LOG(DEBUG) << "OpenVR returns an error and we have a custom compositor supersampling value: " << m_compositorSuperSampling; - setCompositorSuperSampling(1.0); - } - } else if (m_compositorSuperSampling != css) { - LOG(DEBUG) << "OpenVR reports a changed compositor supersampling value: " << m_compositorSuperSampling << " => " << css; - setCompositorSuperSampling(css); - } - auto air = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_SteamVR_AllowReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setAllowInterleavedReprojection(air); - auto aar = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_SteamVR_AllowAsyncReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setAllowAsyncReprojection(aar); - auto fr = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ForceReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vr::k_pch_SteamVR_ForceReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setForceReprojection(fr); - auto sf = vr::VRSettings()->GetBool(vr::k_pch_SteamVR_Section, vrsettings_steamvr_allowSupersampleFiltering, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not read \"" << vrsettings_steamvr_allowSupersampleFiltering << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - setAllowSupersampleFiltering(sf); - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } +void SteamVRTabController::eventLoopTick() +{ + if ( settingsUpdateCounter >= 50 ) + { + vr::EVRSettingsError vrSettingsError; + auto ss + = vr::VRSettings()->GetFloat( vr::k_pch_SteamVR_Section, + vrsettings_steamvr_supersampleScale, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vrsettings_steamvr_supersampleScale + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + if ( m_superSampling != 1.0 ) + { + LOG( DEBUG ) << "OpenVR returns an error and we have a custom " + "supersampling value: " + << m_superSampling; + setSuperSampling( 1.0 ); + } + } + else if ( m_superSampling != ss ) + { + LOG( DEBUG ) << "OpenVR reports a changed supersampling value: " + << m_superSampling << " => " << ss; + setSuperSampling( ss ); + } + auto css = vr::VRSettings()->GetFloat( + vrsettings_compositor_category, + vr::k_pch_SteamVR_RenderTargetMultiplier_Float, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + if ( vrSettingsError + != vr::VRSettingsError_UnsetSettingHasNoDefault ) + { // does not appear in the default settings file as of beta + // 1477423729 + LOG( WARNING ) + << "Could not read \"compositor::" + << vr::k_pch_SteamVR_RenderTargetMultiplier_Float + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + if ( m_compositorSuperSampling != 1.0 ) + { + LOG( DEBUG ) << "OpenVR returns an error and we have a custom " + "compositor supersampling value: " + << m_compositorSuperSampling; + setCompositorSuperSampling( 1.0 ); + } + } + else if ( m_compositorSuperSampling != css ) + { + LOG( DEBUG ) + << "OpenVR reports a changed compositor supersampling value: " + << m_compositorSuperSampling << " => " << css; + setCompositorSuperSampling( css ); + } + auto air = vr::VRSettings()->GetBool( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_SteamVR_AllowReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setAllowInterleavedReprojection( air ); + auto aar = vr::VRSettings()->GetBool( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_SteamVR_AllowAsyncReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setAllowAsyncReprojection( aar ); + auto fr = vr::VRSettings()->GetBool( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_ForceReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vr::k_pch_SteamVR_ForceReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setForceReprojection( fr ); + auto sf = vr::VRSettings()->GetBool( + vr::k_pch_SteamVR_Section, + vrsettings_steamvr_allowSupersampleFiltering, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not read \"" + << vrsettings_steamvr_allowSupersampleFiltering + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } + setAllowSupersampleFiltering( sf ); + settingsUpdateCounter = 0; + } + else + { + settingsUpdateCounter++; + } } - -void SteamVRTabController::setSuperSampling(float value, bool notify) { - bool override = false; - if (value <= 0.01f) { - LOG(WARNING) << "Encountered a supersampling value <= 0.01, setting supersampling to 1.0"; - value = 1.0f; - override = true; - } - if (override || m_superSampling != value) { - LOG(DEBUG) << "Supersampling value changed: " << m_superSampling << " => " << value; - m_superSampling = value; - vr::VRSettings()->SetFloat(vr::k_pch_SteamVR_Section, vrsettings_steamvr_supersampleScale, m_superSampling); - vr::VRSettings()->Sync(); - if (notify) { - emit superSamplingChanged(m_superSampling); - } - } +void SteamVRTabController::setSuperSampling( float value, bool notify ) +{ + bool override = false; + if ( value <= 0.01f ) + { + LOG( WARNING ) << "Encountered a supersampling value <= 0.01, setting " + "supersampling to 1.0"; + value = 1.0f; + override = true; + } + if ( override || m_superSampling != value ) + { + LOG( DEBUG ) << "Supersampling value changed: " << m_superSampling + << " => " << value; + m_superSampling = value; + vr::VRSettings()->SetFloat( vr::k_pch_SteamVR_Section, + vrsettings_steamvr_supersampleScale, + m_superSampling ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit superSamplingChanged( m_superSampling ); + } + } } - -void SteamVRTabController::setCompositorSuperSampling(float value, bool notify) { - bool override = false; - if (value <= 0.01f) { - LOG(WARNING) << "Encountered a compositor supersampling value <= 0.01, setting supersampling to 1.0"; - value = 1.0f; - override = true; - } - if (override || m_compositorSuperSampling != value) { - LOG(DEBUG) << "Compositor supersampling value changed: " << m_compositorSuperSampling << " => " << value; - m_compositorSuperSampling = value; - vr::VRSettings()->SetFloat(vrsettings_compositor_category, vr::k_pch_SteamVR_RenderTargetMultiplier_Float, m_compositorSuperSampling); - vr::VRSettings()->Sync(); - if (notify) { - emit compositorSuperSamplingChanged(m_compositorSuperSampling); - } - } +void SteamVRTabController::setCompositorSuperSampling( float value, + bool notify ) +{ + bool override = false; + if ( value <= 0.01f ) + { + LOG( WARNING ) << "Encountered a compositor supersampling value <= " + "0.01, setting supersampling to 1.0"; + value = 1.0f; + override = true; + } + if ( override || m_compositorSuperSampling != value ) + { + LOG( DEBUG ) << "Compositor supersampling value changed: " + << m_compositorSuperSampling << " => " << value; + m_compositorSuperSampling = value; + vr::VRSettings()->SetFloat( + vrsettings_compositor_category, + vr::k_pch_SteamVR_RenderTargetMultiplier_Float, + m_compositorSuperSampling ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit compositorSuperSamplingChanged( m_compositorSuperSampling ); + } + } } - -float SteamVRTabController::superSampling() const { - return m_superSampling; +float SteamVRTabController::superSampling() const +{ + return m_superSampling; } - -float SteamVRTabController::compositorSuperSampling() const { - return m_compositorSuperSampling; +float SteamVRTabController::compositorSuperSampling() const +{ + return m_compositorSuperSampling; } - -bool SteamVRTabController::allowInterleavedReprojection() const { - return m_allowInterleavedReprojection; +bool SteamVRTabController::allowInterleavedReprojection() const +{ + return m_allowInterleavedReprojection; } - -bool SteamVRTabController::allowAsyncReprojection() const { - return m_allowAsyncReprojection; +bool SteamVRTabController::allowAsyncReprojection() const +{ + return m_allowAsyncReprojection; } - -void SteamVRTabController::setAllowInterleavedReprojection(bool value, bool notify) { - if (m_allowInterleavedReprojection != value) { - m_allowInterleavedReprojection = value; - vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowReprojection_Bool, m_allowInterleavedReprojection); - vr::VRSettings()->Sync(); - if (notify) { - emit allowInterleavedReprojectionChanged(m_allowInterleavedReprojection); - } - } +void SteamVRTabController::setAllowInterleavedReprojection( bool value, + bool notify ) +{ + if ( m_allowInterleavedReprojection != value ) + { + m_allowInterleavedReprojection = value; + vr::VRSettings()->SetBool( vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowReprojection_Bool, + m_allowInterleavedReprojection ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit allowInterleavedReprojectionChanged( + m_allowInterleavedReprojection ); + } + } } - -void SteamVRTabController::setAllowAsyncReprojection(bool value, bool notify) { - if (m_allowAsyncReprojection != value) { - m_allowAsyncReprojection = value; - vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, m_allowAsyncReprojection); - vr::VRSettings()->Sync(); - if (notify) { - emit allowAsyncReprojectionChanged(m_allowAsyncReprojection); - } - } +void SteamVRTabController::setAllowAsyncReprojection( bool value, bool notify ) +{ + if ( m_allowAsyncReprojection != value ) + { + m_allowAsyncReprojection = value; + vr::VRSettings()->SetBool( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, + m_allowAsyncReprojection ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit allowAsyncReprojectionChanged( m_allowAsyncReprojection ); + } + } } -bool SteamVRTabController::forceReprojection() const { - return m_forceReprojection; +bool SteamVRTabController::forceReprojection() const +{ + return m_forceReprojection; } - -void SteamVRTabController::setForceReprojection(bool value, bool notify) { - if (m_forceReprojection != value) { - m_forceReprojection = value; - vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ForceReprojection_Bool, m_forceReprojection); - vr::VRSettings()->Sync(); - if (notify) { - emit forceReprojectionChanged(m_forceReprojection); - } - } +void SteamVRTabController::setForceReprojection( bool value, bool notify ) +{ + if ( m_forceReprojection != value ) + { + m_forceReprojection = value; + vr::VRSettings()->SetBool( vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_ForceReprojection_Bool, + m_forceReprojection ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit forceReprojectionChanged( m_forceReprojection ); + } + } } - -bool SteamVRTabController::allowSupersampleFiltering() const { - return m_allowSupersampleFiltering; +bool SteamVRTabController::allowSupersampleFiltering() const +{ + return m_allowSupersampleFiltering; } - -void SteamVRTabController::setAllowSupersampleFiltering(bool value, bool notify) { - if (m_allowSupersampleFiltering != value) { - m_allowSupersampleFiltering = value; - vr::VRSettings()->SetBool(vr::k_pch_SteamVR_Section, vrsettings_steamvr_allowSupersampleFiltering, m_allowSupersampleFiltering); - vr::VRSettings()->Sync(); - if (notify) { - emit allowSupersampleFilteringChanged(m_allowSupersampleFiltering); - } - } +void SteamVRTabController::setAllowSupersampleFiltering( bool value, + bool notify ) +{ + if ( m_allowSupersampleFiltering != value ) + { + m_allowSupersampleFiltering = value; + vr::VRSettings()->SetBool( vr::k_pch_SteamVR_Section, + vrsettings_steamvr_allowSupersampleFiltering, + m_allowSupersampleFiltering ); + vr::VRSettings()->Sync(); + if ( notify ) + { + emit allowSupersampleFilteringChanged( + m_allowSupersampleFiltering ); + } + } } +void SteamVRTabController::reset() +{ + vr::EVRSettingsError vrSettingsError; -void SteamVRTabController::reset() { - vr::EVRSettingsError vrSettingsError; + vr::VRSettings()->RemoveKeyInSection( vr::k_pch_SteamVR_Section, + vrsettings_steamvr_supersampleScale, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vrsettings_steamvr_supersampleScale << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_SteamVR_Section, vrsettings_steamvr_supersampleScale, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vrsettings_steamvr_supersampleScale << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + setCompositorSuperSampling( 1.0f ); // Is not in default.vrsettings yet + vr::VRSettings()->RemoveKeyInSection( + vrsettings_compositor_category, + vr::k_pch_SteamVR_RenderTargetMultiplier_Float, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vrsettings_compositor_category + << "::" << vr::k_pch_SteamVR_RenderTargetMultiplier_Float + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - setCompositorSuperSampling(1.0f); // Is not in default.vrsettings yet - vr::VRSettings()->RemoveKeyInSection(vrsettings_compositor_category, vr::k_pch_SteamVR_RenderTargetMultiplier_Float, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vrsettings_compositor_category << "::" << vr::k_pch_SteamVR_RenderTargetMultiplier_Float << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_SteamVR_AllowReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_SteamVR_AllowReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_SteamVR_AllowAsyncReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_AllowAsyncReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_SteamVR_AllowAsyncReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_SteamVR_Section, + vr::k_pch_SteamVR_ForceReprojection_Bool, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vr::k_pch_SteamVR_ForceReprojection_Bool + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_SteamVR_Section, vr::k_pch_SteamVR_ForceReprojection_Bool, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vr::k_pch_SteamVR_ForceReprojection_Bool << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } + vr::VRSettings()->RemoveKeyInSection( + vr::k_pch_SteamVR_Section, + vrsettings_steamvr_allowSupersampleFiltering, + &vrSettingsError ); + if ( vrSettingsError != vr::VRSettingsError_None ) + { + LOG( WARNING ) << "Could not remove \"" + << vrsettings_steamvr_allowSupersampleFiltering + << "\" setting: " + << vr::VRSettings()->GetSettingsErrorNameFromEnum( + vrSettingsError ); + } - vr::VRSettings()->RemoveKeyInSection(vr::k_pch_SteamVR_Section, vrsettings_steamvr_allowSupersampleFiltering, &vrSettingsError); - if (vrSettingsError != vr::VRSettingsError_None) { - LOG(WARNING) << "Could not remove \"" << vrsettings_steamvr_allowSupersampleFiltering << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); - } - - vr::VRSettings()->Sync(); - settingsUpdateCounter = 999; // Easiest way to get default values + vr::VRSettings()->Sync(); + settingsUpdateCounter = 999; // Easiest way to get default values } - -void SteamVRTabController::restartSteamVR() { - QString cmd = QString("cmd.exe /C restartvrserver.bat \"") + parent->getVRRuntimePathUrl().toLocalFile() + QString("\""); - LOG(INFO) << "SteamVR Restart Command: " << cmd; - QProcess::startDetached(cmd); +void SteamVRTabController::restartSteamVR() +{ + QString cmd = QString( "cmd.exe /C restartvrserver.bat \"" ) + + parent->getVRRuntimePathUrl().toLocalFile() + + QString( "\"" ); + LOG( INFO ) << "SteamVR Restart Command: " << cmd; + QProcess::startDetached( cmd ); } - -void SteamVRTabController::addSteamVRProfile(QString name, bool includeSupersampling, bool includeSupersampleFiltering, bool includeReprojectionSettings) { - SteamVRProfile* profile = nullptr; - for (auto& p : steamvrProfiles) { - if (p.profileName.compare(name.toStdString()) == 0) { - profile = &p; - break; - } - } - if (!profile) { - auto i = steamvrProfiles.size(); - steamvrProfiles.emplace_back(); - profile = &steamvrProfiles[i]; - } - profile->profileName = name.toStdString(); - profile->includesSupersampling = includeSupersampling; - if (includeSupersampling) { - profile->supersampling = m_superSampling; - } - profile->includesSupersampleFiltering = includeSupersampleFiltering; - if (includeSupersampleFiltering) { - profile->supersampleFiltering = m_allowSupersampleFiltering; - } - profile->includesReprojectionSettings = includeReprojectionSettings; - if (includeReprojectionSettings) { - profile->asynchronousReprojection = m_allowAsyncReprojection; - profile->interleavedReprojection = m_allowInterleavedReprojection; - profile->alwaysOnReprojection = m_forceReprojection; - } - saveSteamVRProfiles(); - OverlayController::appSettings()->sync(); - emit steamVRProfilesUpdated(); +void SteamVRTabController::addSteamVRProfile( QString name, + bool includeSupersampling, + bool includeSupersampleFiltering, + bool includeReprojectionSettings ) +{ + SteamVRProfile* profile = nullptr; + for ( auto& p : steamvrProfiles ) + { + if ( p.profileName.compare( name.toStdString() ) == 0 ) + { + profile = &p; + break; + } + } + if ( !profile ) + { + auto i = steamvrProfiles.size(); + steamvrProfiles.emplace_back(); + profile = &steamvrProfiles[i]; + } + profile->profileName = name.toStdString(); + profile->includesSupersampling = includeSupersampling; + if ( includeSupersampling ) + { + profile->supersampling = m_superSampling; + } + profile->includesSupersampleFiltering = includeSupersampleFiltering; + if ( includeSupersampleFiltering ) + { + profile->supersampleFiltering = m_allowSupersampleFiltering; + } + profile->includesReprojectionSettings = includeReprojectionSettings; + if ( includeReprojectionSettings ) + { + profile->asynchronousReprojection = m_allowAsyncReprojection; + profile->interleavedReprojection = m_allowInterleavedReprojection; + profile->alwaysOnReprojection = m_forceReprojection; + } + saveSteamVRProfiles(); + OverlayController::appSettings()->sync(); + emit steamVRProfilesUpdated(); } - -void SteamVRTabController::applySteamVRProfile(unsigned index) { - if (index < steamvrProfiles.size()) { - auto& profile = steamvrProfiles[index]; - if (profile.includesSupersampling) { - setSuperSampling(profile.supersampling); - } - if (profile.includesSupersampleFiltering) { - setAllowSupersampleFiltering(profile.supersampleFiltering); - } - if (profile.includesReprojectionSettings) { - setAllowAsyncReprojection(profile.asynchronousReprojection); - setAllowInterleavedReprojection(profile.interleavedReprojection); - setForceReprojection(profile.alwaysOnReprojection); - } - vr::VRSettings()->Sync(true); - } +void SteamVRTabController::applySteamVRProfile( unsigned index ) +{ + if ( index < steamvrProfiles.size() ) + { + auto& profile = steamvrProfiles[index]; + if ( profile.includesSupersampling ) + { + setSuperSampling( profile.supersampling ); + } + if ( profile.includesSupersampleFiltering ) + { + setAllowSupersampleFiltering( profile.supersampleFiltering ); + } + if ( profile.includesReprojectionSettings ) + { + setAllowAsyncReprojection( profile.asynchronousReprojection ); + setAllowInterleavedReprojection( profile.interleavedReprojection ); + setForceReprojection( profile.alwaysOnReprojection ); + } + vr::VRSettings()->Sync( true ); + } } - -void SteamVRTabController::deleteSteamVRProfile(unsigned index) { - if (index < steamvrProfiles.size()) { - auto pos = steamvrProfiles.begin() + index; - steamvrProfiles.erase(pos); - saveSteamVRProfiles(); - OverlayController::appSettings()->sync(); - emit steamVRProfilesUpdated(); - } +void SteamVRTabController::deleteSteamVRProfile( unsigned index ) +{ + if ( index < steamvrProfiles.size() ) + { + auto pos = steamvrProfiles.begin() + index; + steamvrProfiles.erase( pos ); + saveSteamVRProfiles(); + OverlayController::appSettings()->sync(); + emit steamVRProfilesUpdated(); + } } - - -} // namespace advconfig - +} // namespace advsettings diff --git a/src/tabcontrollers/SteamVRTabController.h b/src/tabcontrollers/SteamVRTabController.h index e644cb9..142ba1f 100644 --- a/src/tabcontrollers/SteamVRTabController.h +++ b/src/tabcontrollers/SteamVRTabController.h @@ -3,99 +3,111 @@ #include - - class QQuickWindow; // application namespace -namespace advsettings { - +namespace advsettings +{ // forward declaration class OverlayController; +struct SteamVRProfile +{ + std::string profileName; -struct SteamVRProfile { - std::string profileName; + bool includesSupersampling = false; + float supersampling = 1.0f; - bool includesSupersampling = false; - float supersampling = 1.0f; + bool includesSupersampleFiltering = false; + bool supersampleFiltering = false; - bool includesSupersampleFiltering = false; - bool supersampleFiltering = false; - - bool includesReprojectionSettings = false; - bool asynchronousReprojection = true; - bool interleavedReprojection = true; - bool alwaysOnReprojection = true; + bool includesReprojectionSettings = false; + bool asynchronousReprojection = true; + bool interleavedReprojection = true; + bool alwaysOnReprojection = true; }; - -class SteamVRTabController : public QObject { - Q_OBJECT - Q_PROPERTY(float superSampling READ superSampling WRITE setSuperSampling NOTIFY superSamplingChanged) - Q_PROPERTY(float compositorSuperSampling READ compositorSuperSampling WRITE setCompositorSuperSampling NOTIFY compositorSuperSamplingChanged) - Q_PROPERTY(bool allowInterleavedReprojection READ allowInterleavedReprojection WRITE setAllowInterleavedReprojection NOTIFY allowInterleavedReprojectionChanged) - Q_PROPERTY(bool allowAsyncReprojection READ allowAsyncReprojection WRITE setAllowAsyncReprojection NOTIFY allowAsyncReprojectionChanged) - Q_PROPERTY(bool forceReprojection READ forceReprojection WRITE setForceReprojection NOTIFY forceReprojectionChanged) - Q_PROPERTY(bool allowSupersampleFiltering READ allowSupersampleFiltering WRITE setAllowSupersampleFiltering NOTIFY allowSupersampleFilteringChanged) +class SteamVRTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( float superSampling READ superSampling WRITE setSuperSampling + NOTIFY superSamplingChanged ) + Q_PROPERTY( + float compositorSuperSampling READ compositorSuperSampling WRITE + setCompositorSuperSampling NOTIFY compositorSuperSamplingChanged ) + Q_PROPERTY( + bool allowInterleavedReprojection READ allowInterleavedReprojection + WRITE setAllowInterleavedReprojection NOTIFY + allowInterleavedReprojectionChanged ) + Q_PROPERTY( + bool allowAsyncReprojection READ allowAsyncReprojection WRITE + setAllowAsyncReprojection NOTIFY allowAsyncReprojectionChanged ) + Q_PROPERTY( bool forceReprojection READ forceReprojection WRITE + setForceReprojection NOTIFY forceReprojectionChanged ) + Q_PROPERTY( bool allowSupersampleFiltering READ allowSupersampleFiltering + WRITE setAllowSupersampleFiltering NOTIFY + allowSupersampleFilteringChanged ) private: - OverlayController* parent; - QQuickWindow* widget; + OverlayController* parent; + QQuickWindow* widget; - float m_superSampling = 1.0; - float m_compositorSuperSampling = 1.0; - bool m_allowInterleavedReprojection = true; - bool m_allowAsyncReprojection = true; - bool m_forceReprojection = false; - bool m_allowSupersampleFiltering = true; + float m_superSampling = 1.0; + float m_compositorSuperSampling = 1.0; + bool m_allowInterleavedReprojection = true; + bool m_allowAsyncReprojection = true; + bool m_forceReprojection = false; + bool m_allowSupersampleFiltering = true; - std::vector steamvrProfiles; + std::vector steamvrProfiles; - unsigned settingsUpdateCounter = 0; + unsigned settingsUpdateCounter = 0; public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - void eventLoopTick(); + void eventLoopTick(); - float superSampling() const; - float compositorSuperSampling() const; - bool allowInterleavedReprojection() const; - bool allowAsyncReprojection() const; - bool forceReprojection() const; - bool allowSupersampleFiltering() const; + float superSampling() const; + float compositorSuperSampling() const; + bool allowInterleavedReprojection() const; + bool allowAsyncReprojection() const; + bool forceReprojection() const; + bool allowSupersampleFiltering() const; - void reloadSteamVRProfiles(); - void saveSteamVRProfiles(); + void reloadSteamVRProfiles(); + void saveSteamVRProfiles(); - Q_INVOKABLE unsigned getSteamVRProfileCount(); - Q_INVOKABLE QString getSteamVRProfileName(unsigned index); + Q_INVOKABLE unsigned getSteamVRProfileCount(); + Q_INVOKABLE QString getSteamVRProfileName( unsigned index ); public slots: - void setSuperSampling(float value, bool notify = true); - void setCompositorSuperSampling(float value, bool notify = true); - void setAllowInterleavedReprojection(bool value, bool notify = true); - void setAllowAsyncReprojection(bool value, bool notify = true); - void setForceReprojection(bool value, bool notify = true); - void setAllowSupersampleFiltering(bool value, bool notify = true); + void setSuperSampling( float value, bool notify = true ); + void setCompositorSuperSampling( float value, bool notify = true ); + void setAllowInterleavedReprojection( bool value, bool notify = true ); + void setAllowAsyncReprojection( bool value, bool notify = true ); + void setForceReprojection( bool value, bool notify = true ); + void setAllowSupersampleFiltering( bool value, bool notify = true ); - void addSteamVRProfile(QString name, bool includeSupersampling, bool includeSupersampleFiltering, bool includeReprojectionSettings); - void applySteamVRProfile(unsigned index); - void deleteSteamVRProfile(unsigned index); + void addSteamVRProfile( QString name, + bool includeSupersampling, + bool includeSupersampleFiltering, + bool includeReprojectionSettings ); + void applySteamVRProfile( unsigned index ); + void deleteSteamVRProfile( unsigned index ); - void reset(); - void restartSteamVR(); + void reset(); + void restartSteamVR(); signals: - void superSamplingChanged(float value); - void compositorSuperSamplingChanged(float value); - void allowInterleavedReprojectionChanged(bool value); - void allowAsyncReprojectionChanged(bool value); - void forceReprojectionChanged(bool value); - void allowSupersampleFilteringChanged(bool value); + void superSamplingChanged( float value ); + void compositorSuperSamplingChanged( float value ); + void allowInterleavedReprojectionChanged( bool value ); + void allowAsyncReprojectionChanged( bool value ); + void forceReprojectionChanged( bool value ); + void allowSupersampleFilteringChanged( bool value ); - void steamVRProfilesUpdated(); + void steamVRProfilesUpdated(); }; } // namespace advsettings diff --git a/src/tabcontrollers/UtilitiesTabController.cpp b/src/tabcontrollers/UtilitiesTabController.cpp index c83cfd3..0684b46 100644 --- a/src/tabcontrollers/UtilitiesTabController.cpp +++ b/src/tabcontrollers/UtilitiesTabController.cpp @@ -4,399 +4,593 @@ #include "../overlaycontroller.h" #include #ifdef _WIN32 - #include "keyboardinput/KeyboardInputWindows.h" +# include "keyboardinput/KeyboardInputWindows.h" #else - #include "keyboardinput/KeyboardInputDummy.h" +# include "keyboardinput/KeyboardInputDummy.h" #endif // application namespace -namespace advsettings { +namespace advsettings +{ +const char* steamDesktopOverlaykey = "valve.steam.desktop"; - const char* steamDesktopOverlaykey = "valve.steam.desktop"; +void UtilitiesTabController::initStage1() +{ +#ifdef _WIN32 + keyboardInput.reset( new KeyboardInputWindows() ); +#else + keyboardInput.reset( new KeyboardInputDummy() ); +#endif + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + auto qAlarmEnabled = settings->value( "alarmEnabled", m_alarmEnabled ); + auto qAlarmIsModal = settings->value( "alarmIsModal", m_alarmIsModal ); + auto qAlarmHour = settings->value( "alarmHour", 0 ); + auto qAlarmMinute = settings->value( "alarmMinute", 0 ); + settings->endGroup(); + m_alarmEnabled = qAlarmEnabled.toBool(); + m_alarmIsModal = qAlarmIsModal.toBool(); + m_alarmTime = QTime( qAlarmHour.toInt(), qAlarmMinute.toInt() ); + vr::VROverlayHandle_t pOverlayHandle; + auto error = vr::VROverlay()->FindOverlay( steamDesktopOverlaykey, + &pOverlayHandle ); + if ( error != vr::VROverlayError_None ) + { + m_steamDesktopOverlayAvailable = false; + LOG( INFO ) << "Could not find overlay \"" << steamDesktopOverlaykey + << "\": " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( error ); + } + else + { + m_steamDesktopOverlayAvailable = true; + float width; + error = vr::VROverlay()->GetOverlayWidthInMeters( pOverlayHandle, + &width ); + if ( error != vr::VROverlayError_None ) + { + LOG( ERROR ) << "Could not read overlay width of \"" + << steamDesktopOverlaykey << "\": " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( + error ); + } + else + { + m_steamDesktopOverlayWidth = width; + } + } +} - void UtilitiesTabController::initStage1() { - #ifdef _WIN32 - keyboardInput.reset(new KeyboardInputWindows()); - #else - keyboardInput.reset(new KeyboardInputDummy()); - #endif - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - auto qAlarmEnabled = settings->value("alarmEnabled", m_alarmEnabled); - auto qAlarmIsModal = settings->value("alarmIsModal", m_alarmIsModal); - auto qAlarmHour = settings->value("alarmHour", 0); - auto qAlarmMinute = settings->value("alarmMinute", 0); - settings->endGroup(); - m_alarmEnabled = qAlarmEnabled.toBool(); - m_alarmIsModal = qAlarmIsModal.toBool(); - m_alarmTime = QTime(qAlarmHour.toInt(), qAlarmMinute.toInt()); - vr::VROverlayHandle_t pOverlayHandle; - auto error = vr::VROverlay()->FindOverlay(steamDesktopOverlaykey, &pOverlayHandle); - if (error != vr::VROverlayError_None) { - m_steamDesktopOverlayAvailable = false; - LOG(INFO) << "Could not find overlay \"" << steamDesktopOverlaykey << "\": " << vr::VROverlay()->GetOverlayErrorNameFromEnum(error); - } else { - m_steamDesktopOverlayAvailable = true; - float width; - error = vr::VROverlay()->GetOverlayWidthInMeters(pOverlayHandle, &width); - if (error != vr::VROverlayError_None) { - LOG(ERROR) << "Could not read overlay width of \"" << steamDesktopOverlaykey << "\": " << vr::VROverlay()->GetOverlayErrorNameFromEnum(error); - } else { - m_steamDesktopOverlayWidth = width; - } - } +void UtilitiesTabController::initStage2( OverlayController* var_parent, + QQuickWindow* var_widget ) +{ + this->parent = var_parent; + this->widget = var_widget; +} - } +void UtilitiesTabController::sendKeyboardInput( QString input ) +{ + keyboardInput->sendKeyboardInput( input ); +} - void UtilitiesTabController::initStage2(OverlayController * var_parent, QQuickWindow * var_widget) { - this->parent = var_parent; - this->widget = var_widget; - } +void UtilitiesTabController::sendKeyboardEnter() +{ + keyboardInput->sendKeyboardEnter(); +} - void UtilitiesTabController::sendKeyboardInput(QString input) { - keyboardInput->sendKeyboardInput(input); - } +void UtilitiesTabController::sendKeyboardAltTab() +{ + keyboardInput->sendKeyboardAltTab(); +} - void UtilitiesTabController::sendKeyboardEnter() { - keyboardInput->sendKeyboardEnter(); - } +void UtilitiesTabController::sendKeyboardBackspace( int count ) +{ + keyboardInput->sendKeyboardBackspace( count ); +} - void UtilitiesTabController::sendKeyboardAltTab() { - keyboardInput->sendKeyboardAltTab(); +bool UtilitiesTabController::alarmEnabled() const +{ + return m_alarmEnabled; +} + +bool UtilitiesTabController::alarmIsModal() const +{ + return m_alarmIsModal; +} + +int UtilitiesTabController::alarmTimeHour() const +{ + return m_alarmTime.hour(); +} + +int UtilitiesTabController::alarmTimeMinute() const +{ + return m_alarmTime.minute(); +} + +void UtilitiesTabController::setAlarmEnabled( bool enabled, bool notify ) +{ + if ( m_alarmEnabled != enabled ) + { + m_alarmEnabled = enabled; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmEnabled", m_alarmEnabled ); + settings->endGroup(); + settings->sync(); + m_alarmLastCheckTime = QTime(); + if ( notify ) + { + emit alarmEnabledChanged( m_alarmEnabled ); + } + } +} + +void UtilitiesTabController::setAlarmIsModal( bool modal, bool notify ) +{ + if ( m_alarmIsModal != modal ) + { + m_alarmIsModal = modal; + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmIsModal", m_alarmIsModal ); + settings->endGroup(); + settings->sync(); + if ( notify ) + { + emit alarmIsModalChanged( m_alarmIsModal ); + } + } +} + +void UtilitiesTabController::setAlarmTimeHour( int hour, bool notify ) +{ + if ( m_alarmTime.hour() != hour ) + { + if ( m_alarmTime.isValid() ) + { + m_alarmTime = QTime( hour, m_alarmTime.minute() ); + } + else + { + m_alarmTime = QTime( hour, 0 ); + } + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmHour", m_alarmTime.hour() ); + settings->setValue( "alarmMinute", m_alarmTime.minute() ); + settings->endGroup(); + settings->sync(); + m_alarmLastCheckTime = QTime(); + if ( notify ) + { + emit alarmTimeHourChanged( hour ); + } + } +} + +void UtilitiesTabController::setAlarmTimeMinute( int min, bool notify ) +{ + if ( m_alarmTime.minute() != min ) + { + if ( m_alarmTime.isValid() ) + { + m_alarmTime = QTime( m_alarmTime.hour(), min ); + } + else + { + m_alarmTime = QTime( 0, min ); + } + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmHour", m_alarmTime.hour() ); + settings->setValue( "alarmMinute", m_alarmTime.minute() ); + settings->endGroup(); + settings->sync(); + m_alarmLastCheckTime = QTime(); + if ( notify ) + { + emit alarmTimeMinuteChanged( min ); + } + } +} + +void UtilitiesTabController::setAlarmTimeToCurrentTime() +{ + auto now = QTime::currentTime(); + setAlarmTimeHour( now.hour() ); + setAlarmTimeMinute( now.minute() ); +} + +void UtilitiesTabController::modAlarmTimeHour( int value, bool notify ) +{ + auto h = m_alarmTime.hour(); + m_alarmTime = m_alarmTime.addSecs( value * 60 * 60 ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmHour", m_alarmTime.hour() ); + settings->setValue( "alarmMinute", m_alarmTime.minute() ); + settings->endGroup(); + settings->sync(); + if ( h != m_alarmTime.hour() ) + { + m_alarmLastCheckTime = QTime(); + if ( notify ) + { + emit alarmTimeHourChanged( m_alarmTime.hour() ); + } + } +} + +void UtilitiesTabController::modAlarmTimeMinute( int value, bool notify ) +{ + auto h = m_alarmTime.hour(); + auto m = m_alarmTime.minute(); + m_alarmTime = m_alarmTime.addSecs( value * 60 ); + auto settings = OverlayController::appSettings(); + settings->beginGroup( "utilitiesSettings" ); + settings->setValue( "alarmHour", m_alarmTime.hour() ); + settings->setValue( "alarmMinute", m_alarmTime.minute() ); + settings->endGroup(); + settings->sync(); + if ( m != m_alarmTime.minute() || h != m_alarmTime.hour() ) + { + m_alarmLastCheckTime = QTime(); + if ( notify ) + { + if ( h != m_alarmTime.hour() ) + { + emit alarmTimeHourChanged( m_alarmTime.hour() ); + } + if ( m != m_alarmTime.minute() ) + { + emit alarmTimeMinuteChanged( m_alarmTime.minute() ); + } + } + } +} + +vr::VROverlayHandle_t createBatteryOverlay( vr::TrackedDeviceIndex_t index ) +{ + vr::VROverlayHandle_t handle = vr::k_ulOverlayHandleInvalid; + std::string batteryKey = std::string( OverlayController::applicationKey ) + + ".battery." + std::to_string( index ); + vr::VROverlayError overlayError = vr::VROverlay()->CreateOverlay( + batteryKey.c_str(), batteryKey.c_str(), &handle ); + if ( overlayError == vr::VROverlayError_None ) + { + std::string batteryIconPath + = QApplication::applicationDirPath().toStdString() + + "/res/battery_0.png"; + if ( QFile::exists( QString::fromStdString( batteryIconPath ) ) ) + { + vr::VROverlay()->SetOverlayFromFile( handle, + batteryIconPath.c_str() ); + vr::VROverlay()->SetOverlayWidthInMeters( handle, 0.05f ); + vr::HmdMatrix34_t notificationTransform + = { { { 1.0f, 0.0f, 0.0f, 0.00f }, + { 0.0f, -1.0f, 0.0f, 0.01f }, + { 0.0f, 0.0f, -1.0f, -0.013f } } }; + vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative( + handle, index, ¬ificationTransform ); + LOG( INFO ) << "Created battery overlay for device " << index; + } + else + { + LOG( ERROR ) << "Could not find battery icon \"" << batteryIconPath + << "\""; + } + } + else + { + LOG( ERROR ) << "Could not create ptt notification overlay: " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( + overlayError ); } - void UtilitiesTabController::sendKeyboardBackspace(int count) { - keyboardInput->sendKeyboardBackspace(count); - } + return handle; +} - - bool UtilitiesTabController::alarmEnabled() const { - return m_alarmEnabled; - } - - bool UtilitiesTabController::alarmIsModal() const { - return m_alarmIsModal; - } - - int UtilitiesTabController::alarmTimeHour() const { - return m_alarmTime.hour(); - } - - int UtilitiesTabController::alarmTimeMinute() const { - return m_alarmTime.minute(); - } - - void UtilitiesTabController::setAlarmEnabled(bool enabled, bool notify) { - if (m_alarmEnabled != enabled) { - m_alarmEnabled = enabled; - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmEnabled", m_alarmEnabled); - settings->endGroup(); - settings->sync(); - m_alarmLastCheckTime = QTime(); - if (notify) { - emit alarmEnabledChanged(m_alarmEnabled); - } - } - } - - void UtilitiesTabController::setAlarmIsModal(bool modal, bool notify) { - if (m_alarmIsModal != modal) { - m_alarmIsModal = modal; - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmIsModal", m_alarmIsModal); - settings->endGroup(); - settings->sync(); - if (notify) { - emit alarmIsModalChanged(m_alarmIsModal); - } - } - } - - void UtilitiesTabController::setAlarmTimeHour(int hour, bool notify) { - if (m_alarmTime.hour() != hour) { - if (m_alarmTime.isValid()) { - m_alarmTime = QTime(hour, m_alarmTime.minute()); - } else { - m_alarmTime = QTime(hour, 0); - } - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmHour", m_alarmTime.hour()); - settings->setValue("alarmMinute", m_alarmTime.minute()); - settings->endGroup(); - settings->sync(); - m_alarmLastCheckTime = QTime(); - if (notify) { - emit alarmTimeHourChanged(hour); - } - } - } - - void UtilitiesTabController::setAlarmTimeMinute(int min, bool notify) { - if (m_alarmTime.minute() != min) { - if (m_alarmTime.isValid()) { - m_alarmTime = QTime(m_alarmTime.hour(), min); - } else { - m_alarmTime = QTime(0, min); - } - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmHour", m_alarmTime.hour()); - settings->setValue("alarmMinute", m_alarmTime.minute()); - settings->endGroup(); - settings->sync(); - m_alarmLastCheckTime = QTime(); - if (notify) { - emit alarmTimeMinuteChanged(min); - } - } - } - - void UtilitiesTabController::setAlarmTimeToCurrentTime() { - auto now = QTime::currentTime(); - setAlarmTimeHour(now.hour()); - setAlarmTimeMinute(now.minute()); - } - - void UtilitiesTabController::modAlarmTimeHour(int value, bool notify) { - auto h = m_alarmTime.hour(); - m_alarmTime = m_alarmTime.addSecs(value * 60 * 60); - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmHour", m_alarmTime.hour()); - settings->setValue("alarmMinute", m_alarmTime.minute()); - settings->endGroup(); - settings->sync(); - if (h != m_alarmTime.hour()) { - m_alarmLastCheckTime = QTime(); - if (notify) { - emit alarmTimeHourChanged(m_alarmTime.hour()); - } - } - } - - void UtilitiesTabController::modAlarmTimeMinute(int value, bool notify) { - auto h = m_alarmTime.hour(); - auto m = m_alarmTime.minute(); - m_alarmTime = m_alarmTime.addSecs(value * 60); - auto settings = OverlayController::appSettings(); - settings->beginGroup("utilitiesSettings"); - settings->setValue("alarmHour", m_alarmTime.hour()); - settings->setValue("alarmMinute", m_alarmTime.minute()); - settings->endGroup(); - settings->sync(); - if (m != m_alarmTime.minute() || h != m_alarmTime.hour()) { - m_alarmLastCheckTime = QTime(); - if (notify) { - if (h != m_alarmTime.hour()) { - emit alarmTimeHourChanged(m_alarmTime.hour()); - } - if (m != m_alarmTime.minute()) { - emit alarmTimeMinuteChanged(m_alarmTime.minute()); - } - } - } - } - - vr::VROverlayHandle_t createBatteryOverlay(vr::TrackedDeviceIndex_t index) { - vr::VROverlayHandle_t handle = vr::k_ulOverlayHandleInvalid; - std::string batteryKey = std::string(OverlayController::applicationKey) + ".battery." + std::to_string(index); - vr::VROverlayError overlayError = vr::VROverlay()->CreateOverlay(batteryKey.c_str(), batteryKey.c_str(), &handle); - if (overlayError == vr::VROverlayError_None) { - std::string batteryIconPath = QApplication::applicationDirPath().toStdString() + "/res/battery_0.png"; - if (QFile::exists(QString::fromStdString(batteryIconPath))) { - vr::VROverlay()->SetOverlayFromFile(handle, batteryIconPath.c_str()); - vr::VROverlay()->SetOverlayWidthInMeters(handle, 0.05f); - vr::HmdMatrix34_t notificationTransform = {{ - {1.0f, 0.0f, 0.0f, 0.00f}, - {0.0f, -1.0f, 0.0f, 0.01f}, - {0.0f, 0.0f, -1.0f, -0.013f} - }}; - vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative(handle, index, ¬ificationTransform); - LOG(INFO) << "Created battery overlay for device " << index; - } else { - LOG(ERROR) << "Could not find battery icon \"" << batteryIconPath << "\""; +void UtilitiesTabController::eventLoopTick() +{ + if ( settingsUpdateCounter >= 10 ) + { + vr::VROverlayHandle_t pOverlayHandle; + auto error = vr::VROverlay()->FindOverlay( steamDesktopOverlaykey, + &pOverlayHandle ); + if ( error == vr::VROverlayError_None ) + { + if ( !m_steamDesktopOverlayAvailable ) + { + m_steamDesktopOverlayAvailable = true; + emit steamDesktopOverlayAvailableChanged( + m_steamDesktopOverlayAvailable ); + } + float width; + error = vr::VROverlay()->GetOverlayWidthInMeters( pOverlayHandle, + &width ); + if ( error != vr::VROverlayError_None ) + { + LOG( ERROR ) + << "Could not read overlay width of \"" + << steamDesktopOverlaykey << "\": " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( error ); + } + else + { + setSteamDesktopOverlayWidth( width, true, false ); + } + } + else + { + if ( m_steamDesktopOverlayAvailable ) + { + m_steamDesktopOverlayAvailable = false; + emit steamDesktopOverlayAvailableChanged( + m_steamDesktopOverlayAvailable ); } - } else { - LOG(ERROR) << "Could not create ptt notification overlay: " << vr::VROverlay()->GetOverlayErrorNameFromEnum(overlayError); } - return handle; - } - - - void UtilitiesTabController::eventLoopTick() { - if (settingsUpdateCounter >= 10) { - - vr::VROverlayHandle_t pOverlayHandle; - auto error = vr::VROverlay()->FindOverlay(steamDesktopOverlaykey, &pOverlayHandle); - if (error == vr::VROverlayError_None) { - if (!m_steamDesktopOverlayAvailable) { - m_steamDesktopOverlayAvailable = true; - emit steamDesktopOverlayAvailableChanged(m_steamDesktopOverlayAvailable); - } - float width; - error = vr::VROverlay()->GetOverlayWidthInMeters(pOverlayHandle, &width); - if (error != vr::VROverlayError_None) { - LOG(ERROR) << "Could not read overlay width of \"" << steamDesktopOverlaykey << "\": " << vr::VROverlay()->GetOverlayErrorNameFromEnum(error); - } else { - setSteamDesktopOverlayWidth(width, true, false); - } - } else { - if (m_steamDesktopOverlayAvailable) { - m_steamDesktopOverlayAvailable = false; - emit steamDesktopOverlayAvailableChanged(m_steamDesktopOverlayAvailable); - } - } - - if (m_alarmEnabled && m_alarmTime.isValid()) { - auto now = QTime::currentTime(); - if (m_alarmLastCheckTime.isValid() && m_alarmLastCheckTime <= m_alarmTime && m_alarmTime <= now) { - setAlarmEnabled(false); - char alarmMessageBuffer[1024]; - std::snprintf(alarmMessageBuffer, 1024, "The alarm at %02i:%02i went off.", alarmTimeHour(), alarmTimeMinute()); - if (m_alarmIsModal) { - std::thread messageThread([](UtilitiesTabController* parent, std::string message) { - auto res = vr::VROverlay()->ShowMessageOverlay(message.c_str(), "Alarm Clock", "Ok", "+15 min"); - if (res == vr::VRMessageOverlayResponse_ButtonPress_1) { - parent->setAlarmTimeToCurrentTime(); - parent->modAlarmTimeMinute(15); - parent->setAlarmEnabled(true); - } else if (res >= vr::VRMessageOverlayResponse_CouldntFindSystemOverlay) { - static const char* errorMessages[] = { "CouldntFindSystemOverlay", "CouldntFindOrCreateClientOverlay", "ApplicationQuit" }; - int errorCode = res - vr::VRMessageOverlayResponse_CouldntFindSystemOverlay; - if (res < 3) { - LOG(ERROR) << "Could not create Alarm Overlay: " << errorMessages[errorCode]; - } else { - LOG(ERROR) << "Could not create Alarm Overlay: Unknown Error"; - } - } - }, this, std::string(alarmMessageBuffer)); - messageThread.detach(); - } else { - vr::VRNotificationId notificationId; - vr::EVRInitError eError; - vr::IVRNotifications* vrnotification = (vr::IVRNotifications*)vr::VR_GetGenericInterface(vr::IVRNotifications_Version, &eError); - if (eError != vr::VRInitError_None) { - LOG(ERROR) << "Error while getting IVRNotifications interface" << vr::VR_GetVRInitErrorAsEnglishDescription(eError); - vrnotification = nullptr; - } else { - vr::NotificationBitmap_t* messageIconPtr = nullptr; - /* - // Can i even create this object on the stack, who takes ownership? - vr::NotificationBitmap_t messageIcon; - - // First get image width and height - vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(), nullptr, 0, (uint32_t*)&messageIcon.m_nWidth, (uint32_t*)&messageIcon.m_nHeight); - - messageIcon.m_nBytesPerPixel = 4; - unsigned bufferSize = messageIcon.m_nWidth*messageIcon.m_nHeight*messageIcon.m_nBytesPerPixel; - - // Can I delete this buffer after this section? Who takes ownership? - std::unique_ptr imageBuffer; - imageBuffer.reset(new char[bufferSize]); - messageIcon.m_pImageData = imageBuffer.get(); - - // Get image data - auto iconError = vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(), messageIcon.m_pImageData, bufferSize, (uint32_t*)&messageIcon.m_nWidth, (uint32_t*)&messageIcon.m_nHeight); - if (iconError != vr::VROverlayError_None) { - LOG(ERROR) << "Error while getting message overlay icon: " << vr::VROverlay()->GetOverlayErrorNameFromEnum(iconError); - } else { - messageIconPtr = &messageIcon; - } - */ - auto nError = vrnotification->CreateNotification( - parent->overlayHandle(), 666, vr::EVRNotificationType_Transient, alarmMessageBuffer, vr::EVRNotificationStyle_Application, messageIconPtr, ¬ificationId - ); - if (nError != vr::VRNotificationError_OK) { - LOG(ERROR) << "Error while creating notification: " << nError; - vrnotification = nullptr; - } - } - } - } - m_alarmLastCheckTime = now; - } - - - // attach battery overlay to all tracked devices that aren't a controller or hmd - for(vr::TrackedDeviceIndex_t i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { - vr::ETrackedDeviceClass deviceClass = vr::VRSystem()->GetTrackedDeviceClass(i); - if (deviceClass == vr::ETrackedDeviceClass::TrackedDeviceClass_GenericTracker) { - if (m_batteryOverlayHandles[i] == vr::k_ulOverlayHandleInvalid) { - LOG(INFO) << "Creating battery overlay for device " << i; - m_batteryOverlayHandles[i] = createBatteryOverlay(i); - m_batteryVisible[i] = true; - } - - bool shouldShow = vr::VROverlay()->IsDashboardVisible(); - - if (shouldShow != m_batteryVisible[i]) { - if (shouldShow) { - vr::VROverlay()->ShowOverlay(m_batteryOverlayHandles[i]); - } else { - vr::VROverlay()->HideOverlay(m_batteryOverlayHandles[i]); - } - m_batteryVisible[i] = shouldShow; - } - - bool hasBatteryStatus = vr::VRSystem()->GetBoolTrackedDeviceProperty(i, vr::ETrackedDeviceProperty::Prop_DeviceProvidesBatteryStatus_Bool); - if (hasBatteryStatus) { - float battery = vr::VRSystem()->GetFloatTrackedDeviceProperty(i, vr::ETrackedDeviceProperty::Prop_DeviceBatteryPercentage_Float); - int batteryState = ceil(battery * 5); - - if (batteryState != m_batteryState[i]) { - LOG(INFO) << "Updating battery overlay for device " << i << " to " << batteryState << "(" << battery << ""; - std::string batteryIconPath = QApplication::applicationDirPath().toStdString() + "/res/battery_" + std::to_string(batteryState) + ".png"; - if (QFile::exists(QString::fromStdString(batteryIconPath))) { - vr::VROverlay()->SetOverlayFromFile(m_batteryOverlayHandles[i], batteryIconPath.c_str()); - } else { - LOG(ERROR) << "Could not find battery icon \"" << batteryIconPath << "\""; + if ( m_alarmEnabled && m_alarmTime.isValid() ) + { + auto now = QTime::currentTime(); + if ( m_alarmLastCheckTime.isValid() + && m_alarmLastCheckTime <= m_alarmTime && m_alarmTime <= now ) + { + setAlarmEnabled( false ); + char alarmMessageBuffer[1024]; + std::snprintf( alarmMessageBuffer, + 1024, + "The alarm at %02i:%02i went off.", + alarmTimeHour(), + alarmTimeMinute() ); + if ( m_alarmIsModal ) + { + std::thread messageThread( + []( UtilitiesTabController* parent, + std::string message ) { + auto res = vr::VROverlay()->ShowMessageOverlay( + message.c_str(), + "Alarm Clock", + "Ok", + "+15 min" ); + if ( res + == vr::VRMessageOverlayResponse_ButtonPress_1 ) + { + parent->setAlarmTimeToCurrentTime(); + parent->modAlarmTimeMinute( 15 ); + parent->setAlarmEnabled( true ); } - m_batteryState[i] = batteryState; + else if ( + res + >= vr::VRMessageOverlayResponse_CouldntFindSystemOverlay ) + { + static const char* errorMessages[] + = { "CouldntFindSystemOverlay", + "CouldntFindOrCreateClientOverlay", + "ApplicationQuit" }; + int errorCode + = res + - vr::VRMessageOverlayResponse_CouldntFindSystemOverlay; + if ( res < 3 ) + { + LOG( ERROR ) + << "Could not create Alarm Overlay: " + << errorMessages[errorCode]; + } + else + { + LOG( ERROR ) << "Could not create Alarm " + "Overlay: Unknown Error"; + } + } + }, + this, + std::string( alarmMessageBuffer ) ); + messageThread.detach(); + } + else + { + vr::VRNotificationId notificationId; + vr::EVRInitError eError; + vr::IVRNotifications* vrnotification + = ( vr::IVRNotifications* ) vr::VR_GetGenericInterface( + vr::IVRNotifications_Version, &eError ); + if ( eError != vr::VRInitError_None ) + { + LOG( ERROR ) + << "Error while getting IVRNotifications interface" + << vr::VR_GetVRInitErrorAsEnglishDescription( + eError ); + vrnotification = nullptr; + } + else + { + vr::NotificationBitmap_t* messageIconPtr = nullptr; + /* + // Can i even create this object on the stack, who takes + ownership? vr::NotificationBitmap_t messageIcon; + + // First get image width and height + vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(), + nullptr, 0, (uint32_t*)&messageIcon.m_nWidth, + (uint32_t*)&messageIcon.m_nHeight); + + messageIcon.m_nBytesPerPixel = 4; + unsigned bufferSize = + messageIcon.m_nWidth*messageIcon.m_nHeight*messageIcon.m_nBytesPerPixel; + + // Can I delete this buffer after this section? Who + takes ownership? std::unique_ptr imageBuffer; + imageBuffer.reset(new char[bufferSize]); + messageIcon.m_pImageData = imageBuffer.get(); + + // Get image data + auto iconError = + vr::VROverlay()->GetOverlayImageData(parent->overlayThumbnailHandle(), + messageIcon.m_pImageData, bufferSize, + (uint32_t*)&messageIcon.m_nWidth, + (uint32_t*)&messageIcon.m_nHeight); if (iconError != + vr::VROverlayError_None) { LOG(ERROR) << "Error while + getting message overlay icon: " << + vr::VROverlay()->GetOverlayErrorNameFromEnum(iconError); + } else { + messageIconPtr = &messageIcon; + } + */ + auto nError = vrnotification->CreateNotification( + parent->overlayHandle(), + 666, + vr::EVRNotificationType_Transient, + alarmMessageBuffer, + vr::EVRNotificationStyle_Application, + messageIconPtr, + ¬ificationId ); + if ( nError != vr::VRNotificationError_OK ) + { + LOG( ERROR ) + << "Error while creating notification: " + << nError; + vrnotification = nullptr; } } } } + m_alarmLastCheckTime = now; + } - settingsUpdateCounter = 0; - } else { - settingsUpdateCounter++; - } + // attach battery overlay to all tracked devices that aren't a + // controller or hmd + for ( vr::TrackedDeviceIndex_t i = 0; i < vr::k_unMaxTrackedDeviceCount; + i++ ) + { + vr::ETrackedDeviceClass deviceClass + = vr::VRSystem()->GetTrackedDeviceClass( i ); + if ( deviceClass + == vr::ETrackedDeviceClass::TrackedDeviceClass_GenericTracker ) + { + if ( m_batteryOverlayHandles[i] + == vr::k_ulOverlayHandleInvalid ) + { + LOG( INFO ) << "Creating battery overlay for device " << i; + m_batteryOverlayHandles[i] = createBatteryOverlay( i ); + m_batteryVisible[i] = true; + } + + bool shouldShow = vr::VROverlay()->IsDashboardVisible(); + + if ( shouldShow != m_batteryVisible[i] ) + { + if ( shouldShow ) + { + vr::VROverlay()->ShowOverlay( + m_batteryOverlayHandles[i] ); + } + else + { + vr::VROverlay()->HideOverlay( + m_batteryOverlayHandles[i] ); + } + m_batteryVisible[i] = shouldShow; + } + + bool hasBatteryStatus + = vr::VRSystem()->GetBoolTrackedDeviceProperty( + i, + vr::ETrackedDeviceProperty:: + Prop_DeviceProvidesBatteryStatus_Bool ); + if ( hasBatteryStatus ) + { + float battery + = vr::VRSystem()->GetFloatTrackedDeviceProperty( + i, + vr::ETrackedDeviceProperty:: + Prop_DeviceBatteryPercentage_Float ); + int batteryState = ceil( battery * 5 ); + + if ( batteryState != m_batteryState[i] ) + { + LOG( INFO ) + << "Updating battery overlay for device " << i + << " to " << batteryState << "(" << battery << ""; + std::string batteryIconPath + = QApplication::applicationDirPath().toStdString() + + "/res/battery_" + std::to_string( batteryState ) + + ".png"; + if ( QFile::exists( + QString::fromStdString( batteryIconPath ) ) ) + { + vr::VROverlay()->SetOverlayFromFile( + m_batteryOverlayHandles[i], + batteryIconPath.c_str() ); + } + else + { + LOG( ERROR ) << "Could not find battery icon \"" + << batteryIconPath << "\""; + } + m_batteryState[i] = batteryState; + } + } + } + } + + settingsUpdateCounter = 0; } + else + { + settingsUpdateCounter++; + } +} +bool UtilitiesTabController::steamDesktopOverlayAvailable() const +{ + return m_steamDesktopOverlayAvailable; +} - bool UtilitiesTabController::steamDesktopOverlayAvailable() const { - return m_steamDesktopOverlayAvailable; - } +float UtilitiesTabController::steamDesktopOverlayWidth() const +{ + return m_steamDesktopOverlayWidth; +} - float UtilitiesTabController::steamDesktopOverlayWidth() const { - return m_steamDesktopOverlayWidth; - } +void UtilitiesTabController::setSteamDesktopOverlayWidth( float width, + bool notify, + bool notifyOpenVr ) +{ + if ( std::abs( m_steamDesktopOverlayWidth - width ) > 0.01 ) + { + m_steamDesktopOverlayWidth = width; + if ( notifyOpenVr ) + { + vr::VROverlayHandle_t pOverlayHandle; + auto error = vr::VROverlay()->FindOverlay( steamDesktopOverlaykey, + &pOverlayHandle ); + if ( error != vr::VROverlayError_None ) + { + LOG( ERROR ) + << "Could not find overlay \"" << steamDesktopOverlaykey + << "\": " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( error ); + } + else + { + error = vr::VROverlay()->SetOverlayWidthInMeters( + pOverlayHandle, m_steamDesktopOverlayWidth ); + if ( error != vr::VROverlayError_None ) + { + LOG( ERROR ) + << "Could not modify overlay width of \"" + << steamDesktopOverlaykey << "\": " + << vr::VROverlay()->GetOverlayErrorNameFromEnum( + error ); + } + } + } + if ( notify ) + { + emit steamDesktopOverlayWidthChanged( m_steamDesktopOverlayWidth ); + } + } +} - void UtilitiesTabController::setSteamDesktopOverlayWidth(float width, bool notify, bool notifyOpenVr) { - if (std::abs(m_steamDesktopOverlayWidth - width) > 0.01) { - m_steamDesktopOverlayWidth = width; - if (notifyOpenVr) { - vr::VROverlayHandle_t pOverlayHandle; - auto error = vr::VROverlay()->FindOverlay(steamDesktopOverlaykey, &pOverlayHandle); - if (error != vr::VROverlayError_None) { - LOG(ERROR) << "Could not find overlay \"" << steamDesktopOverlaykey << "\": " << vr::VROverlay()->GetOverlayErrorNameFromEnum(error); - } else { - error = vr::VROverlay()->SetOverlayWidthInMeters(pOverlayHandle, m_steamDesktopOverlayWidth); - if (error != vr::VROverlayError_None) { - LOG(ERROR) << "Could not modify overlay width of \"" << steamDesktopOverlaykey << "\": " << vr::VROverlay()->GetOverlayErrorNameFromEnum(error); - } - } - } - if (notify) { - emit steamDesktopOverlayWidthChanged(m_steamDesktopOverlayWidth); - } - } - } - - -} // namespace advconfig +} // namespace advsettings diff --git a/src/tabcontrollers/UtilitiesTabController.h b/src/tabcontrollers/UtilitiesTabController.h index 29d24e6..375e2e4 100644 --- a/src/tabcontrollers/UtilitiesTabController.h +++ b/src/tabcontrollers/UtilitiesTabController.h @@ -9,77 +9,88 @@ class QQuickWindow; // application namespace -namespace advsettings { +namespace advsettings +{ +// forward declaration +class OverlayController; - // forward declaration - class OverlayController; +class UtilitiesTabController : public QObject +{ + Q_OBJECT + Q_PROPERTY( bool alarmEnabled READ alarmEnabled WRITE setAlarmEnabled NOTIFY + alarmEnabledChanged ) + Q_PROPERTY( bool alarmIsModal READ alarmIsModal WRITE setAlarmIsModal NOTIFY + alarmIsModalChanged ) + Q_PROPERTY( int alarmTimeHour READ alarmTimeHour WRITE setAlarmTimeHour + NOTIFY alarmTimeHourChanged ) + Q_PROPERTY( int alarmTimeMinute READ alarmTimeMinute WRITE + setAlarmTimeMinute NOTIFY alarmTimeMinuteChanged ) + Q_PROPERTY( + bool steamDesktopOverlayAvailable READ steamDesktopOverlayAvailable + NOTIFY steamDesktopOverlayAvailableChanged ) + Q_PROPERTY( + float steamDesktopOverlayWidth READ steamDesktopOverlayWidth WRITE + setSteamDesktopOverlayWidth NOTIFY steamDesktopOverlayWidthChanged ) +private: + OverlayController* parent; + QQuickWindow* widget; - class UtilitiesTabController : public QObject { - Q_OBJECT - Q_PROPERTY(bool alarmEnabled READ alarmEnabled WRITE setAlarmEnabled NOTIFY alarmEnabledChanged) - Q_PROPERTY(bool alarmIsModal READ alarmIsModal WRITE setAlarmIsModal NOTIFY alarmIsModalChanged) - Q_PROPERTY(int alarmTimeHour READ alarmTimeHour WRITE setAlarmTimeHour NOTIFY alarmTimeHourChanged) - Q_PROPERTY(int alarmTimeMinute READ alarmTimeMinute WRITE setAlarmTimeMinute NOTIFY alarmTimeMinuteChanged) - Q_PROPERTY(bool steamDesktopOverlayAvailable READ steamDesktopOverlayAvailable NOTIFY steamDesktopOverlayAvailableChanged) - Q_PROPERTY(float steamDesktopOverlayWidth READ steamDesktopOverlayWidth WRITE setSteamDesktopOverlayWidth NOTIFY steamDesktopOverlayWidthChanged) + unsigned settingsUpdateCounter = 0; - private: - OverlayController* parent; - QQuickWindow* widget; + bool m_alarmEnabled = false; + bool m_alarmIsModal = true; + QTime m_alarmTime; + QTime m_alarmLastCheckTime; + bool m_steamDesktopOverlayAvailable = false; + float m_steamDesktopOverlayWidth = 4.0f; + vr::VROverlayHandle_t + m_batteryOverlayHandles[vr::k_unMaxTrackedDeviceCount]; + int m_batteryState[vr::k_unMaxTrackedDeviceCount]; + bool m_batteryVisible[vr::k_unMaxTrackedDeviceCount]; - unsigned settingsUpdateCounter = 0; + std::unique_ptr keyboardInput; - bool m_alarmEnabled = false; - bool m_alarmIsModal = true; - QTime m_alarmTime; - QTime m_alarmLastCheckTime; - bool m_steamDesktopOverlayAvailable = false; - float m_steamDesktopOverlayWidth = 4.0f; - vr::VROverlayHandle_t m_batteryOverlayHandles[vr::k_unMaxTrackedDeviceCount]; - int m_batteryState[vr::k_unMaxTrackedDeviceCount]; - bool m_batteryVisible[vr::k_unMaxTrackedDeviceCount]; +public: + void initStage1(); + void initStage2( OverlayController* parent, QQuickWindow* widget ); - std::unique_ptr keyboardInput; + void eventLoopTick(); - public: - void initStage1(); - void initStage2(OverlayController* parent, QQuickWindow* widget); + bool alarmEnabled() const; + bool alarmIsModal() const; + int alarmTimeHour() const; + int alarmTimeMinute() const; - void eventLoopTick(); + bool steamDesktopOverlayAvailable() const; + float steamDesktopOverlayWidth() const; - bool alarmEnabled() const; - bool alarmIsModal() const; - int alarmTimeHour() const; - int alarmTimeMinute() const; +public slots: + void sendKeyboardInput( QString input ); + void sendKeyboardEnter(); + void sendKeyboardAltTab(); + void sendKeyboardBackspace( int count ); - bool steamDesktopOverlayAvailable() const; - float steamDesktopOverlayWidth() const; + void setAlarmEnabled( bool enabled, bool notify = true ); + void setAlarmIsModal( bool modal, bool notify = true ); + void setAlarmTimeHour( int hour, bool notify = true ); + void setAlarmTimeMinute( int min, bool notify = true ); + void setAlarmTimeToCurrentTime(); + void modAlarmTimeHour( int value, bool notify = true ); + void modAlarmTimeMinute( int value, bool notify = true ); - public slots: - void sendKeyboardInput(QString input); - void sendKeyboardEnter(); - void sendKeyboardAltTab(); - void sendKeyboardBackspace(int count); + void setSteamDesktopOverlayWidth( float width, + bool notify = true, + bool notifyOpenVr = true ); - void setAlarmEnabled(bool enabled, bool notify = true); - void setAlarmIsModal(bool modal, bool notify = true); - void setAlarmTimeHour(int hour, bool notify = true); - void setAlarmTimeMinute(int min, bool notify = true); - void setAlarmTimeToCurrentTime(); - void modAlarmTimeHour(int value, bool notify = true); - void modAlarmTimeMinute(int value, bool notify = true); +signals: + void alarmEnabledChanged( bool enabled ); + void alarmIsModalChanged( bool modal ); + void alarmTimeHourChanged( int hour ); + void alarmTimeMinuteChanged( int min ); - void setSteamDesktopOverlayWidth(float width, bool notify = true, bool notifyOpenVr = true); - - signals: - void alarmEnabledChanged(bool enabled); - void alarmIsModalChanged(bool modal); - void alarmTimeHourChanged(int hour); - void alarmTimeMinuteChanged(int min); - - void steamDesktopOverlayAvailableChanged(bool available); - void steamDesktopOverlayWidthChanged(float width); - }; + void steamDesktopOverlayAvailableChanged( bool available ); + void steamDesktopOverlayWidthChanged( float width ); +}; } // namespace advsettings diff --git a/src/tabcontrollers/audiomanager/AudioManagerDummy.cpp b/src/tabcontrollers/audiomanager/AudioManagerDummy.cpp index a36781b..3316d3a 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerDummy.cpp +++ b/src/tabcontrollers/audiomanager/AudioManagerDummy.cpp @@ -1,23 +1,23 @@ #include "AudioManagerDummy.h" -// Used to get the compiler to shut up about C4100: unreferenced formal parameter. -// The cast is to get GCC to shut up about it. -#define UNREFERENCED_PARAMETER(P) static_cast((P)) +// Used to get the compiler to shut up about C4100: unreferenced formal +// parameter. The cast is to get GCC to shut up about it. +#define UNREFERENCED_PARAMETER( P ) static_cast( ( P ) ) // application namespace -namespace advsettings { - -void AudioManagerDummy::init(AudioTabController *controller) +namespace advsettings +{ +void AudioManagerDummy::init( AudioTabController* controller ) { // noop - UNREFERENCED_PARAMETER(controller); + UNREFERENCED_PARAMETER( controller ); } -void AudioManagerDummy::setPlaybackDevice(const std::string &id, bool notify) +void AudioManagerDummy::setPlaybackDevice( const std::string& id, bool notify ) { // noop - UNREFERENCED_PARAMETER(id); - UNREFERENCED_PARAMETER(notify); + UNREFERENCED_PARAMETER( id ); + UNREFERENCED_PARAMETER( notify ); } std::string AudioManagerDummy::getPlaybackDevName() @@ -30,11 +30,11 @@ std::string AudioManagerDummy::getPlaybackDevId() return "dummy"; } -void AudioManagerDummy::setMirrorDevice(const std::string &id, bool notify) +void AudioManagerDummy::setMirrorDevice( const std::string& id, bool notify ) { // noop - UNREFERENCED_PARAMETER(id); - UNREFERENCED_PARAMETER(notify); + UNREFERENCED_PARAMETER( id ); + UNREFERENCED_PARAMETER( notify ); } bool AudioManagerDummy::isMirrorValid() @@ -57,9 +57,9 @@ float AudioManagerDummy::getMirrorVolume() return 0; } -bool AudioManagerDummy::setMirrorVolume(float value) +bool AudioManagerDummy::setMirrorVolume( float value ) { - UNREFERENCED_PARAMETER(value); + UNREFERENCED_PARAMETER( value ); return false; } @@ -68,9 +68,9 @@ bool AudioManagerDummy::getMirrorMuted() return true; } -bool AudioManagerDummy::setMirrorMuted(bool value) +bool AudioManagerDummy::setMirrorMuted( bool value ) { - UNREFERENCED_PARAMETER(value); + UNREFERENCED_PARAMETER( value ); return false; } @@ -79,11 +79,11 @@ bool AudioManagerDummy::isMicValid() return false; } -void AudioManagerDummy::setMicDevice(const std::string &id, bool notify) +void AudioManagerDummy::setMicDevice( const std::string& id, bool notify ) { // noop - UNREFERENCED_PARAMETER(id); - UNREFERENCED_PARAMETER(notify); + UNREFERENCED_PARAMETER( id ); + UNREFERENCED_PARAMETER( notify ); } std::string AudioManagerDummy::getMicDevName() @@ -101,9 +101,9 @@ float AudioManagerDummy::getMicVolume() return 0; } -bool AudioManagerDummy::setMicVolume(float value) +bool AudioManagerDummy::setMicVolume( float value ) { - UNREFERENCED_PARAMETER(value); + UNREFERENCED_PARAMETER( value ); return false; } @@ -112,22 +112,22 @@ bool AudioManagerDummy::getMicMuted() return true; } -bool AudioManagerDummy::setMicMuted(bool value) +bool AudioManagerDummy::setMicMuted( bool value ) { - UNREFERENCED_PARAMETER(value); + UNREFERENCED_PARAMETER( value ); return false; } -std::vector > AudioManagerDummy::getRecordingDevices() +std::vector> + AudioManagerDummy::getRecordingDevices() { return {}; } -std::vector > AudioManagerDummy::getPlaybackDevices() +std::vector> + AudioManagerDummy::getPlaybackDevices() { return {}; } - - -} +} // namespace advsettings diff --git a/src/tabcontrollers/audiomanager/AudioManagerDummy.h b/src/tabcontrollers/audiomanager/AudioManagerDummy.h index 5094f10..490ceb9 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerDummy.h +++ b/src/tabcontrollers/audiomanager/AudioManagerDummy.h @@ -4,39 +4,43 @@ #include "../AudioManager.h" // application namespace -namespace advsettings { - +namespace advsettings +{ class AudioManagerDummy : public AudioManager { public: + virtual void init( AudioTabController* controller ) override; - virtual void init(AudioTabController* controller) override; - - virtual void setPlaybackDevice(const std::string& id, bool notify = true) override; + virtual void setPlaybackDevice( const std::string& id, + bool notify = true ) override; virtual std::string getPlaybackDevName() override; virtual std::string getPlaybackDevId() override; - virtual void setMirrorDevice(const std::string& id, bool notify = true) override; + virtual void setMirrorDevice( const std::string& id, + bool notify = true ) override; virtual bool isMirrorValid() override; virtual std::string getMirrorDevName() override; virtual std::string getMirrorDevId() override; virtual float getMirrorVolume() override; - virtual bool setMirrorVolume(float value) override; + virtual bool setMirrorVolume( float value ) override; virtual bool getMirrorMuted() override; - virtual bool setMirrorMuted(bool value) override; + virtual bool setMirrorMuted( bool value ) override; virtual bool isMicValid() override; - virtual void setMicDevice(const std::string& id, bool notify = true) override; + virtual void setMicDevice( const std::string& id, + bool notify = true ) override; virtual std::string getMicDevName() override; virtual std::string getMicDevId() override; virtual float getMicVolume() override; - virtual bool setMicVolume(float value) override; + virtual bool setMicVolume( float value ) override; virtual bool getMicMuted() override; - virtual bool setMicMuted(bool value) override; + virtual bool setMicMuted( bool value ) override; - virtual std::vector> getRecordingDevices() override; - virtual std::vector> getPlaybackDevices() override; + virtual std::vector> + getRecordingDevices() override; + virtual std::vector> + getPlaybackDevices() override; }; -} +} // namespace advsettings #endif // AUDIOMANAGERLINUX_H diff --git a/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp b/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp index b05fcf5..5cb9238 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp +++ b/src/tabcontrollers/audiomanager/AudioManagerWindows.cpp @@ -6,481 +6,680 @@ #include #include - // application namespace -namespace advsettings { - -AudioManagerWindows::~AudioManagerWindows() { - std::lock_guard lock(_mutex); - audioDeviceEnumerator->UnregisterEndpointNotificationCallback((IMMNotificationClient*)this); - if (mirrorAudioEndpointVolume) { - mirrorAudioEndpointVolume->Release(); - } - if (micAudioEndpointVolume) { - micAudioEndpointVolume->Release(); - } - if (mirrorAudioDevice) { - mirrorAudioDevice->Release(); - } - if (micAudioDevice) { - micAudioDevice->Release(); - } - if (playbackAudioDevice) { - playbackAudioDevice->Release(); - } - audioDeviceEnumerator->Release(); +namespace advsettings +{ +AudioManagerWindows::~AudioManagerWindows() +{ + std::lock_guard lock( _mutex ); + audioDeviceEnumerator->UnregisterEndpointNotificationCallback( + ( IMMNotificationClient* ) this ); + if ( mirrorAudioEndpointVolume ) + { + mirrorAudioEndpointVolume->Release(); + } + if ( micAudioEndpointVolume ) + { + micAudioEndpointVolume->Release(); + } + if ( mirrorAudioDevice ) + { + mirrorAudioDevice->Release(); + } + if ( micAudioDevice ) + { + micAudioDevice->Release(); + } + if ( playbackAudioDevice ) + { + playbackAudioDevice->Release(); + } + audioDeviceEnumerator->Release(); } -void AudioManagerWindows::init(AudioTabController* var_controller) { - std::lock_guard lock(_mutex); - audioDeviceEnumerator = getAudioDeviceEnumerator(); - if (!audioDeviceEnumerator) { - throw std::exception("Could not create audio device enumerator"); - } - playbackAudioDevice = getDefaultPlaybackDevice(audioDeviceEnumerator); - if (!playbackAudioDevice) { - LOG(WARNING) << "Could not find a default recording device."; - } - micAudioDevice = getDefaultRecordingDevice(audioDeviceEnumerator); - if (micAudioDevice) { - micAudioEndpointVolume = getAudioEndpointVolume(micAudioDevice); - } else { - LOG(WARNING) << "Could not find a default recording device."; - } - this->controller = var_controller; - audioDeviceEnumerator->RegisterEndpointNotificationCallback((IMMNotificationClient*)this); - policyConfig = getPolicyConfig(); - if (!policyConfig) { - LOG(ERROR) << "Could not find PolicyConfig interface"; - } +void AudioManagerWindows::init( AudioTabController* var_controller ) +{ + std::lock_guard lock( _mutex ); + audioDeviceEnumerator = getAudioDeviceEnumerator(); + if ( !audioDeviceEnumerator ) + { + throw std::exception( "Could not create audio device enumerator" ); + } + playbackAudioDevice = getDefaultPlaybackDevice( audioDeviceEnumerator ); + if ( !playbackAudioDevice ) + { + LOG( WARNING ) << "Could not find a default recording device."; + } + micAudioDevice = getDefaultRecordingDevice( audioDeviceEnumerator ); + if ( micAudioDevice ) + { + micAudioEndpointVolume = getAudioEndpointVolume( micAudioDevice ); + } + else + { + LOG( WARNING ) << "Could not find a default recording device."; + } + this->controller = var_controller; + audioDeviceEnumerator->RegisterEndpointNotificationCallback( + ( IMMNotificationClient* ) this ); + policyConfig = getPolicyConfig(); + if ( !policyConfig ) + { + LOG( ERROR ) << "Could not find PolicyConfig interface"; + } } -void AudioManagerWindows::setPlaybackDevice(const std::string & id, bool notify) { - std::lock_guard lock(_mutex); - if (!id.empty()) { - auto dev = getDevice(audioDeviceEnumerator, id); - if (!dev) { - LOG(WARNING) << "Could not find playback device \"" << id << "\"."; - } else { - playbackAudioDevice = dev; - if (policyConfig) { - LPWSTR devId; - if (dev->GetId(&devId) >= 0) { - policyConfig->SetDefaultEndpoint(devId, eConsole); - } - } - } - } - if (notify) { - controller->onNewPlaybackDevice(); - } +void AudioManagerWindows::setPlaybackDevice( const std::string& id, + bool notify ) +{ + std::lock_guard lock( _mutex ); + if ( !id.empty() ) + { + auto dev = getDevice( audioDeviceEnumerator, id ); + if ( !dev ) + { + LOG( WARNING ) << "Could not find playback device \"" << id + << "\"."; + } + else + { + playbackAudioDevice = dev; + if ( policyConfig ) + { + LPWSTR devId; + if ( dev->GetId( &devId ) >= 0 ) + { + policyConfig->SetDefaultEndpoint( devId, eConsole ); + } + } + } + } + if ( notify ) + { + controller->onNewPlaybackDevice(); + } } -std::string AudioManagerWindows::getPlaybackDevName() { - std::lock_guard lock(_mutex); - if (playbackAudioDevice) { - return getDeviceName(playbackAudioDevice); - } - return ""; +std::string AudioManagerWindows::getPlaybackDevName() +{ + std::lock_guard lock( _mutex ); + if ( playbackAudioDevice ) + { + return getDeviceName( playbackAudioDevice ); + } + return ""; } -std::string AudioManagerWindows::getPlaybackDevId() { - std::lock_guard lock(_mutex); - if (playbackAudioDevice) { - return getDeviceId(playbackAudioDevice); - } - return ""; +std::string AudioManagerWindows::getPlaybackDevId() +{ + std::lock_guard lock( _mutex ); + if ( playbackAudioDevice ) + { + return getDeviceId( playbackAudioDevice ); + } + return ""; } - -void AudioManagerWindows::setMirrorDevice(const std::string& id, bool notify) { - std::lock_guard lock(_mutex); - if (id.empty()) { - deleteMirrorDevice(); - if (notify) { - controller->onNewMirrorDevice(); - } - } else { - auto dev = getDevice(audioDeviceEnumerator, id); - if (dev) { - mirrorAudioDevice = dev; - mirrorAudioEndpointVolume = getAudioEndpointVolume(mirrorAudioDevice); - } else { - LOG(WARNING) << "Could not find mirror device \"" << id << "\"."; - } - } - if (notify) { - controller->onNewMirrorDevice(); - } +void AudioManagerWindows::setMirrorDevice( const std::string& id, bool notify ) +{ + std::lock_guard lock( _mutex ); + if ( id.empty() ) + { + deleteMirrorDevice(); + if ( notify ) + { + controller->onNewMirrorDevice(); + } + } + else + { + auto dev = getDevice( audioDeviceEnumerator, id ); + if ( dev ) + { + mirrorAudioDevice = dev; + mirrorAudioEndpointVolume + = getAudioEndpointVolume( mirrorAudioDevice ); + } + else + { + LOG( WARNING ) << "Could not find mirror device \"" << id << "\"."; + } + } + if ( notify ) + { + controller->onNewMirrorDevice(); + } } -void AudioManagerWindows::deleteMirrorDevice() { - if (mirrorAudioEndpointVolume) { - mirrorAudioEndpointVolume->Release(); - mirrorAudioEndpointVolume = nullptr; - } - if (mirrorAudioDevice) { - mirrorAudioDevice->Release(); - mirrorAudioDevice = nullptr; - } +void AudioManagerWindows::deleteMirrorDevice() +{ + if ( mirrorAudioEndpointVolume ) + { + mirrorAudioEndpointVolume->Release(); + mirrorAudioEndpointVolume = nullptr; + } + if ( mirrorAudioDevice ) + { + mirrorAudioDevice->Release(); + mirrorAudioDevice = nullptr; + } } -bool AudioManagerWindows::isMirrorValid() { - return mirrorAudioEndpointVolume != nullptr; +bool AudioManagerWindows::isMirrorValid() +{ + return mirrorAudioEndpointVolume != nullptr; } -std::string AudioManagerWindows::getMirrorDevName() { - std::lock_guard lock(_mutex); - if (mirrorAudioDevice) { - return getDeviceName(mirrorAudioDevice); - } - return ""; +std::string AudioManagerWindows::getMirrorDevName() +{ + std::lock_guard lock( _mutex ); + if ( mirrorAudioDevice ) + { + return getDeviceName( mirrorAudioDevice ); + } + return ""; } -std::string AudioManagerWindows::getMirrorDevId() { - std::lock_guard lock(_mutex); - if (mirrorAudioDevice) { - return getDeviceId(mirrorAudioDevice); - } - return ""; +std::string AudioManagerWindows::getMirrorDevId() +{ + std::lock_guard lock( _mutex ); + if ( mirrorAudioDevice ) + { + return getDeviceId( mirrorAudioDevice ); + } + return ""; } -float AudioManagerWindows::getMirrorVolume() { - float value; - if (mirrorAudioEndpointVolume && mirrorAudioEndpointVolume->GetMasterVolumeLevelScalar(&value) >= 0) { - return value; - } else { - return 0.0; - } +float AudioManagerWindows::getMirrorVolume() +{ + float value; + if ( mirrorAudioEndpointVolume + && mirrorAudioEndpointVolume->GetMasterVolumeLevelScalar( &value ) + >= 0 ) + { + return value; + } + else + { + return 0.0; + } } -bool AudioManagerWindows::setMirrorVolume(float value) { - if (mirrorAudioEndpointVolume) { - if (mirrorAudioEndpointVolume->SetMasterVolumeLevelScalar(value, nullptr) >= 0) { - return true; - } - } - return false; +bool AudioManagerWindows::setMirrorVolume( float value ) +{ + if ( mirrorAudioEndpointVolume ) + { + if ( mirrorAudioEndpointVolume->SetMasterVolumeLevelScalar( value, + nullptr ) + >= 0 ) + { + return true; + } + } + return false; } -bool AudioManagerWindows::getMirrorMuted() { - BOOL value; - if (mirrorAudioEndpointVolume && mirrorAudioEndpointVolume->GetMute(&value) >= 0) { - return value; - } else { - return false; - } +bool AudioManagerWindows::getMirrorMuted() +{ + BOOL value; + if ( mirrorAudioEndpointVolume + && mirrorAudioEndpointVolume->GetMute( &value ) >= 0 ) + { + return value; + } + else + { + return false; + } } -bool AudioManagerWindows::setMirrorMuted(bool value) { - if (mirrorAudioEndpointVolume) { - if (mirrorAudioEndpointVolume->SetMute(value, nullptr) >= 0) { - return true; - } - } - return false; +bool AudioManagerWindows::setMirrorMuted( bool value ) +{ + if ( mirrorAudioEndpointVolume ) + { + if ( mirrorAudioEndpointVolume->SetMute( value, nullptr ) >= 0 ) + { + return true; + } + } + return false; } - -bool AudioManagerWindows::isMicValid() { - return micAudioEndpointVolume != nullptr; +bool AudioManagerWindows::isMicValid() +{ + return micAudioEndpointVolume != nullptr; } -void AudioManagerWindows::setMicDevice(const std::string & id, bool notify) { - std::lock_guard lock(_mutex); - if (!id.empty()) { - auto dev = getDevice(audioDeviceEnumerator, id); - if (!dev) { - LOG(WARNING) << "Could not find recording device \"" << id << "\"."; - } else { - micAudioDevice = dev; - if (policyConfig) { - LPWSTR devId; - if (dev->GetId(&devId) >= 0) { - policyConfig->SetDefaultEndpoint(devId, eConsole); - } - } - } - } - if (notify) { - controller->onNewRecordingDevice(); - } +void AudioManagerWindows::setMicDevice( const std::string& id, bool notify ) +{ + std::lock_guard lock( _mutex ); + if ( !id.empty() ) + { + auto dev = getDevice( audioDeviceEnumerator, id ); + if ( !dev ) + { + LOG( WARNING ) << "Could not find recording device \"" << id + << "\"."; + } + else + { + micAudioDevice = dev; + if ( policyConfig ) + { + LPWSTR devId; + if ( dev->GetId( &devId ) >= 0 ) + { + policyConfig->SetDefaultEndpoint( devId, eConsole ); + } + } + } + } + if ( notify ) + { + controller->onNewRecordingDevice(); + } } -std::string AudioManagerWindows::getMicDevName() { - std::lock_guard lock(_mutex); - if (micAudioDevice) { - return getDeviceName(micAudioDevice); - } - return ""; +std::string AudioManagerWindows::getMicDevName() +{ + std::lock_guard lock( _mutex ); + if ( micAudioDevice ) + { + return getDeviceName( micAudioDevice ); + } + return ""; } -std::string AudioManagerWindows::getMicDevId() { - std::lock_guard lock(_mutex); - if (micAudioDevice) { - return getDeviceId(micAudioDevice); - } - return ""; +std::string AudioManagerWindows::getMicDevId() +{ + std::lock_guard lock( _mutex ); + if ( micAudioDevice ) + { + return getDeviceId( micAudioDevice ); + } + return ""; } -float AudioManagerWindows::getMicVolume() { - float value; - if (micAudioEndpointVolume && micAudioEndpointVolume->GetMasterVolumeLevelScalar(&value) >= 0) { - return value; - } else { - return 0.0; - } +float AudioManagerWindows::getMicVolume() +{ + float value; + if ( micAudioEndpointVolume + && micAudioEndpointVolume->GetMasterVolumeLevelScalar( &value ) >= 0 ) + { + return value; + } + else + { + return 0.0; + } } -bool AudioManagerWindows::setMicVolume(float value) { - if (micAudioEndpointVolume) { - if (micAudioEndpointVolume->SetMasterVolumeLevelScalar(value, nullptr) >= 0) { - return true; - } - } - return false; +bool AudioManagerWindows::setMicVolume( float value ) +{ + if ( micAudioEndpointVolume ) + { + if ( micAudioEndpointVolume->SetMasterVolumeLevelScalar( value, + nullptr ) + >= 0 ) + { + return true; + } + } + return false; } -bool AudioManagerWindows::getMicMuted() { - BOOL value; - if (micAudioEndpointVolume && micAudioEndpointVolume->GetMute(&value) >= 0) { - return value; - } else { - return false; - } +bool AudioManagerWindows::getMicMuted() +{ + BOOL value; + if ( micAudioEndpointVolume + && micAudioEndpointVolume->GetMute( &value ) >= 0 ) + { + return value; + } + else + { + return false; + } } -bool AudioManagerWindows::setMicMuted(bool value) { - if (micAudioEndpointVolume) { - if (micAudioEndpointVolume->SetMute(value, nullptr) >= 0) { - return true; - } - } - return false; +bool AudioManagerWindows::setMicMuted( bool value ) +{ + if ( micAudioEndpointVolume ) + { + if ( micAudioEndpointVolume->SetMute( value, nullptr ) >= 0 ) + { + return true; + } + } + return false; } -std::vector> AudioManagerWindows::getRecordingDevices() { - return getDevices(audioDeviceEnumerator, eCapture); +std::vector> + AudioManagerWindows::getRecordingDevices() +{ + return getDevices( audioDeviceEnumerator, eCapture ); } -std::vector> AudioManagerWindows::getPlaybackDevices() { - return getDevices(audioDeviceEnumerator, eRender); +std::vector> + AudioManagerWindows::getPlaybackDevices() +{ + return getDevices( audioDeviceEnumerator, eRender ); } - -IMMDeviceEnumerator* AudioManagerWindows::getAudioDeviceEnumerator() { - IMMDeviceEnumerator* pEnumerator; - if (CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator) < 0) { - return nullptr; - } - return pEnumerator; +IMMDeviceEnumerator* AudioManagerWindows::getAudioDeviceEnumerator() +{ + IMMDeviceEnumerator* pEnumerator; + if ( CoCreateInstance( __uuidof( MMDeviceEnumerator ), + NULL, + CLSCTX_ALL, + __uuidof( IMMDeviceEnumerator ), + ( void** ) &pEnumerator ) + < 0 ) + { + return nullptr; + } + return pEnumerator; } -IPolicyConfig * AudioManagerWindows::getPolicyConfig() { - IPolicyConfig* var_policyConfig = nullptr; - // for Win 10 - auto hr = CoCreateInstance(__uuidof(CPolicyConfigClient), NULL, CLSCTX_INPROC, IID_IPolicyConfig2, (LPVOID *)&var_policyConfig); - if (hr != S_OK) { - hr = CoCreateInstance(__uuidof(CPolicyConfigClient), NULL, CLSCTX_INPROC, IID_IPolicyConfig1, (LPVOID *)&var_policyConfig); - } - // for Win Vista, 7, 8, 8.1 - if (hr != S_OK) { - hr = CoCreateInstance(__uuidof(CPolicyConfigClient), NULL, CLSCTX_INPROC, IID_IPolicyConfig0, (LPVOID *)&var_policyConfig); - } - if (hr != S_OK) { - return nullptr; - } else { - return var_policyConfig; - } +IPolicyConfig* AudioManagerWindows::getPolicyConfig() +{ + IPolicyConfig* var_policyConfig = nullptr; + // for Win 10 + auto hr = CoCreateInstance( __uuidof( CPolicyConfigClient ), + NULL, + CLSCTX_INPROC, + IID_IPolicyConfig2, + ( LPVOID* ) &var_policyConfig ); + if ( hr != S_OK ) + { + hr = CoCreateInstance( __uuidof( CPolicyConfigClient ), + NULL, + CLSCTX_INPROC, + IID_IPolicyConfig1, + ( LPVOID* ) &var_policyConfig ); + } + // for Win Vista, 7, 8, 8.1 + if ( hr != S_OK ) + { + hr = CoCreateInstance( __uuidof( CPolicyConfigClient ), + NULL, + CLSCTX_INPROC, + IID_IPolicyConfig0, + ( LPVOID* ) &var_policyConfig ); + } + if ( hr != S_OK ) + { + return nullptr; + } + else + { + return var_policyConfig; + } } -IMMDevice* AudioManagerWindows::getDefaultRecordingDevice(IMMDeviceEnumerator* deviceEnumerator) { - IMMDevice* pDevice; - if (deviceEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice) < 0) { - return nullptr; - } - return pDevice; +IMMDevice* AudioManagerWindows::getDefaultRecordingDevice( + IMMDeviceEnumerator* deviceEnumerator ) +{ + IMMDevice* pDevice; + if ( deviceEnumerator->GetDefaultAudioEndpoint( + eCapture, eConsole, &pDevice ) + < 0 ) + { + return nullptr; + } + return pDevice; } -IMMDevice * AudioManagerWindows::getDefaultPlaybackDevice(IMMDeviceEnumerator * deviceEnumerator) { - IMMDevice* pDevice; - if (deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice) < 0) { - return nullptr; - } - return pDevice; +IMMDevice* AudioManagerWindows::getDefaultPlaybackDevice( + IMMDeviceEnumerator* deviceEnumerator ) +{ + IMMDevice* pDevice; + if ( deviceEnumerator->GetDefaultAudioEndpoint( + eRender, eConsole, &pDevice ) + < 0 ) + { + return nullptr; + } + return pDevice; } -IMMDevice* AudioManagerWindows::getDevice(IMMDeviceEnumerator* deviceEnumerator, const std::string& id) { - std::wstring_convert> converter; - std::wstring wid = converter.from_bytes(id); - return getDevice(deviceEnumerator, wid.c_str()); +IMMDevice* + AudioManagerWindows::getDevice( IMMDeviceEnumerator* deviceEnumerator, + const std::string& id ) +{ + std::wstring_convert> converter; + std::wstring wid = converter.from_bytes( id ); + return getDevice( deviceEnumerator, wid.c_str() ); } -IMMDevice * AudioManagerWindows::getDevice(IMMDeviceEnumerator * deviceEnumerator, LPCWSTR id) { - IMMDevice* pDevice; - if (deviceEnumerator->GetDevice(id, &pDevice) < 0) { - return nullptr; - } - return pDevice; +IMMDevice* + AudioManagerWindows::getDevice( IMMDeviceEnumerator* deviceEnumerator, + LPCWSTR id ) +{ + IMMDevice* pDevice; + if ( deviceEnumerator->GetDevice( id, &pDevice ) < 0 ) + { + return nullptr; + } + return pDevice; } -IAudioEndpointVolume * AudioManagerWindows::getAudioEndpointVolume(IMMDevice* device) { - IAudioEndpointVolume * pEndpointVolume; - if (device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (void**)&pEndpointVolume) < 0) { - return nullptr; - } - return pEndpointVolume; +IAudioEndpointVolume* + AudioManagerWindows::getAudioEndpointVolume( IMMDevice* device ) +{ + IAudioEndpointVolume* pEndpointVolume; + if ( device->Activate( __uuidof( IAudioEndpointVolume ), + CLSCTX_INPROC_SERVER, + NULL, + ( void** ) &pEndpointVolume ) + < 0 ) + { + return nullptr; + } + return pEndpointVolume; } -std::string AudioManagerWindows::getDeviceName(IMMDevice* device) { - IPropertyStore *pProps = nullptr; - PROPVARIANT varString; - if (device->OpenPropertyStore(STGM_READ, &pProps) >= 0 && pProps->GetValue(PKEY_Device_FriendlyName, &varString) >= 0) { - std::wstring_convert> converter; - std::string name = converter.to_bytes(varString.pwszVal); - return name; - } - return ""; +std::string AudioManagerWindows::getDeviceName( IMMDevice* device ) +{ + IPropertyStore* pProps = nullptr; + PROPVARIANT varString; + if ( device->OpenPropertyStore( STGM_READ, &pProps ) >= 0 + && pProps->GetValue( PKEY_Device_FriendlyName, &varString ) >= 0 ) + { + std::wstring_convert> converter; + std::string name = converter.to_bytes( varString.pwszVal ); + return name; + } + return ""; } -std::string AudioManagerWindows::getDeviceId(IMMDevice* device) { - LPWSTR ppstrId; - if (device->GetId(&ppstrId) >= 0) { - std::wstring_convert> converter; - return converter.to_bytes(ppstrId); - } - return ""; +std::string AudioManagerWindows::getDeviceId( IMMDevice* device ) +{ + LPWSTR ppstrId; + if ( device->GetId( &ppstrId ) >= 0 ) + { + std::wstring_convert> converter; + return converter.to_bytes( ppstrId ); + } + return ""; } -std::vector> AudioManagerWindows::getDevices(IMMDeviceEnumerator * deviceEnumerator, EDataFlow dataFlow) { - std::vector> retval; - IMMDeviceCollection *ppDevices = nullptr; - if (deviceEnumerator->EnumAudioEndpoints(dataFlow, DEVICE_STATE_ACTIVE, &ppDevices) >= 0) { - UINT count; - ppDevices->GetCount(&count); - for (UINT i = 0; i < count; ++i) { - IMMDevice *device = nullptr; - ppDevices->Item(i, &device); - if (device) { - retval.emplace_back(getDeviceId(device), getDeviceName(device)); - } - } - ppDevices->Release(); - } - return retval; +std::vector> + AudioManagerWindows::getDevices( IMMDeviceEnumerator* deviceEnumerator, + EDataFlow dataFlow ) +{ + std::vector> retval; + IMMDeviceCollection* ppDevices = nullptr; + if ( deviceEnumerator->EnumAudioEndpoints( + dataFlow, DEVICE_STATE_ACTIVE, &ppDevices ) + >= 0 ) + { + UINT count; + ppDevices->GetCount( &count ); + for ( UINT i = 0; i < count; ++i ) + { + IMMDevice* device = nullptr; + ppDevices->Item( i, &device ); + if ( device ) + { + retval.emplace_back( getDeviceId( device ), + getDeviceName( device ) ); + } + } + ppDevices->Release(); + } + return retval; } - -HRESULT AudioManagerWindows::QueryInterface(REFIID riid, void ** ppvObject) { - if (IID_IUnknown == riid) { - AddRef(); - *ppvObject = (IUnknown*)this; - } else if (__uuidof(IMMNotificationClient) == riid) { - AddRef(); - *ppvObject = (IMMNotificationClient*)this; - } else { - *ppvObject = NULL; - return E_NOINTERFACE; - } - return S_OK; +HRESULT AudioManagerWindows::QueryInterface( REFIID riid, void** ppvObject ) +{ + if ( IID_IUnknown == riid ) + { + AddRef(); + *ppvObject = ( IUnknown* ) this; + } + else if ( __uuidof( IMMNotificationClient ) == riid ) + { + AddRef(); + *ppvObject = ( IMMNotificationClient* ) this; + } + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + return S_OK; } -ULONG AudioManagerWindows::AddRef(void) { - return 1; // We don't need reference counting +ULONG AudioManagerWindows::AddRef( void ) +{ + return 1; // We don't need reference counting } -ULONG AudioManagerWindows::Release(void) { - return 1; // We don't need reference counting +ULONG AudioManagerWindows::Release( void ) +{ + return 1; // We don't need reference counting } -HRESULT AudioManagerWindows::OnDeviceStateChanged(LPCWSTR, DWORD) { - std::lock_guard lock(_mutex); - controller->onDeviceStateChanged(); - return S_OK; +HRESULT AudioManagerWindows::OnDeviceStateChanged( LPCWSTR, DWORD ) +{ + std::lock_guard lock( _mutex ); + controller->onDeviceStateChanged(); + return S_OK; } -HRESULT AudioManagerWindows::OnDeviceAdded(LPCWSTR) { - std::lock_guard lock(_mutex); - controller->onDeviceStateChanged(); - return S_OK; +HRESULT AudioManagerWindows::OnDeviceAdded( LPCWSTR ) +{ + std::lock_guard lock( _mutex ); + controller->onDeviceStateChanged(); + return S_OK; } -HRESULT AudioManagerWindows::OnDeviceRemoved(LPCWSTR) { - std::lock_guard lock(_mutex); - controller->onDeviceStateChanged(); - return S_OK; +HRESULT AudioManagerWindows::OnDeviceRemoved( LPCWSTR ) +{ + std::lock_guard lock( _mutex ); + controller->onDeviceStateChanged(); + return S_OK; } -HRESULT AudioManagerWindows::OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) { - std::lock_guard lock(_mutex); - if (flow == eCapture && role == eMultimedia) { - if (audioDeviceEnumerator) { - auto device = getDevice(audioDeviceEnumerator, pwstrDefaultDeviceId); - if (device != micAudioDevice) { - if (micAudioDevice) { - micAudioDevice->Release(); - } - micAudioDevice = device; - if (micAudioDevice) { - micAudioEndpointVolume = getAudioEndpointVolume(micAudioDevice); - } else { - std::wstring_convert> converter; - std::string name = converter.to_bytes(pwstrDefaultDeviceId); - LOG(WARNING) << "Could not find recording device \"" << name << "\"."; - } - controller->onNewRecordingDevice(); - } - } - } else if (flow == eRender && role == eMultimedia) { - if (audioDeviceEnumerator) { - auto device = getDevice(audioDeviceEnumerator, pwstrDefaultDeviceId); - if (device != playbackAudioDevice) { - if (playbackAudioDevice) { - playbackAudioDevice->Release(); - } - playbackAudioDevice = device; - if (!playbackAudioDevice) { - std::wstring_convert> converter; - std::string name = converter.to_bytes(pwstrDefaultDeviceId); - LOG(WARNING) << "Could not find playback device \"" << name << "\"."; - } - controller->onNewPlaybackDevice(); - } - } - } - /*char* pszFlow = (char*)"?????"; - char* pszRole = (char*)"?????"; +HRESULT +AudioManagerWindows::OnDefaultDeviceChanged( EDataFlow flow, + ERole role, + LPCWSTR pwstrDefaultDeviceId ) +{ + std::lock_guard lock( _mutex ); + if ( flow == eCapture && role == eMultimedia ) + { + if ( audioDeviceEnumerator ) + { + auto device + = getDevice( audioDeviceEnumerator, pwstrDefaultDeviceId ); + if ( device != micAudioDevice ) + { + if ( micAudioDevice ) + { + micAudioDevice->Release(); + } + micAudioDevice = device; + if ( micAudioDevice ) + { + micAudioEndpointVolume + = getAudioEndpointVolume( micAudioDevice ); + } + else + { + std::wstring_convert> + converter; + std::string name + = converter.to_bytes( pwstrDefaultDeviceId ); + LOG( WARNING ) << "Could not find recording device \"" + << name << "\"."; + } + controller->onNewRecordingDevice(); + } + } + } + else if ( flow == eRender && role == eMultimedia ) + { + if ( audioDeviceEnumerator ) + { + auto device + = getDevice( audioDeviceEnumerator, pwstrDefaultDeviceId ); + if ( device != playbackAudioDevice ) + { + if ( playbackAudioDevice ) + { + playbackAudioDevice->Release(); + } + playbackAudioDevice = device; + if ( !playbackAudioDevice ) + { + std::wstring_convert> + converter; + std::string name + = converter.to_bytes( pwstrDefaultDeviceId ); + LOG( WARNING ) + << "Could not find playback device \"" << name << "\"."; + } + controller->onNewPlaybackDevice(); + } + } + } + /*char* pszFlow = (char*)"?????"; + char* pszRole = (char*)"?????"; - switch (flow) { - case eRender: - pszFlow = (char*)"eRender"; - break; - case eCapture: - pszFlow = (char*)"eCapture"; - break; - } + switch (flow) { + case eRender: + pszFlow = (char*)"eRender"; + break; + case eCapture: + pszFlow = (char*)"eCapture"; + break; + } - switch (role) { - case eConsole: - pszRole = (char*)"eConsole"; - break; - case eMultimedia: - pszRole = (char*)"eMultimedia"; - break; - case eCommunications: - pszRole = (char*)"eCommunications"; - break; - } + switch (role) { + case eConsole: + pszRole = (char*)"eConsole"; + break; + case eMultimedia: + pszRole = (char*)"eMultimedia"; + break; + case eCommunications: + pszRole = (char*)"eCommunications"; + break; + } - std::wstring_convert> converter; - std::string name = converter.to_bytes(pwstrDefaultDeviceId); - printf(" %s -->New default device: flow = %s, role = %s\n", name.c_str(), pszFlow, pszRole); - fflush(stdout);*/ - return S_OK; + std::wstring_convert> converter; + std::string name = converter.to_bytes(pwstrDefaultDeviceId); + printf(" %s -->New default device: flow = %s, role = %s\n", name.c_str(), + pszFlow, pszRole); fflush(stdout);*/ + return S_OK; } -HRESULT AudioManagerWindows::OnPropertyValueChanged(LPCWSTR, const PROPERTYKEY) { - return S_OK; +HRESULT AudioManagerWindows::OnPropertyValueChanged( LPCWSTR, + const PROPERTYKEY ) +{ + return S_OK; } -} +} // namespace advsettings diff --git a/src/tabcontrollers/audiomanager/AudioManagerWindows.h b/src/tabcontrollers/audiomanager/AudioManagerWindows.h index 78c1541..7651b05 100644 --- a/src/tabcontrollers/audiomanager/AudioManagerWindows.h +++ b/src/tabcontrollers/audiomanager/AudioManagerWindows.h @@ -8,77 +8,91 @@ #include "IPolicyConfig.h" #include - // application namespace -namespace advsettings { +namespace advsettings +{ +class AudioManagerWindows : public AudioManager, IMMNotificationClient +{ + friend class AudioNotificationClient; -class AudioManagerWindows : public AudioManager, IMMNotificationClient { -friend class AudioNotificationClient; private: - std::recursive_mutex _mutex; - AudioTabController* controller = nullptr; - IMMDeviceEnumerator* audioDeviceEnumerator = nullptr; - IMMDevice* playbackAudioDevice = nullptr; - IMMDevice* mirrorAudioDevice = nullptr; - IAudioEndpointVolume* mirrorAudioEndpointVolume = nullptr; - IMMDevice* micAudioDevice = nullptr; - IAudioEndpointVolume* micAudioEndpointVolume = nullptr; - IPolicyConfig* policyConfig = nullptr; + std::recursive_mutex _mutex; + AudioTabController* controller = nullptr; + IMMDeviceEnumerator* audioDeviceEnumerator = nullptr; + IMMDevice* playbackAudioDevice = nullptr; + IMMDevice* mirrorAudioDevice = nullptr; + IAudioEndpointVolume* mirrorAudioEndpointVolume = nullptr; + IMMDevice* micAudioDevice = nullptr; + IAudioEndpointVolume* micAudioEndpointVolume = nullptr; + IPolicyConfig* policyConfig = nullptr; public: ~AudioManagerWindows() override; - virtual void init(AudioTabController* controller) override; + virtual void init( AudioTabController* controller ) override; - virtual void setPlaybackDevice(const std::string& id, bool notify = true) override; - virtual std::string getPlaybackDevName() override; - virtual std::string getPlaybackDevId() override; + virtual void setPlaybackDevice( const std::string& id, + bool notify = true ) override; + virtual std::string getPlaybackDevName() override; + virtual std::string getPlaybackDevId() override; - virtual void setMirrorDevice(const std::string& id, bool notify = true) override; - virtual bool isMirrorValid() override; - virtual std::string getMirrorDevName() override; - virtual std::string getMirrorDevId() override; - virtual float getMirrorVolume() override; - virtual bool setMirrorVolume(float value) override; - virtual bool getMirrorMuted() override; - virtual bool setMirrorMuted(bool value) override; + virtual void setMirrorDevice( const std::string& id, + bool notify = true ) override; + virtual bool isMirrorValid() override; + virtual std::string getMirrorDevName() override; + virtual std::string getMirrorDevId() override; + virtual float getMirrorVolume() override; + virtual bool setMirrorVolume( float value ) override; + virtual bool getMirrorMuted() override; + virtual bool setMirrorMuted( bool value ) override; - virtual bool isMicValid() override; - virtual void setMicDevice(const std::string& id, bool notify = true) override; - virtual std::string getMicDevName() override; - virtual std::string getMicDevId() override; - virtual float getMicVolume() override; - virtual bool setMicVolume(float value) override; - virtual bool getMicMuted() override; - virtual bool setMicMuted(bool value) override; + virtual bool isMicValid() override; + virtual void setMicDevice( const std::string& id, + bool notify = true ) override; + virtual std::string getMicDevName() override; + virtual std::string getMicDevId() override; + virtual float getMicVolume() override; + virtual bool setMicVolume( float value ) override; + virtual bool getMicMuted() override; + virtual bool setMicMuted( bool value ) override; - virtual std::vector> getRecordingDevices() override; - virtual std::vector> getPlaybackDevices() override; + virtual std::vector> + getRecordingDevices() override; + virtual std::vector> + getPlaybackDevices() override; - void deleteMirrorDevice(); + void deleteMirrorDevice(); - // from IMMNotificationClient - virtual HRESULT QueryInterface(REFIID riid, void ** ppvObject) override; - virtual ULONG AddRef(void) override; - virtual ULONG Release(void) override; - virtual HRESULT OnDeviceStateChanged(LPCWSTR pwstrDeviceId, DWORD dwNewState) override; - virtual HRESULT OnDeviceAdded(LPCWSTR pwstrDeviceId) override; - virtual HRESULT OnDeviceRemoved(LPCWSTR pwstrDeviceId) override; - virtual HRESULT OnDefaultDeviceChanged(EDataFlow flow, ERole role, LPCWSTR pwstrDefaultDeviceId) override; - virtual HRESULT OnPropertyValueChanged(LPCWSTR pwstrDeviceId, const PROPERTYKEY key) override; + // from IMMNotificationClient + virtual HRESULT QueryInterface( REFIID riid, void** ppvObject ) override; + virtual ULONG AddRef( void ) override; + virtual ULONG Release( void ) override; + virtual HRESULT OnDeviceStateChanged( LPCWSTR pwstrDeviceId, + DWORD dwNewState ) override; + virtual HRESULT OnDeviceAdded( LPCWSTR pwstrDeviceId ) override; + virtual HRESULT OnDeviceRemoved( LPCWSTR pwstrDeviceId ) override; + virtual HRESULT + OnDefaultDeviceChanged( EDataFlow flow, + ERole role, + LPCWSTR pwstrDefaultDeviceId ) override; + virtual HRESULT OnPropertyValueChanged( LPCWSTR pwstrDeviceId, + const PROPERTYKEY key ) override; private: - IMMDeviceEnumerator* getAudioDeviceEnumerator(); - IPolicyConfig* getPolicyConfig(); - IMMDevice* getDefaultRecordingDevice(IMMDeviceEnumerator* deviceEnumerator); - IMMDevice* getDefaultPlaybackDevice(IMMDeviceEnumerator* deviceEnumerator); - IMMDevice* getDevice(IMMDeviceEnumerator* deviceEnumerator, const std::string& id); - IMMDevice* getDevice(IMMDeviceEnumerator* deviceEnumerator, LPCWSTR id); - IAudioEndpointVolume* getAudioEndpointVolume(IMMDevice* device); - std::string getDeviceName(IMMDevice* device); - std::string getDeviceId(IMMDevice* device); - std::vector> getDevices(IMMDeviceEnumerator* deviceEnumerator, EDataFlow dataFlow); + IMMDeviceEnumerator* getAudioDeviceEnumerator(); + IPolicyConfig* getPolicyConfig(); + IMMDevice* + getDefaultRecordingDevice( IMMDeviceEnumerator* deviceEnumerator ); + IMMDevice* + getDefaultPlaybackDevice( IMMDeviceEnumerator* deviceEnumerator ); + IMMDevice* getDevice( IMMDeviceEnumerator* deviceEnumerator, + const std::string& id ); + IMMDevice* getDevice( IMMDeviceEnumerator* deviceEnumerator, LPCWSTR id ); + IAudioEndpointVolume* getAudioEndpointVolume( IMMDevice* device ); + std::string getDeviceName( IMMDevice* device ); + std::string getDeviceId( IMMDevice* device ); + std::vector> + getDevices( IMMDeviceEnumerator* deviceEnumerator, EDataFlow dataFlow ); }; -} - +} // namespace advsettings diff --git a/src/tabcontrollers/audiomanager/IPolicyConfig.h b/src/tabcontrollers/audiomanager/IPolicyConfig.h index dd8d1bd..f14daa9 100644 --- a/src/tabcontrollers/audiomanager/IPolicyConfig.h +++ b/src/tabcontrollers/audiomanager/IPolicyConfig.h @@ -5,173 +5,129 @@ // @author EreTIk // ---------------------------------------------------------------------------- - #pragma once // ca286fc3-91fd-42c3-8e9b-caafa66242e3 -static const GUID IID_IPolicyConfig2 = { 0xCA286FC3, 0x91FD, 0x42C3, { 0x8E, 0x9B, 0xCA, 0xAF, 0xA6, 0x62, 0x42, 0xE3 } }; +static const GUID IID_IPolicyConfig2 + = { 0xCA286FC3, + 0x91FD, + 0x42C3, + { 0x8E, 0x9B, 0xCA, 0xAF, 0xA6, 0x62, 0x42, 0xE3 } }; // 6be54be8-a068-4875-a49d-0c2966473b11 -static const GUID IID_IPolicyConfig1 = { 0x6BE54BE8, 0xA068, 0x4875, { 0xA4, 0x9D, 0x0C, 0x29, 0x66, 0x47, 0x3B, 0x11 } }; +static const GUID IID_IPolicyConfig1 + = { 0x6BE54BE8, + 0xA068, + 0x4875, + { 0xA4, 0x9D, 0x0C, 0x29, 0x66, 0x47, 0x3B, 0x11 } }; // f8679f50-850a-41cf-9c72-430f290290c8 -static const GUID IID_IPolicyConfig0 = { 0xF8679F50, 0x850A, 0x41CF, { 0x9C, 0x72, 0x43, 0x0F, 0x29, 0x02, 0x90, 0xC8 } }; +static const GUID IID_IPolicyConfig0 + = { 0xF8679F50, + 0x850A, + 0x41CF, + { 0x9C, 0x72, 0x43, 0x0F, 0x29, 0x02, 0x90, 0xC8 } }; -class DECLSPEC_UUID("870af99c-171d-4f9e-af0d-e63df40c2bc9") CPolicyConfigClient; +class DECLSPEC_UUID( "870af99c-171d-4f9e-af0d-e63df40c2bc9" ) + CPolicyConfigClient; interface IPolicyConfig : public IUnknown { public: - - virtual HRESULT GetMixFormat( - PCWSTR, - WAVEFORMATEX ** - ); + virtual HRESULT GetMixFormat( PCWSTR, WAVEFORMATEX** ); virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat( - PCWSTR, - INT, - WAVEFORMATEX ** - ); + PCWSTR, INT, WAVEFORMATEX** ); - virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat( - PCWSTR - ); + virtual HRESULT STDMETHODCALLTYPE ResetDeviceFormat( PCWSTR ); virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat( - PCWSTR, - WAVEFORMATEX *, - WAVEFORMATEX * - ); + PCWSTR, WAVEFORMATEX*, WAVEFORMATEX* ); virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod( - PCWSTR, - INT, - PINT64, - PINT64 - ); + PCWSTR, INT, PINT64, PINT64 ); - virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod( - PCWSTR, - PINT64 - ); + virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod( PCWSTR, PINT64 ); - virtual HRESULT STDMETHODCALLTYPE GetShareMode( - PCWSTR, - struct DeviceShareMode * - ); + virtual HRESULT STDMETHODCALLTYPE GetShareMode( PCWSTR, + struct DeviceShareMode* ); - virtual HRESULT STDMETHODCALLTYPE SetShareMode( - PCWSTR, - struct DeviceShareMode * - ); + virtual HRESULT STDMETHODCALLTYPE SetShareMode( PCWSTR, + struct DeviceShareMode* ); virtual HRESULT STDMETHODCALLTYPE GetPropertyValue( - PCWSTR, - int, - const PROPERTYKEY &, - const PROPVARIANT * - ); + PCWSTR, int, const PROPERTYKEY&, const PROPVARIANT* ); virtual HRESULT STDMETHODCALLTYPE SetPropertyValue( - PCWSTR, - int, - const PROPERTYKEY &, - const PROPVARIANT * - ); + PCWSTR, int, const PROPERTYKEY&, const PROPVARIANT* ); virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint( - __in PCWSTR wszDeviceId, - __in ERole eRole - ); + __in PCWSTR wszDeviceId, __in ERole eRole ); - virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility( - PCWSTR, - INT - ); + virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility( PCWSTR, INT ); }; -interface DECLSPEC_UUID("568b9108-44bf-40b4-9006-86afe5b5a620") -IPolicyConfigVista; -class DECLSPEC_UUID("294935CE-F637-4E7C-A41B-AB255460B862") -CPolicyConfigVistaClient; +interface DECLSPEC_UUID( "568b9108-44bf-40b4-9006-86afe5b5a620" ) + IPolicyConfigVista; +class DECLSPEC_UUID( "294935CE-F637-4E7C-A41B-AB255460B862" ) + CPolicyConfigVistaClient; // ---------------------------------------------------------------------------- // class CPolicyConfigVistaClient // {294935CE-F637-4E7C-A41B-AB255460B862} -// +// // interface IPolicyConfigVista // {568b9108-44bf-40b4-9006-86afe5b5a620} // // Query interface: // CComPtr PolicyConfig; // PolicyConfig.CoCreateInstance(__uuidof(CPolicyConfigVistaClient)); -// +// // @compatible: Windows Vista and Later // ---------------------------------------------------------------------------- interface IPolicyConfigVista : public IUnknown { public: - virtual HRESULT GetMixFormat( PCWSTR, - WAVEFORMATEX ** - ); // not available on Windows 7, use method from IPolicyConfig + WAVEFORMATEX** ); // not available on Windows 7, use method from + // IPolicyConfig virtual HRESULT STDMETHODCALLTYPE GetDeviceFormat( - PCWSTR, - INT, - WAVEFORMATEX ** - ); + PCWSTR, INT, WAVEFORMATEX** ); virtual HRESULT STDMETHODCALLTYPE SetDeviceFormat( - PCWSTR, - WAVEFORMATEX *, - WAVEFORMATEX * - ); + PCWSTR, WAVEFORMATEX*, WAVEFORMATEX* ); virtual HRESULT STDMETHODCALLTYPE GetProcessingPeriod( PCWSTR, INT, PINT64, - PINT64 - ); // not available on Windows 7, use method from IPolicyConfig + PINT64 ); // not available on Windows 7, use method from IPolicyConfig virtual HRESULT STDMETHODCALLTYPE SetProcessingPeriod( PCWSTR, - PINT64 - ); // not available on Windows 7, use method from IPolicyConfig + PINT64 ); // not available on Windows 7, use method from IPolicyConfig virtual HRESULT STDMETHODCALLTYPE GetShareMode( PCWSTR, - struct DeviceShareMode * - ); // not available on Windows 7, use method from IPolicyConfig + struct DeviceShareMode* ); // not available on Windows 7, use method + // from IPolicyConfig virtual HRESULT STDMETHODCALLTYPE SetShareMode( PCWSTR, - struct DeviceShareMode * - ); // not available on Windows 7, use method from IPolicyConfig + struct DeviceShareMode* ); // not available on Windows 7, use method + // from IPolicyConfig virtual HRESULT STDMETHODCALLTYPE GetPropertyValue( - PCWSTR, - int, - const PROPERTYKEY &, - const PROPVARIANT * - ); + PCWSTR, int, const PROPERTYKEY&, const PROPVARIANT* ); virtual HRESULT STDMETHODCALLTYPE SetPropertyValue( - PCWSTR, - int, - const PROPERTYKEY &, - const PROPVARIANT * - ); + PCWSTR, int, const PROPERTYKEY&, const PROPVARIANT* ); virtual HRESULT STDMETHODCALLTYPE SetDefaultEndpoint( - __in PCWSTR wszDeviceId, - __in ERole eRole - ); + __in PCWSTR wszDeviceId, __in ERole eRole ); virtual HRESULT STDMETHODCALLTYPE SetEndpointVisibility( PCWSTR, - INT - ); // not available on Windows 7, use method from IPolicyConfig + INT ); // not available on Windows 7, use method from IPolicyConfig }; diff --git a/src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp b/src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp index 83cd526..4bb4aea 100644 --- a/src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp +++ b/src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp @@ -1,15 +1,15 @@ #include "KeyboardInputDummy.h" -// Used to get the compiler to shut up about C4100: unreferenced formal parameter. -// The cast is to get GCC to shut up about it. -#define UNREFERENCED_PARAMETER(P) static_cast((P)) +// Used to get the compiler to shut up about C4100: unreferenced formal +// parameter. The cast is to get GCC to shut up about it. +#define UNREFERENCED_PARAMETER( P ) static_cast( ( P ) ) -namespace advsettings { - -void KeyboardInputDummy::sendKeyboardInput(QString input) +namespace advsettings +{ +void KeyboardInputDummy::sendKeyboardInput( QString input ) { // noop - UNREFERENCED_PARAMETER(input); + UNREFERENCED_PARAMETER( input ); } void KeyboardInputDummy::sendKeyboardEnter() @@ -17,10 +17,10 @@ void KeyboardInputDummy::sendKeyboardEnter() // noop } -void KeyboardInputDummy::sendKeyboardBackspace(int count) +void KeyboardInputDummy::sendKeyboardBackspace( int count ) { // noop - UNREFERENCED_PARAMETER(count); + UNREFERENCED_PARAMETER( count ); } void KeyboardInputDummy::sendKeyboardAltTab() @@ -28,4 +28,4 @@ void KeyboardInputDummy::sendKeyboardAltTab() // noop } -} +} // namespace advsettings diff --git a/src/tabcontrollers/keyboardinput/KeyboardInputDummy.h b/src/tabcontrollers/keyboardinput/KeyboardInputDummy.h index f5ee302..66e5fa5 100644 --- a/src/tabcontrollers/keyboardinput/KeyboardInputDummy.h +++ b/src/tabcontrollers/keyboardinput/KeyboardInputDummy.h @@ -4,17 +4,17 @@ #include "../KeyboardInput.h" // application namespace -namespace advsettings { - +namespace advsettings +{ class KeyboardInputDummy : public KeyboardInput { public: - virtual void sendKeyboardInput(QString input) override; + virtual void sendKeyboardInput( QString input ) override; virtual void sendKeyboardEnter() override; - virtual void sendKeyboardBackspace(int count) override; + virtual void sendKeyboardBackspace( int count ) override; virtual void sendKeyboardAltTab() override; }; -} +} // namespace advsettings #endif // KEYBOARDINPUTDUMMY_H diff --git a/src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp b/src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp index 471f27a..40e596f 100644 --- a/src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp +++ b/src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp @@ -2,14 +2,18 @@ #include #include "../../logging.h" -namespace advsettings { - -void fillKiStruct(INPUT& ip, WORD scanCode, bool keyup) { +namespace advsettings +{ +void fillKiStruct( INPUT& ip, WORD scanCode, bool keyup ) +{ ip.type = INPUT_KEYBOARD; ip.ki.wVk = scanCode; - if (keyup) { + if ( keyup ) + { ip.ki.dwFlags = KEYEVENTF_KEYUP; - } else { + } + else + { ip.ki.dwFlags = 0; } ip.ki.wScan = 0; @@ -17,78 +21,103 @@ void fillKiStruct(INPUT& ip, WORD scanCode, bool keyup) { ip.ki.time = 0; }; -void sendKeyboardInputRaw(int inputCount, LPINPUT input) { - if ((inputCount > 0) && !SendInput(static_cast(inputCount), input, sizeof(INPUT))) { - char *err; +void sendKeyboardInputRaw( int inputCount, LPINPUT input ) +{ + if ( ( inputCount > 0 ) + && !SendInput( + static_cast( inputCount ), input, sizeof( INPUT ) ) ) + { + char* err; auto errCode = GetLastError(); - if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - nullptr, - errCode, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language - reinterpret_cast(&err), - 0, - nullptr)){ - LOG(ERROR) << "Error calling SendInput(): Could not get error message (" << errCode << ")"; - } else { - LOG(ERROR) << "Error calling SendInput(): " << err; + if ( !FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER + | FORMAT_MESSAGE_FROM_SYSTEM, + nullptr, + errCode, + MAKELANGID( LANG_NEUTRAL, + SUBLANG_DEFAULT ), // default language + reinterpret_cast( &err ), + 0, + nullptr ) ) + { + LOG( ERROR ) + << "Error calling SendInput(): Could not get error message (" + << errCode << ")"; + } + else + { + LOG( ERROR ) << "Error calling SendInput(): " << err; } } } -void KeyboardInputWindows::sendKeyboardInput(QString input) +void KeyboardInputWindows::sendKeyboardInput( QString input ) { int len = input.length(); - if (len > 0) { - LPINPUT ips = new INPUT[static_cast(len) * 5 + 3]; + if ( len > 0 ) + { + LPINPUT ips = new INPUT[static_cast( len ) * 5 + 3]; int ii = 0; bool shiftPressed = false; bool ctrlPressed = false; bool altPressed = false; - for (int i = 0; i < len; i++) { - short tmp = VkKeyScan(input.at(i).toLatin1()); + for ( int i = 0; i < len; i++ ) + { + short tmp = VkKeyScan( input.at( i ).toLatin1() ); WORD c = tmp & 0xFF; short shiftState = tmp >> 8; bool isShift = shiftState & 1; bool isCtrl = shiftState & 2; bool isAlt = shiftState & 4; - if (isShift && !shiftPressed) { - fillKiStruct(ips[ii++], VK_SHIFT, false); + if ( isShift && !shiftPressed ) + { + fillKiStruct( ips[ii++], VK_SHIFT, false ); shiftPressed = true; - } else if (!isShift && shiftPressed) { - fillKiStruct(ips[ii++], VK_SHIFT, true); + } + else if ( !isShift && shiftPressed ) + { + fillKiStruct( ips[ii++], VK_SHIFT, true ); shiftPressed = false; } - if (isCtrl && !ctrlPressed) { - fillKiStruct(ips[ii++], VK_CONTROL, false); + if ( isCtrl && !ctrlPressed ) + { + fillKiStruct( ips[ii++], VK_CONTROL, false ); ctrlPressed = true; - } else if (!isCtrl && ctrlPressed) { - fillKiStruct(ips[ii++], VK_CONTROL, true); + } + else if ( !isCtrl && ctrlPressed ) + { + fillKiStruct( ips[ii++], VK_CONTROL, true ); ctrlPressed = false; } - if (isAlt && !altPressed) { - fillKiStruct(ips[ii++], VK_MENU, false); + if ( isAlt && !altPressed ) + { + fillKiStruct( ips[ii++], VK_MENU, false ); altPressed = true; - } else if (!isAlt && altPressed) { - fillKiStruct(ips[ii++], VK_MENU, true); + } + else if ( !isAlt && altPressed ) + { + fillKiStruct( ips[ii++], VK_MENU, true ); altPressed = false; } - fillKiStruct(ips[ii++], c, false); - fillKiStruct(ips[ii++], c, true); + fillKiStruct( ips[ii++], c, false ); + fillKiStruct( ips[ii++], c, true ); } - if (shiftPressed) { - fillKiStruct(ips[ii++], VK_SHIFT, true); + if ( shiftPressed ) + { + fillKiStruct( ips[ii++], VK_SHIFT, true ); shiftPressed = false; } - if (ctrlPressed) { - fillKiStruct(ips[ii++], VK_CONTROL, true); + if ( ctrlPressed ) + { + fillKiStruct( ips[ii++], VK_CONTROL, true ); ctrlPressed = false; } - if (altPressed) { - fillKiStruct(ips[ii++], VK_MENU, true); + if ( altPressed ) + { + fillKiStruct( ips[ii++], VK_MENU, true ); altPressed = false; } - sendKeyboardInputRaw(ii, ips); + sendKeyboardInputRaw( ii, ips ); delete[] ips; } } @@ -96,24 +125,26 @@ void KeyboardInputWindows::sendKeyboardInput(QString input) void KeyboardInputWindows::sendKeyboardEnter() { LPINPUT ips = new INPUT[2]; - fillKiStruct(ips[0], VK_RETURN, false); - fillKiStruct(ips[1], VK_RETURN, true); + fillKiStruct( ips[0], VK_RETURN, false ); + fillKiStruct( ips[1], VK_RETURN, true ); - sendKeyboardInputRaw(2, ips); + sendKeyboardInputRaw( 2, ips ); delete[] ips; } -void KeyboardInputWindows::sendKeyboardBackspace(int count) +void KeyboardInputWindows::sendKeyboardBackspace( int count ) { - if (count > 0) { + if ( count > 0 ) + { // We ensure that count is nonnegative, therefore safe cast. - LPINPUT ips = new INPUT[static_cast(count) * 2]; - for (int i = 0; i < count; i++) { - fillKiStruct(ips[2 * i], VK_BACK, false); - fillKiStruct(ips[2 * i + 1], VK_BACK, true); + LPINPUT ips = new INPUT[static_cast( count ) * 2]; + for ( int i = 0; i < count; i++ ) + { + fillKiStruct( ips[2 * i], VK_BACK, false ); + fillKiStruct( ips[2 * i + 1], VK_BACK, true ); } - sendKeyboardInputRaw(count * 2, ips); + sendKeyboardInputRaw( count * 2, ips ); delete[] ips; } } @@ -122,13 +153,13 @@ void KeyboardInputWindows::sendKeyboardAltTab() { LPINPUT ips = new INPUT[4]; // VK_MENU is alt - fillKiStruct(ips[0], VK_MENU, false); - fillKiStruct(ips[1], VK_TAB, false); - fillKiStruct(ips[2], VK_TAB, true); - fillKiStruct(ips[3], VK_MENU, true); + fillKiStruct( ips[0], VK_MENU, false ); + fillKiStruct( ips[1], VK_TAB, false ); + fillKiStruct( ips[2], VK_TAB, true ); + fillKiStruct( ips[3], VK_MENU, true ); - sendKeyboardInputRaw(4, ips); + sendKeyboardInputRaw( 4, ips ); delete[] ips; } -} +} // namespace advsettings diff --git a/src/tabcontrollers/keyboardinput/KeyboardInputWindows.h b/src/tabcontrollers/keyboardinput/KeyboardInputWindows.h index 3292b72..e376703 100644 --- a/src/tabcontrollers/keyboardinput/KeyboardInputWindows.h +++ b/src/tabcontrollers/keyboardinput/KeyboardInputWindows.h @@ -4,17 +4,17 @@ #include "../KeyboardInput.h" // application namespace -namespace advsettings { - +namespace advsettings +{ class KeyboardInputWindows : public KeyboardInput { public: - virtual void sendKeyboardInput(QString input) override; + virtual void sendKeyboardInput( QString input ) override; virtual void sendKeyboardEnter() override; - virtual void sendKeyboardBackspace(int count) override; + virtual void sendKeyboardBackspace( int count ) override; virtual void sendKeyboardAltTab() override; }; -} +} // namespace advsettings #endif // KEYBOARDINPUTWINDOWS_H diff --git a/src/utils/ChaperoneUtils.cpp b/src/utils/ChaperoneUtils.cpp index 832593a..1ae5723 100644 --- a/src/utils/ChaperoneUtils.cpp +++ b/src/utils/ChaperoneUtils.cpp @@ -2,80 +2,101 @@ #include #include -namespace utils { - - -float ChaperoneUtils::_getDistanceToChaperone(const vr::HmdVector3_t & x, vr::HmdVector3_t * projectedPoint) { - float distance = NAN; - vr::HmdVector3_t* _cornersPtr = _corners.get(); - for (uint32_t i = 0; i < _quadsCount; i++) { - uint32_t i2 = (i + 1) % _quadsCount; - vr::HmdVector3_t& r0 = _cornersPtr[i]; - vr::HmdVector3_t& r1 = _cornersPtr[i2]; - float u_x = r1.v[0] - r0.v[0]; - float u_z = r1.v[2] - r0.v[2]; - float r = ((x.v[0] - r0.v[0]) * u_x + (x.v[2] - r0.v[2]) * u_z) / (u_x*u_x + u_z*u_z); - //int mode = 0; // 0 .. projected point on segment, 1 .. projected point outside of segment (r0 closer than r1), 2 .. projected point outside of segment (r1 closer than r0) - float d; - float x1_x; - float x1_z; - if (r < 0.0f || r > 1.0f) { // projected point outside of segment - float d_x = r0.v[0] - x.v[0]; - float d_z = r0.v[2] - x.v[2]; - float d1 = sqrt(d_x*d_x + d_z*d_z); - d_x = r1.v[0] - x.v[0]; - d_z = r1.v[2] - x.v[2]; - float d2 = sqrt(d_x*d_x + d_z*d_z); - if (d1 < d2) { - d = d1; - x1_x = r0.v[0]; - x1_z = r0.v[2]; - } else { - d = d2; - x1_x = r1.v[0]; - x1_z = r1.v[2]; - } - } else { // projected point on segment - x1_x = r0.v[0] + r * u_x; - x1_z = r0.v[2] + r * u_z; - float d_x = x1_x - x.v[0]; - float d_z = x1_z - x.v[2]; - d = sqrt(d_x*d_x + d_z*d_z); - } - if (std::isnan(distance) || d < distance) { - distance = d; - if (projectedPoint) { - projectedPoint->v[0] = x1_x; - projectedPoint->v[1] = x.v[1]; - projectedPoint->v[2] = x1_z; - } - } - } - return distance; +namespace utils +{ +float ChaperoneUtils::_getDistanceToChaperone( + const vr::HmdVector3_t& x, + vr::HmdVector3_t* projectedPoint ) +{ + float distance = NAN; + vr::HmdVector3_t* _cornersPtr = _corners.get(); + for ( uint32_t i = 0; i < _quadsCount; i++ ) + { + uint32_t i2 = ( i + 1 ) % _quadsCount; + vr::HmdVector3_t& r0 = _cornersPtr[i]; + vr::HmdVector3_t& r1 = _cornersPtr[i2]; + float u_x = r1.v[0] - r0.v[0]; + float u_z = r1.v[2] - r0.v[2]; + float r = ( ( x.v[0] - r0.v[0] ) * u_x + ( x.v[2] - r0.v[2] ) * u_z ) + / ( u_x * u_x + u_z * u_z ); + // int mode = 0; // 0 .. projected point on segment, 1 .. projected + // point outside of segment (r0 closer than r1), 2 .. projected point + // outside of segment (r1 closer than r0) + float d; + float x1_x; + float x1_z; + if ( r < 0.0f || r > 1.0f ) + { // projected point outside of segment + float d_x = r0.v[0] - x.v[0]; + float d_z = r0.v[2] - x.v[2]; + float d1 = sqrt( d_x * d_x + d_z * d_z ); + d_x = r1.v[0] - x.v[0]; + d_z = r1.v[2] - x.v[2]; + float d2 = sqrt( d_x * d_x + d_z * d_z ); + if ( d1 < d2 ) + { + d = d1; + x1_x = r0.v[0]; + x1_z = r0.v[2]; + } + else + { + d = d2; + x1_x = r1.v[0]; + x1_z = r1.v[2]; + } + } + else + { // projected point on segment + x1_x = r0.v[0] + r * u_x; + x1_z = r0.v[2] + r * u_z; + float d_x = x1_x - x.v[0]; + float d_z = x1_z - x.v[2]; + d = sqrt( d_x * d_x + d_z * d_z ); + } + if ( std::isnan( distance ) || d < distance ) + { + distance = d; + if ( projectedPoint ) + { + projectedPoint->v[0] = x1_x; + projectedPoint->v[1] = x.v[1]; + projectedPoint->v[2] = x1_z; + } + } + } + return distance; } - -void ChaperoneUtils::loadChaperoneData() { - std::lock_guard lock(_mutex); - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(nullptr, &_quadsCount); - if (_quadsCount > 0) { - std::unique_ptr quadsBuffer(new vr::HmdQuad_t[_quadsCount]); - vr::HmdQuad_t* quadsBufferPtr = quadsBuffer.get(); - _corners.reset((vr::HmdVector3_t*)new vr::HmdQuad_t[_quadsCount]); - vr::HmdVector3_t* _cornersPtr = _corners.get(); - vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo(quadsBufferPtr, &_quadsCount); - for (uint32_t i = 0; i < _quadsCount; i++) { - _cornersPtr[i] = quadsBufferPtr[i].vCorners[0]; - uint32_t i2 = (i + 1) % _quadsCount; - if (quadsBufferPtr[i].vCorners[3].v[0] != quadsBufferPtr[i2].vCorners[0].v[0] - || quadsBufferPtr[i].vCorners[3].v[1] != quadsBufferPtr[i2].vCorners[0].v[1] - || quadsBufferPtr[i].vCorners[3].v[2] != quadsBufferPtr[i2].vCorners[0].v[2] - || quadsBufferPtr[i].vCorners[0].v[1] != 0.0f) { - _chaperoneWellFormed = false; - } - } - } +void ChaperoneUtils::loadChaperoneData() +{ + std::lock_guard lock( _mutex ); + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( nullptr, &_quadsCount ); + if ( _quadsCount > 0 ) + { + std::unique_ptr quadsBuffer( + new vr::HmdQuad_t[_quadsCount] ); + vr::HmdQuad_t* quadsBufferPtr = quadsBuffer.get(); + _corners.reset( ( vr::HmdVector3_t* ) new vr::HmdQuad_t[_quadsCount] ); + vr::HmdVector3_t* _cornersPtr = _corners.get(); + vr::VRChaperoneSetup()->GetLiveCollisionBoundsInfo( quadsBufferPtr, + &_quadsCount ); + for ( uint32_t i = 0; i < _quadsCount; i++ ) + { + _cornersPtr[i] = quadsBufferPtr[i].vCorners[0]; + uint32_t i2 = ( i + 1 ) % _quadsCount; + if ( quadsBufferPtr[i].vCorners[3].v[0] + != quadsBufferPtr[i2].vCorners[0].v[0] + || quadsBufferPtr[i].vCorners[3].v[1] + != quadsBufferPtr[i2].vCorners[0].v[1] + || quadsBufferPtr[i].vCorners[3].v[2] + != quadsBufferPtr[i2].vCorners[0].v[2] + || quadsBufferPtr[i].vCorners[0].v[1] != 0.0f ) + { + _chaperoneWellFormed = false; + } + } + } } - } // end namespace utils diff --git a/src/utils/ChaperoneUtils.h b/src/utils/ChaperoneUtils.h index 873536b..9a1176e 100644 --- a/src/utils/ChaperoneUtils.h +++ b/src/utils/ChaperoneUtils.h @@ -4,35 +4,50 @@ #include #include -namespace utils { - -class ChaperoneUtils { +namespace utils +{ +class ChaperoneUtils +{ private: - std::recursive_mutex _mutex; - uint32_t _quadsCount = 0; - std::unique_ptr _corners; - bool _chaperoneWellFormed = true; + std::recursive_mutex _mutex; + uint32_t _quadsCount = 0; + std::unique_ptr _corners; + bool _chaperoneWellFormed = true; - float _getDistanceToChaperone(const vr::HmdVector3_t& point, vr::HmdVector3_t* projectedPoint); + float _getDistanceToChaperone( const vr::HmdVector3_t& point, + vr::HmdVector3_t* projectedPoint ); public: - uint32_t quadsCount() const noexcept { return _quadsCount; } - bool isChaperoneWellFormed() const noexcept { return _chaperoneWellFormed; } + uint32_t quadsCount() const noexcept + { + return _quadsCount; + } + bool isChaperoneWellFormed() const noexcept + { + return _chaperoneWellFormed; + } - std::recursive_mutex& mutex() noexcept { return _mutex; } + std::recursive_mutex& mutex() noexcept + { + return _mutex; + } - void loadChaperoneData(); + void loadChaperoneData(); - float getDistanceToChaperone(const vr::HmdVector3_t& point, vr::HmdVector3_t* projectedPoint = nullptr, bool doLock = false) { - if (doLock) { - std::lock_guard lock(_mutex); - return _getDistanceToChaperone(point, projectedPoint); - } else { - return _getDistanceToChaperone(point, projectedPoint); - } - } + float getDistanceToChaperone( const vr::HmdVector3_t& point, + vr::HmdVector3_t* projectedPoint = nullptr, + bool doLock = false ) + { + if ( doLock ) + { + std::lock_guard lock( _mutex ); + return _getDistanceToChaperone( point, projectedPoint ); + } + else + { + return _getDistanceToChaperone( point, projectedPoint ); + } + } }; - } // end namespace utils - diff --git a/src/utils/Matrix.h b/src/utils/Matrix.h index 3da60d1..0eed8d6 100644 --- a/src/utils/Matrix.h +++ b/src/utils/Matrix.h @@ -3,95 +3,108 @@ #include #include - -namespace utils { - -inline vr::HmdMatrix34_t& initRotationMatrix(vr::HmdMatrix34_t& matrix, unsigned axisId, float angle) { - switch (axisId) { - case 0: // x-axis - matrix.m[0][0] = 1.0f; - matrix.m[0][1] = 0.0f; - matrix.m[0][2] = 0.0f; - matrix.m[0][3] = 0.0f; - matrix.m[1][0] = 0.0f; - matrix.m[1][1] = std::cos(angle); - matrix.m[1][2] = -std::sin(angle); - matrix.m[1][3] = 0.0f; - matrix.m[2][0] = 0.0f; - matrix.m[2][1] = std::sin(angle); - matrix.m[2][2] = std::cos(angle); - matrix.m[2][3] = 0.0f; - break; - case 1: // y-axis - matrix.m[0][0] = std::cos(angle); - matrix.m[0][1] = 0.0f; - matrix.m[0][2] = std::sin(angle); - matrix.m[0][3] = 0.0f; - matrix.m[1][0] = 0.0f; - matrix.m[1][1] = 1.0f; - matrix.m[1][2] = 0.0f; - matrix.m[1][3] = 0.0f; - matrix.m[2][0] = -std::sin(angle); - matrix.m[2][1] = 0.0f; - matrix.m[2][2] = std::cos(angle); - matrix.m[2][3] = 0.0f; - break; - case 2: // z-axis - matrix.m[0][0] = std::cos(angle); - matrix.m[0][1] = -std::sin(angle); - matrix.m[0][2] = 0.0f; - matrix.m[0][3] = 0.0f; - matrix.m[1][0] = std::sin(angle); - matrix.m[1][1] = std::cos(angle); - matrix.m[1][2] = 0.0f; - matrix.m[1][3] = 0.0f; - matrix.m[2][0] = 0.0f; - matrix.m[2][1] = 0.0f; - matrix.m[2][2] = 1.0f; - matrix.m[2][3] = 0.0f; - break; - default: - break; - } - return matrix; +namespace utils +{ +inline vr::HmdMatrix34_t& initRotationMatrix( vr::HmdMatrix34_t& matrix, + unsigned axisId, + float angle ) +{ + switch ( axisId ) + { + case 0: // x-axis + matrix.m[0][0] = 1.0f; + matrix.m[0][1] = 0.0f; + matrix.m[0][2] = 0.0f; + matrix.m[0][3] = 0.0f; + matrix.m[1][0] = 0.0f; + matrix.m[1][1] = std::cos( angle ); + matrix.m[1][2] = -std::sin( angle ); + matrix.m[1][3] = 0.0f; + matrix.m[2][0] = 0.0f; + matrix.m[2][1] = std::sin( angle ); + matrix.m[2][2] = std::cos( angle ); + matrix.m[2][3] = 0.0f; + break; + case 1: // y-axis + matrix.m[0][0] = std::cos( angle ); + matrix.m[0][1] = 0.0f; + matrix.m[0][2] = std::sin( angle ); + matrix.m[0][3] = 0.0f; + matrix.m[1][0] = 0.0f; + matrix.m[1][1] = 1.0f; + matrix.m[1][2] = 0.0f; + matrix.m[1][3] = 0.0f; + matrix.m[2][0] = -std::sin( angle ); + matrix.m[2][1] = 0.0f; + matrix.m[2][2] = std::cos( angle ); + matrix.m[2][3] = 0.0f; + break; + case 2: // z-axis + matrix.m[0][0] = std::cos( angle ); + matrix.m[0][1] = -std::sin( angle ); + matrix.m[0][2] = 0.0f; + matrix.m[0][3] = 0.0f; + matrix.m[1][0] = std::sin( angle ); + matrix.m[1][1] = std::cos( angle ); + matrix.m[1][2] = 0.0f; + matrix.m[1][3] = 0.0f; + matrix.m[2][0] = 0.0f; + matrix.m[2][1] = 0.0f; + matrix.m[2][2] = 1.0f; + matrix.m[2][3] = 0.0f; + break; + default: + break; + } + return matrix; } - -inline vr::HmdMatrix34_t& matMul33(vr::HmdMatrix34_t& result, const vr::HmdMatrix34_t& a, const vr::HmdMatrix34_t& b) { - for (unsigned i = 0; i < 3; i++) { - for (unsigned j = 0; j < 3; j++) { - result.m[i][j] = 0.0f; - for (unsigned k = 0; k < 3; k++) { - result.m[i][j] += a.m[i][k] * b.m[k][j]; - } - } - } - return result; +inline vr::HmdMatrix34_t& matMul33( vr::HmdMatrix34_t& result, + const vr::HmdMatrix34_t& a, + const vr::HmdMatrix34_t& b ) +{ + for ( unsigned i = 0; i < 3; i++ ) + { + for ( unsigned j = 0; j < 3; j++ ) + { + result.m[i][j] = 0.0f; + for ( unsigned k = 0; k < 3; k++ ) + { + result.m[i][j] += a.m[i][k] * b.m[k][j]; + } + } + } + return result; } - -inline vr::HmdVector3_t& matMul33(vr::HmdVector3_t& result, const vr::HmdMatrix34_t& a, const vr::HmdVector3_t& b) { - for (unsigned i = 0; i < 3; i++) { - result.v[i] = 0.0f; - for (unsigned k = 0; k < 3; k++) { - result.v[i] += a.m[i][k] * b.v[k]; - }; - } - return result; +inline vr::HmdVector3_t& matMul33( vr::HmdVector3_t& result, + const vr::HmdMatrix34_t& a, + const vr::HmdVector3_t& b ) +{ + for ( unsigned i = 0; i < 3; i++ ) + { + result.v[i] = 0.0f; + for ( unsigned k = 0; k < 3; k++ ) + { + result.v[i] += a.m[i][k] * b.v[k]; + }; + } + return result; } - -inline vr::HmdVector3_t& matMul33(vr::HmdVector3_t& result, const vr::HmdVector3_t& a, const vr::HmdMatrix34_t& b) { - for (unsigned i = 0; i < 3; i++) { - result.v[i] = 0.0f; - for (unsigned k = 0; k < 3; k++) { - result.v[i] += a.v[k] * b.m[k][i]; - }; - } - return result; +inline vr::HmdVector3_t& matMul33( vr::HmdVector3_t& result, + const vr::HmdVector3_t& a, + const vr::HmdMatrix34_t& b ) +{ + for ( unsigned i = 0; i < 3; i++ ) + { + result.v[i] = 0.0f; + for ( unsigned k = 0; k < 3; k++ ) + { + result.v[i] += a.v[k] * b.m[k][i]; + }; + } + return result; } - - } // end namespace utils -