summaryrefslogtreecommitdiffhomepage
path: root/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c
diff options
context:
space:
mode:
Diffstat (limited to 'ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c')
-rw-r--r--ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c1961
1 files changed, 1961 insertions, 0 deletions
diff --git a/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c
new file mode 100644
index 0000000..014af83
--- /dev/null
+++ b/ovr_sdk_win_23.0.0/LibOVR/Shim/OVR_CAPIShim.c
@@ -0,0 +1,1961 @@
+/************************************************************************************
+
+Filename : OVR_CAPIShim.c
+Content : CAPI DLL user library
+Created : November 20, 2014
+Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
+
+Licensed under the Oculus Master SDK License Version 1.0 (the "License");
+you may not use the Oculus VR Rift SDK except in compliance with the License,
+which is provided at the time of installation or download, or which
+otherwise accompanies this software in either electronic or hard copy form.
+
+You may obtain a copy of the License at
+
+https://developer.oculus.com/licenses/oculusmastersdk-1.0
+
+Unless required by applicable law or agreed to in writing, the Oculus VR SDK
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+************************************************************************************/
+
+#include <assert.h>
+#include <ctype.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "OVR_CAPI.h"
+#include "OVR_CAPI_Prototypes.h"
+#include "OVR_ErrorCode.h"
+#include "OVR_Version.h"
+
+#if defined(_WIN32)
+#if defined(_MSC_VER)
+#pragma warning(push, 0)
+#endif
+#include <Windows.h>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#include "OVR_CAPI_D3D.h"
+#else
+#if defined(__APPLE__)
+#include <libgen.h>
+#include <mach-o/dyld.h>
+#include <pwd.h>
+#include <sys/syslimits.h>
+#include <unistd.h>
+#endif
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+#include "OVR_CAPI_GL.h"
+#include "OVR_CAPI_Vk.h"
+
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable : 4996) // 'getenv': This function or variable may be unsafe.
+#endif
+
+// clang-format off
+static const uint8_t OculusSDKUniqueIdentifier[] = {
+ 0x9E, 0xB2, 0x0B, 0x1A, 0xB7, 0x97, 0x09, 0x20, 0xE0, 0xFB, 0x83, 0xED, 0xF8, 0x33, 0x5A, 0xEB,
+ 0x80, 0x4D, 0x8E, 0x92, 0x20, 0x69, 0x13, 0x56, 0xB4, 0xBB, 0xC4, 0x85, 0xA7, 0x9E, 0xA4, 0xFE,
+ OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_PATCH_VERSION
+};
+
+// clang-format on
+
+static const uint8_t OculusSDKUniqueIdentifierXORResult = 0xcb;
+
+// -----------------------------------------------------------------------------------
+// ***** OVR_BUILD_DEBUG
+//
+// Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set.
+//
+// If you want to control the behavior of these flags, then explicitly define
+// either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments.
+
+#if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE)
+#if defined(_MSC_VER)
+#if defined(_DEBUG)
+#define OVR_BUILD_DEBUG
+#endif
+#else
+#if defined(DEBUG)
+#define OVR_BUILD_DEBUG
+#endif
+#endif
+#endif
+
+//-----------------------------------------------------------------------------------
+// ***** FilePathCharType, ModuleHandleType, ModuleFunctionType
+//
+#if defined(_WIN32) // We need to use wchar_t on Microsoft platforms, as that's the native file
+// system character type.
+#define FilePathCharType \
+ wchar_t // #define instead of typedef because debuggers (VC++, XCode) don't recognize typedef'd
+// types as a string type.
+typedef HMODULE ModuleHandleType;
+typedef FARPROC ModuleFunctionType;
+#else
+#define FilePathCharType char
+typedef void* ModuleHandleType;
+typedef void* ModuleFunctionType;
+#endif
+
+#define ModuleHandleTypeNull ((ModuleHandleType)NULL)
+#define ModuleFunctionTypeNull ((ModuleFunctionType)NULL)
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_MAX_PATH
+//
+#if !defined(OVR_MAX_PATH)
+#if defined(_WIN32)
+#define OVR_MAX_PATH _MAX_PATH
+#elif defined(__APPLE__)
+#define OVR_MAX_PATH PATH_MAX
+#else
+#define OVR_MAX_PATH 1024
+#endif
+#endif
+
+#if !defined(OVR_DLSYM)
+#if defined(_WIN32)
+#define OVR_DLSYM(dlImage, name) GetProcAddress(dlImage, name)
+#else
+#define OVR_DLSYM(dlImage, name) dlsym(dlImage, name)
+#endif
+#endif
+
+static size_t OVR_strlcpy(char* dest, const char* src, size_t destsize) {
+ const char* s = src;
+ size_t n = destsize;
+
+ if (n && --n) {
+ do {
+ if ((*dest++ = *s++) == 0)
+ break;
+ } while (--n);
+ }
+
+ if (!n) {
+ if (destsize)
+ *dest = 0;
+ while (*s++) {
+ }
+ }
+
+ return (size_t)((s - src) - 1);
+}
+
+static size_t OVR_strlcat(char* dest, const char* src, size_t destsize) {
+ const size_t d = destsize ? strlen(dest) : 0;
+ const size_t s = strlen(src);
+ const size_t t = s + d;
+
+ if (t < destsize)
+ memcpy(dest + d, src, (s + 1) * sizeof(*src));
+ else {
+ if (destsize) {
+ memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src));
+ dest[destsize - 1] = 0;
+ }
+ }
+
+ return t;
+}
+
+#if defined(__APPLE__)
+static ovrBool
+OVR_strend(const char* pStr, const char* pFind, size_t strLength, size_t findLength) {
+ if (strLength == (size_t)-1)
+ strLength = strlen(pStr);
+ if (findLength == (size_t)-1)
+ findLength = strlen(pFind);
+ if (strLength >= findLength)
+ return (strcmp(pStr + strLength - findLength, pFind) == 0);
+ return ovrFalse;
+}
+
+static ovrBool OVR_isBundleFolder(const char* filePath) {
+ static const char* extensionArray[] = {".app", ".bundle", ".framework", ".plugin", ".kext"};
+ size_t i;
+
+ for (i = 0; i < sizeof(extensionArray) / sizeof(extensionArray[0]); i++) {
+ if (OVR_strend(filePath, extensionArray[i], (size_t)-1, (size_t)-1))
+ return ovrTrue;
+ }
+
+ return ovrFalse;
+}
+#endif
+
+#if !defined(_WIN32)
+static ovrBool OVR_GetCurrentWorkingDirectory(
+ FilePathCharType* directoryPath,
+ size_t directoryPathCapacity) {
+#if defined(_WIN32)
+ DWORD dwSize = GetCurrentDirectoryW((DWORD)directoryPathCapacity, directoryPath);
+
+ if ((dwSize > 0) &&
+ (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a \ char.
+ {
+ size_t length = wcslen(directoryPath);
+
+ if ((length == 0) ||
+ ((directoryPath[length - 1] != L'\\') && (directoryPath[length - 1] != L'/'))) {
+ directoryPath[length++] = L'\\';
+ directoryPath[length] = L'\0';
+ }
+
+ return ovrTrue;
+ }
+
+#else
+ char* cwd = getcwd(directoryPath, directoryPathCapacity);
+
+ if (cwd && directoryPath[0] &&
+ (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a / char.
+ {
+ size_t length = strlen(directoryPath);
+
+ if ((length == 0) || (directoryPath[length - 1] != '/')) {
+ directoryPath[length++] = '/';
+ directoryPath[length] = '\0';
+ }
+
+ return ovrTrue;
+ }
+#endif
+
+ if (directoryPathCapacity > 0)
+ directoryPath[0] = '\0';
+
+ return ovrFalse;
+}
+
+// The appContainer argument is specific currently to only Macintosh. If true and the application is
+// a .app bundle then it returns the
+// location of the bundle and not the path to the executable within the bundle. Else return the path
+// to the executable binary itself.
+// The moduleHandle refers to the relevant dynamic (a.k.a. shared) library. The main executable is
+// the main module, and each of the shared
+// libraries is a module. This way you can specify that you want to know the directory of the given
+// shared library, which may be different
+// from the main executable. If the moduleHandle is NULL then the current application module is
+// used.
+static ovrBool OVR_GetCurrentApplicationDirectory(
+ FilePathCharType* directoryPath,
+ size_t directoryPathCapacity,
+ ovrBool appContainer,
+ ModuleHandleType moduleHandle) {
+#if defined(_WIN32)
+ DWORD length = GetModuleFileNameW(moduleHandle, directoryPath, (DWORD)directoryPathCapacity);
+ DWORD pos;
+
+ if ((length != 0) &&
+ (length <
+ (DWORD)directoryPathCapacity)) // If there wasn't an error and there was enough capacity...
+ {
+ for (pos = length; (pos > 0) && (directoryPath[pos] != '\\') && (directoryPath[pos] != '/');
+ --pos) {
+ if ((directoryPath[pos - 1] != '\\') && (directoryPath[pos - 1] != '/'))
+ directoryPath[pos - 1] = 0;
+ }
+
+ return ovrTrue;
+ }
+
+ (void)appContainer; // Not used on this platform.
+
+#elif defined(__APPLE__)
+ uint32_t directoryPathCapacity32 = (uint32_t)directoryPathCapacity;
+ int result = _NSGetExecutablePath(directoryPath, &directoryPathCapacity32);
+
+ if (result == 0) // If success...
+ {
+ char realPath[OVR_MAX_PATH];
+
+ if (realpath(directoryPath, realPath)) // realpath returns the canonicalized absolute file path.
+ {
+ size_t length = 0;
+
+ if (appContainer) // If the caller wants the path to the containing bundle...
+ {
+ char containerPath[OVR_MAX_PATH];
+ ovrBool pathIsContainer;
+
+ OVR_strlcpy(containerPath, realPath, sizeof(containerPath));
+ pathIsContainer = OVR_isBundleFolder(containerPath);
+
+ while (!pathIsContainer && strncmp(containerPath, ".", OVR_MAX_PATH) &&
+ strncmp(containerPath, "/", OVR_MAX_PATH)) // While the container we're looking for
+ // is not found and while the path doesn't
+ // start with a . or /
+ {
+ OVR_strlcpy(containerPath, dirname(containerPath), sizeof(containerPath));
+ pathIsContainer = OVR_isBundleFolder(containerPath);
+ }
+
+ if (pathIsContainer)
+ length = OVR_strlcpy(directoryPath, containerPath, directoryPathCapacity);
+ }
+
+ if (length == 0) // If not set above in the appContainer block...
+ length = OVR_strlcpy(directoryPath, realPath, directoryPathCapacity);
+
+ while (length-- && (directoryPath[length] != '/'))
+ directoryPath[length] =
+ '\0'; // Strip the file name from the file path, leaving a trailing / char.
+
+ return ovrTrue;
+ }
+ }
+
+ (void)moduleHandle; // Not used on this platform.
+
+#else
+ ssize_t length = readlink("/proc/self/exe", directoryPath, directoryPathCapacity);
+ ssize_t pos;
+
+ if (length > 0) {
+ for (pos = length; (pos > 0) && (directoryPath[pos] != '/'); --pos) {
+ if (directoryPath[pos - 1] != '/')
+ directoryPath[pos - 1] = '\0';
+ }
+
+ return ovrTrue;
+ }
+
+ (void)appContainer; // Not used on this platform.
+ (void)moduleHandle;
+#endif
+
+ if (directoryPathCapacity > 0)
+ directoryPath[0] = '\0';
+
+ return ovrFalse;
+}
+#endif // !defined(_WIN32)
+
+#if defined(_WIN32)
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4201)
+#endif
+
+#include <Softpub.h>
+#include <Wincrypt.h>
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+// Expected certificates:
+#define ExpectedNumCertificates 3
+typedef struct CertificateEntry_t {
+ const wchar_t* Issuer;
+ const wchar_t* Subject;
+} CertificateEntry;
+
+CertificateEntry NewCertificateChain[ExpectedNumCertificates] = {
+ {L"DigiCert SHA2 Assured ID Code Signing CA", L"Oculus VR, LLC"},
+ {L"DigiCert Assured ID Root CA", L"DigiCert SHA2 Assured ID Code Signing CA"},
+ {L"DigiCert Assured ID Root CA", L"DigiCert Assured ID Root CA"},
+};
+
+#define CertificateChainCount 1
+CertificateEntry* AllowedCertificateChains[CertificateChainCount] = {NewCertificateChain};
+
+typedef DWORD(WINAPI* PtrCertGetNameStringW)(
+ PCCERT_CONTEXT pCertContext,
+ DWORD dwType,
+ DWORD dwFlags,
+ void* pvTypePara,
+ LPWSTR pszNameString,
+ DWORD cchNameString);
+typedef LONG(WINAPI* PtrWinVerifyTrust)(HWND hwnd, GUID* pgActionID, LPVOID pWVTData);
+typedef CRYPT_PROVIDER_DATA*(WINAPI* PtrWTHelperProvDataFromStateData)(HANDLE hStateData);
+typedef CRYPT_PROVIDER_SGNR*(WINAPI* PtrWTHelperGetProvSignerFromChain)(
+ CRYPT_PROVIDER_DATA* pProvData,
+ DWORD idxSigner,
+ BOOL fCounterSigner,
+ DWORD idxCounterSigner);
+
+PtrCertGetNameStringW m_PtrCertGetNameStringW = 0;
+PtrWinVerifyTrust m_PtrWinVerifyTrust = 0;
+PtrWTHelperProvDataFromStateData m_PtrWTHelperProvDataFromStateData = 0;
+PtrWTHelperGetProvSignerFromChain m_PtrWTHelperGetProvSignerFromChain = 0;
+
+typedef enum ValidateCertificateContentsResult_ {
+ VCCRSuccess = 0,
+ VCCRErrorCertCount = -1,
+ VCCRErrorTrust = -2,
+ VCCRErrorValidation = -3
+} ValidateCertificateContentsResult;
+
+static ValidateCertificateContentsResult ValidateCertificateContents(
+ CertificateEntry* chain,
+ CRYPT_PROVIDER_SGNR* cps) {
+ int certIndex;
+
+ if (!cps || !cps->pasCertChain || cps->csCertChain != ExpectedNumCertificates) {
+ return VCCRErrorCertCount;
+ }
+
+ for (certIndex = 0; certIndex < ExpectedNumCertificates; ++certIndex) {
+ CRYPT_PROVIDER_CERT* pCertData = &cps->pasCertChain[certIndex];
+ wchar_t subjectStr[400] = {0};
+ wchar_t issuerStr[400] = {0};
+
+ if ((pCertData->fSelfSigned && !pCertData->fTrustedRoot) || pCertData->fTestCert) {
+ return VCCRErrorTrust;
+ }
+
+ m_PtrCertGetNameStringW(
+ pCertData->pCert,
+ CERT_NAME_ATTR_TYPE,
+ 0,
+ szOID_COMMON_NAME,
+ subjectStr,
+ ARRAYSIZE(subjectStr));
+
+ m_PtrCertGetNameStringW(
+ pCertData->pCert,
+ CERT_NAME_ATTR_TYPE,
+ CERT_NAME_ISSUER_FLAG,
+ 0,
+ issuerStr,
+ ARRAYSIZE(issuerStr));
+
+ if (wcscmp(subjectStr, chain[certIndex].Subject) != 0 ||
+ wcscmp(issuerStr, chain[certIndex].Issuer) != 0) {
+ return VCCRErrorValidation;
+ }
+ }
+
+ return VCCRSuccess;
+}
+
+#define OVR_SIGNING_CONVERT_PTR(ftype, fptr, procaddr) \
+ { \
+ union { \
+ ftype p1; \
+ ModuleFunctionType p2; \
+ } u; \
+ u.p2 = procaddr; \
+ fptr = u.p1; \
+ }
+
+static BOOL OVR_Win32_SignCheck(FilePathCharType* fullPath, HANDLE hFile) {
+ WINTRUST_FILE_INFO fileData;
+ WINTRUST_DATA wintrustData;
+ GUID actionGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+ LONG resultStatus;
+ BOOL verified = FALSE;
+ HMODULE libWinTrust = LoadLibraryW(L"wintrust");
+ HMODULE libCrypt32 = LoadLibraryW(L"crypt32");
+ if (libWinTrust == NULL || libCrypt32 == NULL) {
+ return FALSE;
+ }
+
+ OVR_SIGNING_CONVERT_PTR(
+ PtrCertGetNameStringW,
+ m_PtrCertGetNameStringW,
+ GetProcAddress(libCrypt32, "CertGetNameStringW"));
+ OVR_SIGNING_CONVERT_PTR(
+ PtrWinVerifyTrust, m_PtrWinVerifyTrust, GetProcAddress(libWinTrust, "WinVerifyTrust"));
+ OVR_SIGNING_CONVERT_PTR(
+ PtrWTHelperProvDataFromStateData,
+ m_PtrWTHelperProvDataFromStateData,
+ GetProcAddress(libWinTrust, "WTHelperProvDataFromStateData"));
+ OVR_SIGNING_CONVERT_PTR(
+ PtrWTHelperGetProvSignerFromChain,
+ m_PtrWTHelperGetProvSignerFromChain,
+ GetProcAddress(libWinTrust, "WTHelperGetProvSignerFromChain"));
+
+ if (m_PtrCertGetNameStringW == NULL || m_PtrWinVerifyTrust == NULL ||
+ m_PtrWTHelperProvDataFromStateData == NULL || m_PtrWTHelperGetProvSignerFromChain == NULL) {
+ return FALSE;
+ }
+
+ if (hFile == INVALID_HANDLE_VALUE || fullPath == NULL) {
+ return FALSE;
+ }
+
+ ZeroMemory(&fileData, sizeof(fileData));
+ fileData.cbStruct = sizeof(fileData);
+ fileData.pcwszFilePath = fullPath;
+ fileData.hFile = hFile;
+
+ ZeroMemory(&wintrustData, sizeof(wintrustData));
+ wintrustData.cbStruct = sizeof(wintrustData);
+ wintrustData.pFile = &fileData;
+ wintrustData.dwUnionChoice = WTD_CHOICE_FILE; // Specify WINTRUST_FILE_INFO.
+ wintrustData.dwUIChoice = WTD_UI_NONE; // Do not display any UI.
+ wintrustData.dwUIContext = WTD_UICONTEXT_EXECUTE; // Hint that this is about app execution.
+ wintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
+ wintrustData.dwProvFlags = WTD_REVOCATION_CHECK_NONE;
+ wintrustData.dwStateAction = WTD_STATEACTION_VERIFY;
+ wintrustData.hWVTStateData = 0;
+
+ resultStatus = m_PtrWinVerifyTrust(
+ (HWND)INVALID_HANDLE_VALUE, // Do not display any UI.
+ &actionGUID, // V2 verification
+ &wintrustData);
+
+ if (resultStatus == ERROR_SUCCESS && wintrustData.hWVTStateData != 0 &&
+ wintrustData.hWVTStateData != INVALID_HANDLE_VALUE) {
+ CRYPT_PROVIDER_DATA* cpd = m_PtrWTHelperProvDataFromStateData(wintrustData.hWVTStateData);
+ if (cpd && cpd->csSigners == 1) {
+ CRYPT_PROVIDER_SGNR* cps = m_PtrWTHelperGetProvSignerFromChain(cpd, 0, FALSE, 0);
+ int chainIndex;
+ for (chainIndex = 0; chainIndex < CertificateChainCount; ++chainIndex) {
+ CertificateEntry* chain = AllowedCertificateChains[chainIndex];
+ if (VCCRSuccess == ValidateCertificateContents(chain, cps)) {
+ verified = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ wintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
+
+ m_PtrWinVerifyTrust(
+ (HWND)INVALID_HANDLE_VALUE, // Do not display any UI.
+ &actionGUID, // V2 verification
+ &wintrustData);
+
+ return verified;
+}
+
+#endif // #if defined(_WIN32)
+
+static ModuleHandleType OVR_OpenLibrary(const FilePathCharType* libraryPath, ovrResult* result) {
+#if defined(_WIN32)
+ DWORD fullPathNameLen = 0;
+ FilePathCharType fullPath[MAX_PATH] = {0};
+ HANDLE hFilePinned = INVALID_HANDLE_VALUE;
+ ModuleHandleType hModule = 0;
+
+ *result = ovrSuccess;
+
+ fullPathNameLen = GetFullPathNameW(libraryPath, MAX_PATH, fullPath, 0);
+ if (fullPathNameLen <= 0 || fullPathNameLen >= MAX_PATH) {
+ *result = ovrError_LibPath;
+ return NULL;
+ }
+
+ hFilePinned = CreateFileW(
+ fullPath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0);
+
+ if (hFilePinned == INVALID_HANDLE_VALUE) {
+ *result = ovrError_LibPath;
+ return NULL;
+ }
+
+ if (!OVR_Win32_SignCheck(fullPath, hFilePinned)) {
+ *result = ovrError_LibSignCheck;
+ CloseHandle(hFilePinned);
+ return NULL;
+ }
+
+ hModule = LoadLibraryW(fullPath);
+
+ CloseHandle(hFilePinned);
+
+ if (hModule == NULL) {
+ *result = ovrError_LibLoad;
+ }
+
+ return hModule;
+#else
+ *result = ovrSuccess;
+
+ // Don't bother trying to dlopen() a file that is not even there.
+ if (access(libraryPath, X_OK | R_OK) != 0) {
+ *result = ovrError_LibPath;
+ return NULL;
+ }
+
+ dlerror(); // Clear any previous dlopen() errors
+
+ // Use RTLD_NOW because we don't want unexpected stalls at runtime, and the library isn't very
+ // large.
+ // Use RTLD_LOCAL to avoid unilaterally exporting resolved symbols to the rest of this process.
+ void* lib = dlopen(libraryPath, RTLD_NOW | RTLD_LOCAL);
+
+ if (!lib) {
+ fprintf(stderr, "ERROR: Can't load '%s':\n%s\n", libraryPath, dlerror());
+ }
+
+ return lib;
+#endif
+}
+
+static void OVR_CloseLibrary(ModuleHandleType hLibrary) {
+ if (hLibrary) {
+#if defined(_WIN32)
+ // We may need to consider what to do in the case that the library is in an exception state.
+ // In a Windows C++ DLL, all global objects (including static members of classes) will be
+ // constructed just
+ // before the calling of the DllMain with DLL_PROCESS_ATTACH and they will be destroyed just
+ // after
+ // the call of the DllMain with DLL_PROCESS_DETACH. We may need to intercept DLL_PROCESS_DETACH
+ // and
+ // have special handling for the case that the DLL is broken.
+ FreeLibrary(hLibrary);
+#else
+ dlclose(hLibrary);
+#endif
+ }
+}
+
+// Returns a valid ModuleHandleType (e.g. Windows HMODULE) or returns ModuleHandleTypeNull (e.g.
+// NULL).
+// The caller is required to eventually call OVR_CloseLibrary on a valid return handle.
+//
+static ModuleHandleType OVR_FindLibraryPath(
+ int requestedProductVersion,
+ int requestedMajorVersion,
+ FilePathCharType* libraryPath,
+ size_t libraryPathCapacity,
+ ovrResult* result) {
+ ModuleHandleType moduleHandle;
+ FilePathCharType developerDir[OVR_MAX_PATH] = {'\0'};
+
+#if defined(_MSC_VER)
+#if defined(_WIN64)
+ const char* pBitDepth = "64";
+#else
+ const char* pBitDepth = "32";
+#endif
+#elif defined(__APPLE__)
+// For Apple platforms we are using a Universal Binary LibOVRRT dylib which has both 32 and 64 in
+// it.
+#else // Other Unix.
+#if defined(__x86_64__)
+ const char* pBitDepth = "64";
+#else
+ const char* pBitDepth = "32";
+#endif
+#endif
+
+ (void)requestedProductVersion;
+
+ *result = ovrError_LibLoad;
+ moduleHandle = ModuleHandleTypeNull;
+ if (libraryPathCapacity) {
+ libraryPath[0] = '\0';
+ }
+
+#if (defined(_MSC_VER) || defined(_WIN32)) && !defined(OVR_FILE_PATH_SEPARATOR)
+#define OVR_FILE_PATH_SEPARATOR L"\\"
+#else
+#define OVR_FILE_PATH_SEPARATOR "/"
+#endif
+
+ {
+#if defined(_WIN32)
+ size_t length;
+ _wgetenv_s(&length, developerDir, _countof(developerDir), L"LIBOVR_DLL_DIR");
+ if ((length != 0) && (length < _countof(developerDir)) &&
+ developerDir[length - 2] != OVR_FILE_PATH_SEPARATOR[0]) {
+ assert(developerDir[length - 1] == '\0');
+ developerDir[length - 1] = OVR_FILE_PATH_SEPARATOR[0];
+ developerDir[length] = '\0';
+ }
+#else
+ // Example value: /dev/OculusSDK/Main/LibOVR/Mac/Debug/
+ const char* pLibOvrDllDir = getenv("LIBOVR_DLL_DIR");
+
+ if (pLibOvrDllDir) {
+ char developerDir8[OVR_MAX_PATH];
+ size_t length = OVR_strlcpy(developerDir8, pLibOvrDllDir, sizeof(developerDir8));
+
+ // If missing a trailing path separator then append one.
+ if ((length > 0) && (length < sizeof(developerDir8)) &&
+ (developerDir8[length - 1] != OVR_FILE_PATH_SEPARATOR[0])) {
+ length = OVR_strlcat(developerDir8, OVR_FILE_PATH_SEPARATOR, sizeof(developerDir8));
+ }
+
+ if (length < sizeof(developerDir8)) {
+ OVR_strlcpy(developerDir, developerDir8, sizeof(developerDir));
+ }
+ }
+#endif
+ }
+
+ {
+ size_t i;
+
+#if !defined(_WIN32)
+ FilePathCharType cwDir[OVR_MAX_PATH]; // Will be filled in below.
+ FilePathCharType appDir[OVR_MAX_PATH];
+ OVR_GetCurrentWorkingDirectory(cwDir, sizeof(cwDir) / sizeof(cwDir[0]));
+ OVR_GetCurrentApplicationDirectory(appDir, sizeof(appDir) / sizeof(appDir[0]), ovrTrue, NULL);
+#endif
+
+#if defined(_WIN32)
+ // On Windows, only search the developer directory and the usual path
+ const FilePathCharType* directoryArray[2];
+ directoryArray[0] = developerDir; // Developer directory.
+ directoryArray[1] = L""; // No directory, which causes Windows to use the standard search
+ // strategy to find the DLL.
+
+#elif defined(__APPLE__)
+ // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dyld.1.html
+
+ FilePathCharType homeDir[OVR_MAX_PATH];
+ FilePathCharType homeFrameworkDir[OVR_MAX_PATH];
+ const FilePathCharType* directoryArray[5];
+ size_t homeDirLength = 0;
+
+ const char* pHome = getenv("HOME"); // Try getting the HOME environment variable.
+
+ if (pHome) {
+ homeDirLength = OVR_strlcpy(homeDir, pHome, sizeof(homeDir));
+ } else {
+ // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getpwuid_r.3.html
+ const long pwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+ if (pwBufferSize != -1) {
+ char pwBuffer[pwBufferSize];
+ struct passwd pw;
+ struct passwd* pwResult = NULL;
+
+ if ((getpwuid_r(getuid(), &pw, pwBuffer, pwBufferSize, &pwResult) == 0) && pwResult)
+ homeDirLength = OVR_strlcpy(homeDir, pw.pw_dir, sizeof(homeDir));
+ }
+ }
+
+ if (homeDirLength) {
+ if (homeDir[homeDirLength - 1] == '/')
+ homeDir[homeDirLength - 1] = '\0';
+ OVR_strlcpy(homeFrameworkDir, homeDir, sizeof(homeFrameworkDir));
+ OVR_strlcat(homeFrameworkDir, "/Library/Frameworks/", sizeof(homeFrameworkDir));
+ } else {
+ homeFrameworkDir[0] = '\0';
+ }
+
+ directoryArray[0] = cwDir;
+ directoryArray[1] = appDir;
+ directoryArray[2] = homeFrameworkDir; // ~/Library/Frameworks/
+ directoryArray[3] = "/Library/Frameworks/"; // DYLD_FALLBACK_FRAMEWORK_PATH
+ directoryArray[4] = developerDir; // Developer directory.
+
+#else
+#define STR1(x) #x
+#define STR(x) STR1(x)
+#ifdef LIBDIR
+#define TEST_LIB_DIR STR(LIBDIR) "/"
+#else
+#define TEST_LIB_DIR appDir
+#endif
+
+ const FilePathCharType* directoryArray[5];
+ directoryArray[0] = cwDir;
+ directoryArray[1] = TEST_LIB_DIR; // Directory specified by LIBDIR if defined.
+ directoryArray[2] = developerDir; // Developer directory.
+ directoryArray[3] = "/usr/local/lib/";
+ directoryArray[4] = "/usr/lib/";
+#endif
+
+ // Versioned file expectations.
+ // Windows: LibOVRRT<BIT_DEPTH>_<PRODUCT_VERSION>_<MAJOR_VERSION>.dll
+ // // Example: LibOVRRT64_1_1.dll -- LibOVRRT 64 bit, product 1, major version 1,
+ // minor/patch/build numbers unspecified in the name.
+ // Mac:
+ // LibOVRRT_<PRODUCT_VERSION>.framework/Versions/<MAJOR_VERSION>/LibOVRRT_<PRODUCT_VERSION>
+ // // We are not presently using the .framework bundle's Current directory to hold the
+ // version number. This may change.
+ // Linux: libOVRRT<BIT_DEPTH>_<PRODUCT_VERSION>.so.<MAJOR_VERSION>
+ // // The file on disk may contain a minor version number, but a symlink is used to map this
+ // major-only version to it.
+
+ // Since we are manually loading the LibOVR dynamic library, we need to look in various
+ // locations for a file
+ // that matches our requirements. The functionality required is somewhat similar to the
+ // operating system's
+ // dynamic loader functionality. Each OS has some differences in how this is handled.
+ // Future versions of this may iterate over all libOVRRT.so.* files in the directory and use the
+ // one that matches our requirements.
+ //
+ // We need to look for a library that matches the product version and major version of the
+ // caller's request,
+ // and that library needs to support a minor version that is >= the requested minor version.
+ // Currently we
+ // don't test the minor version here, as the library is named based only on the product and
+ // major version.
+ // Currently the minor version test is handled via the initialization of the library and the
+ // initialization
+ // fails if minor version cannot be supported by the library. The reason this is done during
+ // initialization
+ // is that the library can at runtime support multiple minor versions based on the user's
+ // request. To the
+ // external user, all that matters it that they call ovr_Initialize with a requested version and
+ // it succeeds
+ // or fails.
+ //
+ // The product version is something that is at a higher level than the major version, and is not
+ // something that's
+ // always seen in libraries (an example is the well-known LibXml2 library, in which the 2 is
+ // essentially the product version).
+
+ for (i = 0; i < sizeof(directoryArray) / sizeof(directoryArray[0]); ++i) {
+#if defined(_WIN32)
+ int printfResult = swprintf(
+ libraryPath,
+ libraryPathCapacity,
+ L"%lsLibOVRRT%hs_%d.dll",
+ directoryArray[i],
+ pBitDepth,
+ requestedMajorVersion);
+
+ if (*directoryArray[i] == 0) {
+ int k;
+ FilePathCharType foundPath[MAX_PATH] = {0};
+ DWORD searchResult = SearchPathW(NULL, libraryPath, NULL, MAX_PATH, foundPath, NULL);
+ if (searchResult <= 0 || searchResult >= libraryPathCapacity) {
+ continue;
+ }
+ foundPath[MAX_PATH - 1] = 0;
+ for (k = 0; k < MAX_PATH; ++k) {
+ libraryPath[k] = foundPath[k];
+ }
+ }
+
+#elif defined(__APPLE__)
+ (void)requestedMajorVersion;
+ // https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/VersionInformation.html
+ // Macintosh application bundles have the option of embedding dependent frameworks within the
+ // application
+ // bundle itself. A problem with that is that it doesn't support vendor-supplied updates to
+ // the framework.
+ int printfResult =
+ snprintf(libraryPath, libraryPathCapacity, "%sLibOVRRT.dylib", directoryArray[i]);
+
+#else // Unix
+ // Applications that depend on the OS (e.g. ld-linux / ldd) can rely on the library being in a
+ // common location
+ // such as /usr/lib or can rely on the -rpath linker option to embed a path for the OS to
+ // check for the library,
+ // or can rely on the LD_LIBRARY_PATH environment variable being set. It's generally not
+ // recommended that applications
+ // depend on LD_LIBRARY_PATH be globally modified, partly due to potentialy security issues.
+ // Currently we check the current application directory, current working directory, and then
+ // /usr/lib and possibly others.
+ int printfResult = snprintf(
+ libraryPath,
+ libraryPathCapacity,
+ "%slibOVRRT%s.so.%d",
+ directoryArray[i],
+ pBitDepth,
+ requestedMajorVersion);
+#endif
+
+ if ((printfResult >= 0) && (printfResult < (int)libraryPathCapacity)) {
+ moduleHandle = OVR_OpenLibrary(libraryPath, result);
+ if (moduleHandle != ModuleHandleTypeNull)
+ return moduleHandle;
+ }
+ }
+ }
+
+ return moduleHandle;
+}
+
+//-----------------------------------------------------------------------------------
+// ***** hLibOVR
+//
+// global handle to the LivOVR shared library.
+//
+static ModuleHandleType hLibOVR = NULL;
+
+// This function is currently unsupported.
+ModuleHandleType ovr_GetLibOVRRTHandle() {
+ return hLibOVR;
+}
+
+//-----------------------------------------------------------------------------------
+// ***** Function declarations
+//
+
+//-----------------------------------------------------------------------------------
+// ***** OVR_DECLARE_IMPORT
+//
+// Creates a pointer and loader value union for each entry in OVR_LIST_APIS()
+//
+
+#define OVR_DECLARE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments) \
+ union { \
+ ReturnValue(OVR_CDECL* Ptr) Arguments; \
+ ModuleFunctionType Symbol; \
+ } FunctionName;
+
+#define OVR_IGNORE_IMPORT(ReturnValue, FunctionName, OptionalVersion, Arguments)
+
+//-----------------------------------------------------------------------------------
+// ***** API - a structure with each API entrypoint as a FunctionName.Ptr and FunctionName.Symbol
+// union
+//
+
+static struct { OVR_LIST_APIS(OVR_DECLARE_IMPORT, OVR_IGNORE_IMPORT) } API = {{NULL}};
+
+static void OVR_UnloadSharedLibrary() {
+ memset(&API, 0, sizeof(API));
+ if (hLibOVR)
+ OVR_CloseLibrary(hLibOVR);
+ hLibOVR = NULL;
+}
+
+// Don't put this on the heap
+static ovrErrorInfo LastInitializeErrorInfo = {ovrError_NotInitialized,
+ "ovr_Initialize never called"};
+
+static ovrResult OVR_LoadSharedLibrary(int requestedProductVersion, int requestedMajorVersion) {
+ FilePathCharType filePath[OVR_MAX_PATH];
+ const char* SymbolName = NULL;
+ ovrResult result = ovrSuccess;
+
+ if (hLibOVR)
+ return result;
+
+ hLibOVR = OVR_FindLibraryPath(
+ requestedProductVersion,
+ requestedMajorVersion,
+ filePath,
+ sizeof(filePath) / sizeof(filePath[0]),
+ &result);
+
+ if (!hLibOVR) {
+ LastInitializeErrorInfo.Result = result;
+ OVR_strlcpy(
+ LastInitializeErrorInfo.ErrorString,
+ "Unable to load LibOVRRT DLL",
+ sizeof(LastInitializeErrorInfo.ErrorString));
+ return result;
+ }
+
+ ovrBool AllowSymbolLoadFailure = ovrFalse;
+
+ // Zero the API table just to be paranoid
+ memset(&API, 0, sizeof(API));
+
+// Load the current API entrypoint using the catenated FunctionName and OptionalVersion
+#define OVR_GETFUNCTION(ReturnValue, FunctionName, OptionalVersion, Arguments) \
+ SymbolName = #FunctionName #OptionalVersion; \
+ API.FunctionName.Symbol = OVR_DLSYM(hLibOVR, SymbolName); \
+ if (!API.FunctionName.Symbol && !AllowSymbolLoadFailure) { \
+ LastInitializeErrorInfo.Result = result = ovrError_LibSymbols; \
+ OVR_strlcpy( \
+ LastInitializeErrorInfo.ErrorString, \
+ "Unable to locate LibOVRRT symbol: ", \
+ sizeof(LastInitializeErrorInfo.ErrorString)); \
+ OVR_strlcat( \
+ LastInitializeErrorInfo.ErrorString, \
+ SymbolName, \
+ sizeof(LastInitializeErrorInfo.ErrorString)); \
+ goto FailedToLoadSymbol; \
+ }
+
+ OVR_LIST_APIS(OVR_GETFUNCTION, OVR_IGNORE_IMPORT)
+
+#undef OVR_GETFUNCTION
+
+ return result;
+
+FailedToLoadSymbol:
+ // Check SymbolName for the name of the API which failed to load
+ OVR_UnloadSharedLibrary();
+ return result;
+}
+
+// These defaults are also in CAPI.cpp
+static const ovrInitParams DefaultParams = {
+ ovrInit_RequestVersion, // Flags
+ OVR_MINOR_VERSION, // RequestedMinorVersion
+ 0, // LogCallback
+ 0, // UserData
+ 0, // ConnectionTimeoutSeconds
+ OVR_ON64("") // pad0
+};
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* inputParams) {
+ ovrResult result;
+ ovrInitParams params;
+
+ typedef void(OVR_CDECL * ovr_ReportClientInfoType)(
+ unsigned int compilerVersion,
+ int productVersion,
+ int majorVersion,
+ int minorVersion,
+ int patchVersion,
+ int buildNumber);
+ ovr_ReportClientInfoType reportClientInfo;
+
+ // Do something with our version signature hash to prevent
+ // it from being optimized out. In this case, compute
+ // a cheap CRC.
+ uint8_t crc = 0;
+ size_t i;
+
+ for (i = 0; i < (sizeof(OculusSDKUniqueIdentifier) - 3);
+ ++i) // Minus 3 because we have trailing OVR_MAJOR_VERSION, OVR_MINOR_VERSION,
+ // OVR_PATCH_VERSION which vary per version.
+ {
+ crc ^= OculusSDKUniqueIdentifier[i];
+ }
+
+ assert(crc == OculusSDKUniqueIdentifierXORResult);
+ if (crc != OculusSDKUniqueIdentifierXORResult) {
+ return ovrError_Initialize;
+ }
+
+ if (!inputParams) {
+ params = DefaultParams;
+ } else {
+ params = *inputParams;
+
+ // If not requesting a particular minor version,
+ if (!(params.Flags & ovrInit_RequestVersion)) {
+ // Enable requesting the default minor version.
+ params.Flags |= ovrInit_RequestVersion;
+ params.RequestedMinorVersion = OVR_MINOR_VERSION;
+ }
+ }
+
+ // Clear non-writable bits provided by client code.
+ params.Flags &= ovrinit_WritableBits;
+
+
+ // Error out if the requested minor version is less than our lowest deemed compatible version
+ // denoted by OVR_MIN_REQUESTABLE_MINOR_VERSION.
+ // Note: This code has to be in the shim as we want to enforce usage of the new API versions for
+ // applications being recompiled while maintaining backwards compatibility with older apps
+ if (params.RequestedMinorVersion < OVR_MIN_REQUESTABLE_MINOR_VERSION) {
+ // Requested LibOVRRT version too low
+ result = ovrError_LibVersion;
+ return result;
+ }
+
+ // By design we ignore the build version in the library search.
+ result = OVR_LoadSharedLibrary(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION);
+ if (result != ovrSuccess)
+ return result;
+
+ result = API.ovr_Initialize.Ptr(&params);
+
+ if (result != ovrSuccess) {
+ // Stash the last initialization error for the shim to return if
+ // ovr_GetLastErrorInfo is called after we unload the dll below
+ if (API.ovr_GetLastErrorInfo.Ptr) {
+ API.ovr_GetLastErrorInfo.Ptr(&LastInitializeErrorInfo);
+ }
+ OVR_UnloadSharedLibrary();
+ }
+
+ reportClientInfo =
+ (ovr_ReportClientInfoType)(uintptr_t)OVR_DLSYM(hLibOVR, "ovr_ReportClientInfo");
+
+ if (reportClientInfo) {
+ unsigned int mscFullVer = 0;
+#if defined(_MSC_FULL_VER)
+ mscFullVer = _MSC_FULL_VER;
+#endif // _MSC_FULL_VER
+
+ reportClientInfo(
+ mscFullVer,
+ OVR_PRODUCT_VERSION,
+ OVR_MAJOR_VERSION,
+ OVR_MINOR_VERSION,
+ OVR_PATCH_VERSION,
+ 0);
+ }
+
+ return result;
+}
+
+OVR_PUBLIC_FUNCTION(void) ovr_Shutdown() {
+ if (!API.ovr_Shutdown.Ptr)
+ return;
+ API.ovr_Shutdown.Ptr();
+ OVR_UnloadSharedLibrary();
+}
+
+OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString() {
+ // We don't directly return the value of the DLL API.ovr_GetVersionString.Ptr call,
+ // because that call returns a pointer to memory within the DLL. If the DLL goes
+ // away then that pointer becomes invalid while the process may still be holding
+ // onto it. So we save a local copy of it which is always valid.
+ static char dllVersionStringLocal[32];
+ const char* dllVersionString;
+
+ if (!API.ovr_GetVersionString.Ptr)
+ return "(Unable to load LibOVR)";
+
+ dllVersionString = API.ovr_GetVersionString.Ptr(); // Guaranteed to always be valid.
+ assert(dllVersionString != NULL);
+ OVR_strlcpy(dllVersionStringLocal, dllVersionString, sizeof(dllVersionStringLocal));
+
+ return dllVersionStringLocal;
+}
+
+OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo) {
+ if (!API.ovr_GetLastErrorInfo.Ptr) {
+ *errorInfo = LastInitializeErrorInfo;
+ } else
+ API.ovr_GetLastErrorInfo.Ptr(errorInfo);
+}
+
+OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session) {
+ if (!API.ovr_GetHmdDesc.Ptr) {
+ ovrHmdDesc hmdDesc;
+ memset(&hmdDesc, 0, sizeof(hmdDesc));
+ hmdDesc.Type = ovrHmd_None;
+ return hmdDesc;
+ }
+
+ return API.ovr_GetHmdDesc.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrHmdColorDesc) ovr_GetHmdColorDesc(ovrSession session) {
+ if (!API.ovr_GetHmdColorDesc.Ptr) {
+ ovrHmdColorDesc hmdColorDesc;
+ memset(&hmdColorDesc, 0, sizeof(hmdColorDesc));
+ return hmdColorDesc;
+ }
+
+ return API.ovr_GetHmdColorDesc.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SetClientColorDesc(ovrSession session, const ovrHmdColorDesc* hmdColorDesc) {
+ if (!API.ovr_SetClientColorDesc.Ptr) {
+ return ovrError_NotInitialized;
+ }
+
+ return API.ovr_SetClientColorDesc.Ptr(session, hmdColorDesc);
+}
+
+OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session) {
+ if (!API.ovr_GetTrackerCount.Ptr) {
+ return 0;
+ }
+
+ return API.ovr_GetTrackerCount.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrTrackerDesc)
+ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex) {
+ if (!API.ovr_GetTrackerDesc.Ptr) {
+ ovrTrackerDesc trackerDesc;
+ memset(&trackerDesc, 0, sizeof(trackerDesc));
+ return trackerDesc;
+ }
+
+ return API.ovr_GetTrackerDesc.Ptr(session, trackerDescIndex);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid) {
+ if (!API.ovr_Create.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_Create.Ptr(pSession, pLuid);
+}
+
+OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session) {
+ if (!API.ovr_Destroy.Ptr)
+ return;
+ API.ovr_Destroy.Ptr(session);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus) {
+ if (!API.ovr_GetSessionStatus.Ptr) {
+ if (sessionStatus) {
+ sessionStatus->IsVisible = ovrFalse;
+ sessionStatus->HmdPresent = ovrFalse;
+ sessionStatus->HmdMounted = ovrFalse;
+ sessionStatus->ShouldQuit = ovrFalse;
+ sessionStatus->DisplayLost = ovrFalse;
+ sessionStatus->ShouldRecenter = ovrFalse;
+ sessionStatus->HasInputFocus = ovrFalse;
+ sessionStatus->OverlayPresent = ovrFalse;
+ sessionStatus->DepthRequested = ovrFalse;
+ }
+
+ return ovrError_NotInitialized;
+ }
+
+ return API.ovr_GetSessionStatus.Ptr(session, sessionStatus);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_IsExtensionSupported(ovrSession session, ovrExtensions extension, ovrBool* extensionSupported) {
+ if (!API.ovr_IsExtensionSupported.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_IsExtensionSupported.Ptr(session, extension, extensionSupported);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_EnableExtension(ovrSession session, ovrExtensions extension) {
+ if (!API.ovr_EnableExtension.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_EnableExtension.Ptr(session, extension);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin) {
+ if (!API.ovr_SetTrackingOriginType.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_SetTrackingOriginType.Ptr(session, origin);
+}
+
+OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session) {
+ if (!API.ovr_GetTrackingOriginType.Ptr)
+ return ovrTrackingOrigin_EyeLevel;
+ return API.ovr_GetTrackingOriginType.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session) {
+ if (!API.ovr_RecenterTrackingOrigin.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_RecenterTrackingOrigin.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_SpecifyTrackingOrigin(ovrSession session, ovrPosef originPose) {
+ if (!API.ovr_SpecifyTrackingOrigin.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_SpecifyTrackingOrigin.Ptr(session, originPose);
+}
+
+OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session) {
+ if (!API.ovr_ClearShouldRecenterFlag.Ptr)
+ return;
+ API.ovr_ClearShouldRecenterFlag.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrTrackingState)
+ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker) {
+ if (!API.ovr_GetTrackingState.Ptr) {
+ ovrTrackingState nullTrackingState;
+ memset(&nullTrackingState, 0, sizeof(nullTrackingState));
+ return nullTrackingState;
+ }
+
+ return API.ovr_GetTrackingState.Ptr(session, absTime, latencyMarker);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetDevicePoses(
+ ovrSession session,
+ ovrTrackedDeviceType* deviceTypes,
+ int deviceCount,
+ double absTime,
+ ovrPoseStatef* outDevicePoses) {
+ if (!API.ovr_GetDevicePoses.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_GetDevicePoses.Ptr(session, deviceTypes, deviceCount, absTime, outDevicePoses);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrTrackerPose)
+ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex) {
+ if (!API.ovr_GetTrackerPose.Ptr) {
+ ovrTrackerPose nullTrackerPose;
+ memset(&nullTrackerPose, 0, sizeof(nullTrackerPose));
+ return nullTrackerPose;
+ }
+
+ return API.ovr_GetTrackerPose.Ptr(session, trackerPoseIndex);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState) {
+ if (!API.ovr_GetInputState.Ptr) {
+ if (inputState)
+ memset(inputState, 0, sizeof(ovrInputState));
+ return ovrError_NotInitialized;
+ }
+ return API.ovr_GetInputState.Ptr(session, controllerType, inputState);
+}
+
+
+OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session) {
+ if (!API.ovr_GetConnectedControllerTypes.Ptr) {
+ return 0;
+ }
+ return API.ovr_GetConnectedControllerTypes.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc)
+ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType) {
+ if (!API.ovr_GetTouchHapticsDesc.Ptr) {
+ ovrTouchHapticsDesc nullDesc;
+ memset(&nullDesc, 0, sizeof(nullDesc));
+ return nullDesc;
+ }
+
+ return API.ovr_GetTouchHapticsDesc.Ptr(session, controllerType);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SetControllerVibration(
+ ovrSession session,
+ ovrControllerType controllerType,
+ float frequency,
+ float amplitude) {
+ if (!API.ovr_SetControllerVibration.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_SetControllerVibration.Ptr(session, controllerType, frequency, amplitude);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SubmitControllerVibration(
+ ovrSession session,
+ ovrControllerType controllerType,
+ const ovrHapticsBuffer* buffer) {
+ if (!API.ovr_SubmitControllerVibration.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_SubmitControllerVibration.Ptr(session, controllerType, buffer);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetControllerVibrationState(
+ ovrSession session,
+ ovrControllerType controllerType,
+ ovrHapticsPlaybackState* outState) {
+ if (!API.ovr_GetControllerVibrationState.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetControllerVibrationState.Ptr(session, controllerType, outState);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_TestBoundary(
+ ovrSession session,
+ ovrTrackedDeviceType deviceBitmask,
+ ovrBoundaryType singleBoundaryType,
+ ovrBoundaryTestResult* outTestResult) {
+ if (!API.ovr_TestBoundary.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_TestBoundary.Ptr(session, deviceBitmask, singleBoundaryType, outTestResult);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_TestBoundaryPoint(
+ ovrSession session,
+ const ovrVector3f* point,
+ ovrBoundaryType singleBoundaryType,
+ ovrBoundaryTestResult* outTestResult) {
+ if (!API.ovr_TestBoundaryPoint.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_TestBoundaryPoint.Ptr(session, point, singleBoundaryType, outTestResult);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SetBoundaryLookAndFeel(ovrSession session, const ovrBoundaryLookAndFeel* lookAndFeel) {
+ if (!API.ovr_SetBoundaryLookAndFeel.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_SetBoundaryLookAndFeel.Ptr(session, lookAndFeel);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetBoundaryLookAndFeel(ovrSession session) {
+ if (!API.ovr_ResetBoundaryLookAndFeel.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_ResetBoundaryLookAndFeel.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetBoundaryGeometry(
+ ovrSession session,
+ ovrBoundaryType singleBoundaryType,
+ ovrVector3f* outFloorPoints,
+ int* outFloorPointsCount) {
+ if (!API.ovr_GetBoundaryGeometry.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetBoundaryGeometry.Ptr(
+ session, singleBoundaryType, outFloorPoints, outFloorPointsCount);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetBoundaryDimensions(
+ ovrSession session,
+ ovrBoundaryType singleBoundaryType,
+ ovrVector3f* outDimensions) {
+ if (!API.ovr_GetBoundaryDimensions.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetBoundaryDimensions.Ptr(session, singleBoundaryType, outDimensions);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetBoundaryVisible(ovrSession session, ovrBool* outIsVisible) {
+ if (!API.ovr_GetBoundaryVisible.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetBoundaryVisible.Ptr(session, outIsVisible);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_RequestBoundaryVisible(ovrSession session, ovrBool visible) {
+ if (!API.ovr_RequestBoundaryVisible.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_RequestBoundaryVisible.Ptr(session, visible);
+}
+
+OVR_PUBLIC_FUNCTION(ovrSizei)
+ovr_GetFovTextureSize(
+ ovrSession session,
+ ovrEyeType eye,
+ ovrFovPort fov,
+ float pixelsPerDisplayPixel) {
+ if (!API.ovr_GetFovTextureSize.Ptr) {
+ ovrSizei nullSize;
+ memset(&nullSize, 0, sizeof(nullSize));
+ return nullSize;
+ }
+
+ return API.ovr_GetFovTextureSize.Ptr(session, eye, fov, pixelsPerDisplayPixel);
+}
+
+#if defined(_WIN32)
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateTextureSwapChainDX(
+ ovrSession session,
+ IUnknown* d3dPtr,
+ const ovrTextureSwapChainDesc* desc,
+ ovrTextureSwapChain* outTextureSet) {
+ if (!API.ovr_CreateTextureSwapChainDX.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateTextureSwapChainDX.Ptr(session, d3dPtr, desc, outTextureSet);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateMirrorTextureDX(
+ ovrSession session,
+ IUnknown* d3dPtr,
+ const ovrMirrorTextureDesc* desc,
+ ovrMirrorTexture* outMirrorTexture) {
+ if (!API.ovr_CreateMirrorTextureDX.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateMirrorTextureDX.Ptr(session, d3dPtr, desc, outMirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateMirrorTextureWithOptionsDX(
+ ovrSession session,
+ IUnknown* d3dPtr,
+ const ovrMirrorTextureDesc* desc,
+ ovrMirrorTexture* outMirrorTexture) {
+ if (!API.ovr_CreateMirrorTextureWithOptionsDX.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateMirrorTextureWithOptionsDX.Ptr(session, d3dPtr, desc, outMirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainBufferDX(
+ ovrSession session,
+ ovrTextureSwapChain chain,
+ int index,
+ IID iid,
+ void** ppObject) {
+ if (!API.ovr_GetTextureSwapChainBufferDX.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainBufferDX.Ptr(session, chain, index, iid, ppObject);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetMirrorTextureBufferDX(
+ ovrSession session,
+ ovrMirrorTexture mirror,
+ IID iid,
+ void** ppObject) {
+ if (!API.ovr_GetMirrorTextureBufferDX.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetMirrorTextureBufferDX.Ptr(session, mirror, iid, ppObject);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(unsigned int* deviceOutId) {
+ if (!API.ovr_GetAudioDeviceOutWaveId.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceOutWaveId.Ptr(deviceOutId);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(unsigned int* deviceInId) {
+ if (!API.ovr_GetAudioDeviceInWaveId.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceInWaveId.Ptr(deviceInId);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR* deviceOutStrBuffer) {
+ if (!API.ovr_GetAudioDeviceOutGuidStr.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceOutGuidStr.Ptr(deviceOutStrBuffer);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid) {
+ if (!API.ovr_GetAudioDeviceOutGuid.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceOutGuid.Ptr(deviceOutGuid);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR* deviceInStrBuffer) {
+ if (!API.ovr_GetAudioDeviceInGuidStr.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceInGuidStr.Ptr(deviceInStrBuffer);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid) {
+ if (!API.ovr_GetAudioDeviceInGuid.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetAudioDeviceInGuid.Ptr(deviceInGuid);
+}
+
+#endif // _WIN32
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateTextureSwapChainGL(
+ ovrSession session,
+ const ovrTextureSwapChainDesc* desc,
+ ovrTextureSwapChain* outTextureSet) {
+ if (!API.ovr_CreateTextureSwapChainGL.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateTextureSwapChainGL.Ptr(session, desc, outTextureSet);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateMirrorTextureGL(
+ ovrSession session,
+ const ovrMirrorTextureDesc* desc,
+ ovrMirrorTexture* outMirrorTexture) {
+ if (!API.ovr_CreateMirrorTextureGL.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateMirrorTextureGL.Ptr(session, desc, outMirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateMirrorTextureWithOptionsGL(
+ ovrSession session,
+ const ovrMirrorTextureDesc* desc,
+ ovrMirrorTexture* outMirrorTexture) {
+ if (!API.ovr_CreateMirrorTextureWithOptionsGL.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateMirrorTextureWithOptionsGL.Ptr(session, desc, outMirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainBufferGL(
+ ovrSession session,
+ ovrTextureSwapChain chain,
+ int index,
+ unsigned int* texId) {
+ if (!API.ovr_GetTextureSwapChainBufferGL.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainBufferGL.Ptr(session, chain, index, texId);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetMirrorTextureBufferGL(ovrSession session, ovrMirrorTexture mirror, unsigned int* texId) {
+ if (!API.ovr_GetMirrorTextureBufferGL.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetMirrorTextureBufferGL.Ptr(session, mirror, texId);
+}
+
+#if defined(_WIN32)
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetInstanceExtensionsVk(
+ ovrGraphicsLuid luid,
+ char* extensionNames,
+ uint32_t* inoutExtensionNamesSize) {
+ if (!API.ovr_GetInstanceExtensionsVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetInstanceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetDeviceExtensionsVk(
+ ovrGraphicsLuid luid,
+ char* extensionNames,
+ uint32_t* inoutExtensionNamesSize) {
+ if (!API.ovr_GetDeviceExtensionsVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetDeviceExtensionsVk.Ptr(luid, extensionNames, inoutExtensionNamesSize);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetSessionPhysicalDeviceVk(
+ ovrSession session,
+ ovrGraphicsLuid luid,
+ VkInstance instance,
+ VkPhysicalDevice* out_physicalDevice) {
+ if (!API.ovr_GetSessionPhysicalDeviceVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetSessionPhysicalDeviceVk.Ptr(session, luid, instance, out_physicalDevice);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetSynchronizationQueueVk(ovrSession session, VkQueue queue) {
+ if (!API.ovr_SetSynchronizationQueueVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_SetSynchronizationQueueVk.Ptr(session, queue);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateTextureSwapChainVk(
+ ovrSession session,
+ VkDevice device,
+ const ovrTextureSwapChainDesc* desc,
+ ovrTextureSwapChain* out_TextureSwapChain) {
+ if (!API.ovr_CreateTextureSwapChainVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateTextureSwapChainVk.Ptr(session, device, desc, out_TextureSwapChain);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainBufferVk(
+ ovrSession session,
+ ovrTextureSwapChain chain,
+ int index,
+ VkImage* out_Image) {
+ if (!API.ovr_GetTextureSwapChainBufferVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainBufferVk.Ptr(session, chain, index, out_Image);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CreateMirrorTextureWithOptionsVk(
+ ovrSession session,
+ VkDevice device,
+ const ovrMirrorTextureDesc* desc,
+ ovrMirrorTexture* out_MirrorTexture) {
+ if (!API.ovr_CreateMirrorTextureWithOptionsVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CreateMirrorTextureWithOptionsVk.Ptr(session, device, desc, out_MirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetMirrorTextureBufferVk(
+ ovrSession session,
+ ovrMirrorTexture mirrorTexture,
+ VkImage* out_Image) {
+ if (!API.ovr_GetMirrorTextureBufferVk.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetMirrorTextureBufferVk.Ptr(session, mirrorTexture, out_Image);
+}
+#endif // defined (_WIN32)
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* length) {
+ if (!API.ovr_GetTextureSwapChainLength.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainLength.Ptr(session, chain, length);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainCurrentIndex(
+ ovrSession session,
+ ovrTextureSwapChain chain,
+ int* currentIndex) {
+ if (!API.ovr_GetTextureSwapChainCurrentIndex.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainCurrentIndex.Ptr(session, chain, currentIndex);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetTextureSwapChainDesc(
+ ovrSession session,
+ ovrTextureSwapChain chain,
+ ovrTextureSwapChainDesc* desc) {
+ if (!API.ovr_GetTextureSwapChainDesc.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetTextureSwapChainDesc.Ptr(session, chain, desc);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) {
+ if (!API.ovr_CommitTextureSwapChain.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_CommitTextureSwapChain.Ptr(session, chain);
+}
+
+OVR_PUBLIC_FUNCTION(void)
+ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain) {
+ if (!API.ovr_DestroyTextureSwapChain.Ptr)
+ return;
+
+ API.ovr_DestroyTextureSwapChain.Ptr(session, chain);
+}
+
+OVR_PUBLIC_FUNCTION(void)
+ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture) {
+ if (!API.ovr_DestroyMirrorTexture.Ptr)
+ return;
+
+ API.ovr_DestroyMirrorTexture.Ptr(session, mirrorTexture);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetFovStencil(
+ ovrSession session,
+ const ovrFovStencilDesc* fovStencilDesc,
+ ovrFovStencilMeshBuffer* meshBuffer) {
+ if (!API.ovr_GetFovStencil.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetFovStencil.Ptr(session, fovStencilDesc, meshBuffer);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_WaitToBeginFrame(ovrSession session, long long frameIndex) {
+ if (!API.ovr_WaitToBeginFrame.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_WaitToBeginFrame.Ptr(session, frameIndex);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_BeginFrame(ovrSession session, long long frameIndex) {
+ if (!API.ovr_BeginFrame.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_BeginFrame.Ptr(session, frameIndex);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_EndFrame(
+ ovrSession session,
+ long long frameIndex,
+ const ovrViewScaleDesc* viewScaleDesc,
+ ovrLayerHeader const* const* layerPtrList,
+ unsigned int layerCount) {
+ if (!API.ovr_EndFrame.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_EndFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SubmitFrame(
+ ovrSession session,
+ long long frameIndex,
+ const ovrViewScaleDesc* viewScaleDesc,
+ ovrLayerHeader const* const* layerPtrList,
+ unsigned int layerCount) {
+ if (!API.ovr_SubmitFrame.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_SubmitFrame.Ptr(session, frameIndex, viewScaleDesc, layerPtrList, layerCount);
+}
+
+
+OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc)
+ovr_GetRenderDesc(ovrSession session, ovrEyeType eyeType, ovrFovPort fov) {
+ if (!API.ovr_GetRenderDesc.Ptr) {
+ ovrEyeRenderDesc nullEyeRenderDesc;
+ memset(&nullEyeRenderDesc, 0, sizeof(nullEyeRenderDesc));
+ return nullEyeRenderDesc;
+ }
+ return API.ovr_GetRenderDesc.Ptr(session, eyeType, fov);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetPerfStats(ovrSession session, ovrPerfStats* outPerfStats) {
+ if (!API.ovr_GetPerfStats.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_GetPerfStats.Ptr(session, outPerfStats);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_ResetPerfStats(ovrSession session) {
+ if (!API.ovr_ResetPerfStats.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_ResetPerfStats.Ptr(session);
+}
+
+OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex) {
+ if (!API.ovr_GetPredictedDisplayTime.Ptr)
+ return 0.0;
+
+ return API.ovr_GetPredictedDisplayTime.Ptr(session, frameIndex);
+}
+
+OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds() {
+ if (!API.ovr_GetTimeInSeconds.Ptr)
+ return 0.;
+ return API.ovr_GetTimeInSeconds.Ptr();
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool)
+ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal) {
+ if (!API.ovr_GetBool.Ptr)
+ return ovrFalse;
+ return API.ovr_GetBool.Ptr(session, propertyName, defaultVal);
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool)
+ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value) {
+ if (!API.ovr_SetBool.Ptr)
+ return ovrFalse;
+ return API.ovr_SetBool.Ptr(session, propertyName, value);
+}
+
+OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal) {
+ if (!API.ovr_GetInt.Ptr)
+ return 0;
+ return API.ovr_GetInt.Ptr(session, propertyName, defaultVal);
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value) {
+ if (!API.ovr_SetInt.Ptr)
+ return ovrFalse;
+ return API.ovr_SetInt.Ptr(session, propertyName, value);
+}
+
+OVR_PUBLIC_FUNCTION(float)
+ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal) {
+ if (!API.ovr_GetFloat.Ptr)
+ return 0.f;
+ return API.ovr_GetFloat.Ptr(session, propertyName, defaultVal);
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool)
+ovr_SetFloat(ovrSession session, const char* propertyName, float value) {
+ if (!API.ovr_SetFloat.Ptr)
+ return ovrFalse;
+ return API.ovr_SetFloat.Ptr(session, propertyName, value);
+}
+
+OVR_PUBLIC_FUNCTION(unsigned int)
+ovr_GetFloatArray(
+ ovrSession session,
+ const char* propertyName,
+ float values[],
+ unsigned int arraySize) {
+ if (!API.ovr_GetFloatArray.Ptr)
+ return 0;
+ return API.ovr_GetFloatArray.Ptr(session, propertyName, values, arraySize);
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool)
+ovr_SetFloatArray(
+ ovrSession session,
+ const char* propertyName,
+ const float values[],
+ unsigned int arraySize) {
+ if (!API.ovr_SetFloatArray.Ptr)
+ return ovrFalse;
+ return API.ovr_SetFloatArray.Ptr(session, propertyName, values, arraySize);
+}
+
+OVR_PUBLIC_FUNCTION(const char*)
+ovr_GetString(ovrSession session, const char* propertyName, const char* defaultVal) {
+ if (!API.ovr_GetString.Ptr)
+ return "(Unable to load LibOVR)";
+ return API.ovr_GetString.Ptr(session, propertyName, defaultVal);
+}
+
+OVR_PUBLIC_FUNCTION(ovrBool)
+ovr_SetString(ovrSession session, const char* propertyName, const char* value) {
+ if (!API.ovr_SetString.Ptr)
+ return ovrFalse;
+ return API.ovr_SetString.Ptr(session, propertyName, value);
+}
+
+OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message) {
+ if (!API.ovr_TraceMessage.Ptr)
+ return -1;
+
+ return API.ovr_TraceMessage.Ptr(level, message);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity) {
+ if (!API.ovr_IdentifyClient.Ptr)
+ return ovrError_NotInitialized;
+
+ return API.ovr_IdentifyClient.Ptr(identity);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_Lookup(const char* name, void** data) {
+ if (!API.ovr_Lookup.Ptr)
+ return ovrError_NotInitialized;
+ return API.ovr_Lookup.Ptr(name, data);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_GetExternalCameras(
+ ovrSession session,
+ ovrExternalCamera* outCameras,
+ unsigned int* outCameraCount) {
+ if (!API.ovr_GetExternalCameras.Ptr)
+ return ovrError_NotInitialized;
+ if (!outCameras || !outCameraCount)
+ return ovrError_InvalidParameter;
+
+ return API.ovr_GetExternalCameras.Ptr(session, outCameras, outCameraCount);
+}
+
+OVR_PUBLIC_FUNCTION(ovrResult)
+ovr_SetExternalCameraProperties(
+ ovrSession session,
+ const char* name,
+ const ovrCameraIntrinsics* const intrinsics,
+ const ovrCameraExtrinsics* const extrinsics) {
+ if (!API.ovr_SetExternalCameraProperties.Ptr)
+ return ovrError_NotInitialized;
+ if (!name || (!intrinsics && !extrinsics))
+ return ovrError_InvalidParameter;
+
+ return API.ovr_SetExternalCameraProperties.Ptr(session, name, intrinsics, extrinsics);
+}
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif