diff --git a/examples/BasicDemo/premake4.lua b/examples/BasicDemo/premake4.lua index a480b82c9..cb16d4b79 100644 --- a/examples/BasicDemo/premake4.lua +++ b/examples/BasicDemo/premake4.lua @@ -187,6 +187,7 @@ files { "../ThirdPartyLibs/openvr/samples/shared/lodepng.h", "../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp", "../ThirdPartyLibs/openvr/samples/shared/Matrices.h", + "../ThirdPartyLibs/openvr/samples/shared/strtools.cpp", "../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp", "../ThirdPartyLibs/openvr/samples/shared/pathtools.h", "../ThirdPartyLibs/openvr/samples/shared/Vectors.h", diff --git a/examples/SharedMemory/premake4.lua b/examples/SharedMemory/premake4.lua index 20d97c36b..ff2ab709f 100644 --- a/examples/SharedMemory/premake4.lua +++ b/examples/SharedMemory/premake4.lua @@ -344,6 +344,7 @@ if os.is("Windows") then "../ThirdPartyLibs/openvr/samples/shared/lodepng.h", "../ThirdPartyLibs/openvr/samples/shared/Matrices.cpp", "../ThirdPartyLibs/openvr/samples/shared/Matrices.h", + "../ThirdPartyLibs/openvr/samples/shared/strtools.cpp", "../ThirdPartyLibs/openvr/samples/shared/pathtools.cpp", "../ThirdPartyLibs/openvr/samples/shared/pathtools.h", "../ThirdPartyLibs/openvr/samples/shared/Vectors.h", diff --git a/examples/ThirdPartyLibs/openvr/bin/linux32/libopenvr_api.so b/examples/ThirdPartyLibs/openvr/bin/linux32/libopenvr_api.so new file mode 100644 index 000000000..00825b982 Binary files /dev/null and b/examples/ThirdPartyLibs/openvr/bin/linux32/libopenvr_api.so differ diff --git a/examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so b/examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so index 7b6f2d2de..8d30531dc 100644 Binary files a/examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so and b/examples/ThirdPartyLibs/openvr/bin/linux64/libopenvr_api.so differ diff --git a/examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib b/examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib index 647ec3fa9..5a20f3aae 100644 Binary files a/examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib and b/examples/ThirdPartyLibs/openvr/bin/osx32/libopenvr_api.dylib differ diff --git a/examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll b/examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll index 7aa2b993a..aafef728c 100644 Binary files a/examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll and b/examples/ThirdPartyLibs/openvr/bin/win32/openvr_api.dll differ diff --git a/examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll b/examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll index bbcccde55..ddda89700 100644 Binary files a/examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll and b/examples/ThirdPartyLibs/openvr/bin/win64/openvr_api.dll differ diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr.h b/examples/ThirdPartyLibs/openvr/headers/openvr.h index 6617b4d34..2020e9d3a 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr.h @@ -21,19 +21,13 @@ struct VkPhysicalDevice_T; struct VkInstance_T; struct VkQueue_T; +// Forward declarations to avoid requiring d3d12.h +struct ID3D12Resource; +struct ID3D12CommandQueue; + namespace vr { - -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) typedef void* glSharedTextureHandle_t; typedef int32_t glInt_t; @@ -116,6 +110,8 @@ enum ETextureType TextureType_DirectX = 0, // Handle is an ID3D11Texture TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace @@ -164,6 +160,7 @@ enum ETrackedDeviceClass TrackedDeviceClass_Controller = 2, // Tracked controllers TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; @@ -199,6 +196,30 @@ enum ETrackingUniverseOrigin TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; +// Refers to a single container of properties +typedef uint64_t PropertyContainerHandle_t; +typedef uint32_t PropertyTypeTag_t; + +static const PropertyContainerHandle_t k_ulInvalidPropertyContainer = 0; +static const PropertyTypeTag_t k_unInvalidPropertyTag = 0; + +// Use these tags to set/get common types as struct properties +static const PropertyTypeTag_t k_unFloatPropertyTag = 1; +static const PropertyTypeTag_t k_unInt32PropertyTag = 2; +static const PropertyTypeTag_t k_unUint64PropertyTag = 3; +static const PropertyTypeTag_t k_unBoolPropertyTag = 4; +static const PropertyTypeTag_t k_unStringPropertyTag = 5; + +static const PropertyTypeTag_t k_unHmdMatrix34PropertyTag = 20; +static const PropertyTypeTag_t k_unHmdMatrix44PropertyTag = 21; +static const PropertyTypeTag_t k_unHmdVector3PropertyTag = 22; +static const PropertyTypeTag_t k_unHmdVector4PropertyTag = 23; + +static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; + +static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; +static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; + /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ @@ -241,6 +262,8 @@ enum ETrackedDeviceProperty Prop_DriverVersion_String = 1031, Prop_Firmware_ForceUpdateRequired_Bool = 1032, Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD Prop_ReportsTimeSinceVSync_Bool = 2000, @@ -281,6 +304,11 @@ enum ETrackedDeviceProperty Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, Prop_DisplaySuppressed_Bool = 2036, Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, // Properties that are unique to TrackedDeviceClass_Controller Prop_AttachedDeviceId_String = 3000, @@ -312,6 +340,19 @@ enum ETrackedDeviceProperty Prop_NamedIconPathDeviceStandby_String = 5007, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others Prop_NamedIconPathDeviceAlertLow_String = 5008, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + // Properties that are used by helpers, but are opaque to applications + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, + + // Properties that are unique to drivers + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, + // Vendors are free to expose private debug data in this reserved region Prop_VendorSpecific_Reserved_Start = 10000, Prop_VendorSpecific_Reserved_End = 10999, @@ -327,13 +368,14 @@ enum ETrackedPropertyError TrackedProp_WrongDataType = 1, TrackedProp_WrongDeviceClass = 2, TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). TrackedProp_InvalidDevice = 5, TrackedProp_CouldNotContactServer = 6, TrackedProp_ValueNotProvidedByDevice = 7, TrackedProp_StringExceedsMaximumLength = 8, TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -376,6 +418,14 @@ struct VRVulkanTextureData_t uint32_t m_nWidth, m_nHeight, m_nFormat, m_nSampleCount; }; +/** Data required for passing D3D12 textures to IVRCompositor::Submit. +* Be sure to call OpenVR_Shutdown before destroying these resources. */ +struct D3D12TextureData_t +{ + ID3D12Resource *m_pResource; + ID3D12CommandQueue *m_pCommandQueue; + uint32_t m_nNodeMask; +}; /** Status of the overall system or tracked objects */ enum EVRState @@ -399,7 +449,7 @@ enum EVREventType VREvent_TrackedDeviceActivated = 100, VREvent_TrackedDeviceDeactivated = 101, VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionStarted = 103, VREvent_TrackedDeviceUserInteractionEnded = 104, VREvent_IpdChanged = 105, VREvent_EnterStandbyMode = 106, @@ -407,6 +457,7 @@ enum EVREventType VREvent_TrackedDeviceRoleChanged = 108, VREvent_WatchdogWakeUpRequested = 109, VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, VREvent_ButtonPress = 200, // data is controller VREvent_ButtonUnpress = 201, // data is controller @@ -436,78 +487,83 @@ enum EVREventType VREvent_OverlayShown = 500, VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + + VREvent_PrimaryDashboardDeviceChanged = 525, VREvent_Notification_Shown = 600, VREvent_Notification_Hidden = 601, VREvent_Notification_BeginInteraction = 602, VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, VREvent_TrackedCamera_StartVideoStream = 1500, VREvent_TrackedCamera_StopVideoStream = 1501, @@ -515,26 +571,30 @@ enum EVREventType VREvent_TrackedCamera_ResumeVideoStream = 1503, VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, - VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlay_Closed = 1650, // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; /** Level of Hmd activity */ +// UserInteraction_Timeout means the device is in the process of timing out. +// InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) +// VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. +// VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, - k_EDeviceActivityLevel_UserInteraction = 1, - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, - k_EDeviceActivityLevel_Standby = 3, +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; @@ -711,6 +771,12 @@ struct VREvent_MessageOverlay_t uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; +struct VREvent_Property_t +{ + PropertyContainerHandle_t container; + ETrackedDeviceProperty prop; +}; + /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ typedef union { @@ -733,8 +799,16 @@ typedef union VREvent_ApplicationLaunch_t applicationLaunch; VREvent_EditingCameraSurface_t cameraSurface; VREvent_MessageOverlay_t messageOverlay; + VREvent_Property_t property; } VREvent_Data_t; + +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + /** An event posted by the server to all running applications */ struct VREvent_t { @@ -745,6 +819,9 @@ struct VREvent_t VREvent_Data_t data; }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif /** The mesh to draw into the stencil (or depth) buffer to perform * early stencil (or depth) kills of pixels that will never appear on the HMD. @@ -764,6 +841,8 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Standard = 0, k_eHiddenAreaMesh_Inverse = 1, k_eHiddenAreaMesh_LineLoop = 2, + + k_eHiddenAreaMesh_Max = 3, }; @@ -791,6 +870,12 @@ struct VRControllerAxis_t static const uint32_t k_unControllerStateAxisCount = 5; +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { @@ -805,6 +890,9 @@ struct VRControllerState001_t // Axis data for the controller's analog inputs VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif typedef VRControllerState001_t VRControllerState_t; @@ -887,6 +975,7 @@ enum EVRApplicationType // interfaces (like IVRSettings and IVRApplications) but not hardware. VRApplication_VRMonitor = 5, // Reserved for vrmonitor VRApplication_SteamWatchdog = 6,// Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; @@ -1173,9 +1262,7 @@ public: /** [D3D10/11 Only] * Returns the adapter index that the user should pass into EnumAdapters to create the device - * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. The index will - * also be -1 if the headset is in direct mode on the driver side instead of using the compositor's - * builtin direct mode support. + * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. */ virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0; @@ -1453,6 +1540,7 @@ namespace vr VRApplicationProperty_IsDashboardOverlay_Bool = 60, VRApplicationProperty_IsTemplate_Bool = 61, VRApplicationProperty_IsInstanced_Bool = 62, + VRApplicationProperty_IsInternal_Bool = 63, VRApplicationProperty_LastLaunchTime_Uint64 = 70, }; @@ -1600,6 +1688,11 @@ namespace vr * If working directory is NULL or "" the directory portion of the binary path will be * the working directory. */ virtual EVRApplicationError LaunchInternalProcess( const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory ) = 0; + + /** Returns the current scene process ID according to the application system. A scene process will get scene + * focus once it starts rendering, but it will appear here once it calls VR_Init with the Scene application + * type. */ + virtual uint32_t GetCurrentSceneProcessId() = 0; }; static const char * const IVRApplications_Version = "IVRApplications_006"; @@ -1657,7 +1750,6 @@ namespace vr static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion"; static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; @@ -1708,7 +1800,6 @@ namespace vr //----------------------------------------------------------------------------- // null keys static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_EnableNullDriver_Bool = "enable"; static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; static const char * const k_pch_Null_WindowX_Int32 = "windowX"; @@ -1809,22 +1900,17 @@ namespace vr // model skin keys static const char * const k_pch_modelskin_Section = "modelskins"; + //----------------------------------------------------------------------------- + // driver keys - These could be checked in any driver_ section + static const char * const k_pch_Driver_Enable_Bool = "enable"; + } // namespace vr // ivrchaperone.h namespace vr { -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) enum ChaperoneCalibrationState { @@ -1985,16 +2071,7 @@ static const char * const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; namespace vr { -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) /** Errors that can occur with the VR compositor */ enum EVRCompositorError @@ -2237,8 +2314,10 @@ public: /** Temporarily suspends rendering (useful for finer control over scene transitions). */ virtual void SuspendRendering( bool bSuspend ) = 0; - /** Opens a shared D3D11 texture with the undistorted composited image for each eye. */ + /** Opens a shared D3D11 texture with the undistorted composited image for each eye. Use ReleaseMirrorTextureD3D11 when finished + * instead of calling Release on the resource itself. */ virtual vr::EVRCompositorError GetMirrorTextureD3D11( vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView ) = 0; + virtual void ReleaseMirrorTextureD3D11( void *pD3D11ShaderResourceView ) = 0; /** Access to mirror textures from OpenGL. */ virtual vr::EVRCompositorError GetMirrorTextureGL( vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle ) = 0; @@ -2258,7 +2337,7 @@ public: }; -static const char * const IVRCompositor_Version = "IVRCompositor_019"; +static const char * const IVRCompositor_Version = "IVRCompositor_020"; } // namespace vr @@ -2268,16 +2347,7 @@ static const char * const IVRCompositor_Version = "IVRCompositor_019"; namespace vr { -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) // Used for passing graphic data struct NotificationBitmap_t @@ -2537,7 +2607,7 @@ namespace vr virtual EVROverlayError FindOverlay( const char *pchOverlayKey, VROverlayHandle_t * pOverlayHandle ) = 0; /** Creates a new named overlay. All overlays start hidden and with default settings. */ - virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t * pOverlayHandle ) = 0; + virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t * pOverlayHandle ) = 0; /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are * automatically destroyed. */ @@ -2562,6 +2632,9 @@ namespace vr * the terminating null character. k_unVROverlayMaxNameLength will be enough bytes to fit the string. */ virtual uint32_t GetOverlayName( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + /** set the name to use for this overlay */ + virtual EVROverlayError SetOverlayName( VROverlayHandle_t ulOverlayHandle, const char *pchName ) = 0; + /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height * will be set and VROverlayError_ArrayTooSmall is returned. */ virtual EVROverlayError GetOverlayImageData( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight ) = 0; @@ -2570,7 +2643,6 @@ namespace vr * of the error enum value for all valid error codes */ virtual const char *GetOverlayErrorNameFromEnum( EVROverlayError error ) = 0; - // --------------------------------------------- // Overlay rendering methods // --------------------------------------------- @@ -2647,6 +2719,13 @@ namespace vr /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Gets render model to draw behind this overlay */ + virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0; + + /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. + The model is scaled by the same amount as the overlay, with a default of 1m. */ + virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0; + /** Returns the transform type of this overlay. */ virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0; @@ -2669,6 +2748,12 @@ namespace vr /** Gets the transform information when the overlay is rendering on a component. */ virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0; + /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ + virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + + /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ + virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; @@ -2839,7 +2924,7 @@ namespace vr virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0; }; - static const char * const IVROverlay_Version = "IVROverlay_014"; + static const char * const IVROverlay_Version = "IVROverlay_016"; } // namespace vr @@ -2853,16 +2938,7 @@ static const char * const k_pch_Controller_Component_Tip = "tip"; // F static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping -#if defined(__linux__) || defined(__APPLE__) -// The 32-bit version of gcc has the alignment requirement for uint64 and double set to -// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. -// The 64-bit version of gcc has the alignment requirement for these types set to -// 8 meaning that unless we use #pragma pack(4) our structures will get bigger. -// The 64-bit structure packing has to match the 32-bit structure packing for each platform. -#pragma pack( push, 4 ) -#else #pragma pack( push, 8 ) -#endif /** Errors that can occur with the VR compositor */ enum EVRRenderModelError @@ -2911,11 +2987,20 @@ struct RenderModel_Vertex_t }; /** A texture map for use on a render model */ +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + struct RenderModel_TextureMap_t { uint16_t unWidth, unHeight; // width and height of the texture map in pixels const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. IDs <0 denote the texture is not present */ @@ -2924,6 +3009,12 @@ typedef int32_t TextureID_t; const TextureID_t INVALID_TEXTURE_ID = -1; +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + struct RenderModel_t { const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh @@ -2932,6 +3023,10 @@ struct RenderModel_t uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif + struct RenderModel_ControllerMode_State_t { @@ -3168,7 +3263,7 @@ public: * once SubmitScreenshot() is called. * If Steam is not running, the paths will be in the user's * documents folder under Documents\SteamVR\Screenshots. - * Other VR applications can call this to initate a + * Other VR applications can call this to initiate a * screenshot outside of user control. * The destination file names do not need an extension, * will be replaced with the correct one for the format @@ -3206,7 +3301,7 @@ public: * submitted scene textures of the running application and * write them into the preview image and a side-by-side file * for the VR image. - * This is similiar to request screenshot, but doesn't ever + * This is similar to request screenshot, but doesn't ever * talk to the application, just takes the shot and submits. */ virtual vr::EVRScreenshotError TakeStereoScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; @@ -3217,8 +3312,7 @@ public: * function will display a notification to the user that the * screenshot was taken. The paths should be full paths with * extensions. - * File paths should be absolute including - * exntensions. + * File paths should be absolute including extensions. * screenshotHandle can be k_unScreenshotHandleInvalid if this * was a new shot taking by the app to be saved and not * initiated by a user (achievement earned or something) */ @@ -3291,7 +3385,7 @@ namespace vr /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol( EVRInitError error ); - /** Returns an english string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and + /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_api.cs b/examples/ThirdPartyLibs/openvr/headers/openvr_api.cs index 98e09ef0b..377d91a65 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_api.cs +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_api.cs @@ -475,6 +475,11 @@ public struct IVRApplications [MarshalAs(UnmanagedType.FunctionPtr)] internal _LaunchInternalProcess LaunchInternalProcess; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate uint _GetCurrentSceneProcessId(); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _GetCurrentSceneProcessId GetCurrentSceneProcessId; + } [StructLayout(LayoutKind.Sequential)] @@ -800,6 +805,11 @@ public struct IVRCompositor [MarshalAs(UnmanagedType.FunctionPtr)] internal _GetMirrorTextureD3D11 GetMirrorTextureD3D11; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate void _ReleaseMirrorTextureD3D11(IntPtr pD3D11ShaderResourceView); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _ReleaseMirrorTextureD3D11 ReleaseMirrorTextureD3D11; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate EVRCompositorError _GetMirrorTextureGL(EVREye eEye, ref uint pglTextureId, IntPtr pglSharedTextureHandle); [MarshalAs(UnmanagedType.FunctionPtr)] @@ -841,7 +851,7 @@ public struct IVROverlay internal _FindOverlay FindOverlay; [UnmanagedFunctionPointer(CallingConvention.StdCall)] - internal delegate EVROverlayError _CreateOverlay(string pchOverlayKey, string pchOverlayFriendlyName, ref ulong pOverlayHandle); + internal delegate EVROverlayError _CreateOverlay(string pchOverlayKey, string pchOverlayName, ref ulong pOverlayHandle); [MarshalAs(UnmanagedType.FunctionPtr)] internal _CreateOverlay CreateOverlay; @@ -870,6 +880,11 @@ public struct IVROverlay [MarshalAs(UnmanagedType.FunctionPtr)] internal _GetOverlayName GetOverlayName; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate EVROverlayError _SetOverlayName(ulong ulOverlayHandle, string pchName); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _SetOverlayName SetOverlayName; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate EVROverlayError _GetOverlayImageData(ulong ulOverlayHandle, IntPtr pvBuffer, uint unBufferSize, ref uint punWidth, ref uint punHeight); [MarshalAs(UnmanagedType.FunctionPtr)] @@ -980,6 +995,16 @@ public struct IVROverlay [MarshalAs(UnmanagedType.FunctionPtr)] internal _GetOverlayTextureBounds GetOverlayTextureBounds; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate uint _GetOverlayRenderModel(ulong ulOverlayHandle, string pchValue, uint unBufferSize, ref HmdColor_t pColor, ref EVROverlayError pError); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _GetOverlayRenderModel GetOverlayRenderModel; + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate EVROverlayError _SetOverlayRenderModel(ulong ulOverlayHandle, string pchRenderModel, ref HmdColor_t pColor); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _SetOverlayRenderModel SetOverlayRenderModel; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate EVROverlayError _GetOverlayTransformType(ulong ulOverlayHandle, ref VROverlayTransformType peTransformType); [MarshalAs(UnmanagedType.FunctionPtr)] @@ -1015,6 +1040,16 @@ public struct IVROverlay [MarshalAs(UnmanagedType.FunctionPtr)] internal _GetOverlayTransformTrackedDeviceComponent GetOverlayTransformTrackedDeviceComponent; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate EVROverlayError _GetOverlayTransformOverlayRelative(ulong ulOverlayHandle, ref ulong ulOverlayHandleParent, ref HmdMatrix34_t pmatParentOverlayToOverlayTransform); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _GetOverlayTransformOverlayRelative GetOverlayTransformOverlayRelative; + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate EVROverlayError _SetOverlayTransformOverlayRelative(ulong ulOverlayHandle, ulong ulOverlayHandleParent, ref HmdMatrix34_t pmatParentOverlayToOverlayTransform); + [MarshalAs(UnmanagedType.FunctionPtr)] + internal _SetOverlayTransformOverlayRelative SetOverlayTransformOverlayRelative; + [UnmanagedFunctionPointer(CallingConvention.StdCall)] internal delegate EVROverlayError _ShowOverlay(ulong ulOverlayHandle); [MarshalAs(UnmanagedType.FunctionPtr)] @@ -1593,8 +1628,32 @@ public class CVRSystem IntPtr result = FnTable.GetPropErrorNameFromEnum(error); return Marshal.PtrToStringAnsi(result); } +// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were +// originally mis-compiled with the wrong packing for Linux and OSX. + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate bool _PollNextEventPacked(ref VREvent_t_Packed pEvent,uint uncbVREvent); + [StructLayout(LayoutKind.Explicit)] + struct PollNextEventUnion + { + [FieldOffset(0)] + public IVRSystem._PollNextEvent pPollNextEvent; + [FieldOffset(0)] + public _PollNextEventPacked pPollNextEventPacked; + } public bool PollNextEvent(ref VREvent_t pEvent,uint uncbVREvent) { + if ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) || + (System.Environment.OSVersion.Platform == System.PlatformID.Unix)) + { + PollNextEventUnion u; + VREvent_t_Packed event_packed = new VREvent_t_Packed(); + u.pPollNextEventPacked = null; + u.pPollNextEvent = FnTable.PollNextEvent; + bool packed_result = u.pPollNextEventPacked(ref event_packed,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VREvent_t_Packed))); + + event_packed.Unpack(ref pEvent); + return packed_result; + } bool result = FnTable.PollNextEvent(ref pEvent,uncbVREvent); return result; } @@ -1613,13 +1672,61 @@ public class CVRSystem HiddenAreaMesh_t result = FnTable.GetHiddenAreaMesh(eEye,type); return result; } +// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were +// originally mis-compiled with the wrong packing for Linux and OSX. + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate bool _GetControllerStatePacked(uint unControllerDeviceIndex,ref VRControllerState_t_Packed pControllerState,uint unControllerStateSize); + [StructLayout(LayoutKind.Explicit)] + struct GetControllerStateUnion + { + [FieldOffset(0)] + public IVRSystem._GetControllerState pGetControllerState; + [FieldOffset(0)] + public _GetControllerStatePacked pGetControllerStatePacked; + } public bool GetControllerState(uint unControllerDeviceIndex,ref VRControllerState_t pControllerState,uint unControllerStateSize) { + if ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) || + (System.Environment.OSVersion.Platform == System.PlatformID.Unix)) + { + GetControllerStateUnion u; + VRControllerState_t_Packed state_packed = new VRControllerState_t_Packed(pControllerState); + u.pGetControllerStatePacked = null; + u.pGetControllerState = FnTable.GetControllerState; + bool packed_result = u.pGetControllerStatePacked(unControllerDeviceIndex,ref state_packed,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t_Packed))); + + state_packed.Unpack(ref pControllerState); + return packed_result; + } bool result = FnTable.GetControllerState(unControllerDeviceIndex,ref pControllerState,unControllerStateSize); return result; } +// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were +// originally mis-compiled with the wrong packing for Linux and OSX. + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate bool _GetControllerStateWithPosePacked(ETrackingUniverseOrigin eOrigin,uint unControllerDeviceIndex,ref VRControllerState_t_Packed pControllerState,uint unControllerStateSize,ref TrackedDevicePose_t pTrackedDevicePose); + [StructLayout(LayoutKind.Explicit)] + struct GetControllerStateWithPoseUnion + { + [FieldOffset(0)] + public IVRSystem._GetControllerStateWithPose pGetControllerStateWithPose; + [FieldOffset(0)] + public _GetControllerStateWithPosePacked pGetControllerStateWithPosePacked; + } public bool GetControllerStateWithPose(ETrackingUniverseOrigin eOrigin,uint unControllerDeviceIndex,ref VRControllerState_t pControllerState,uint unControllerStateSize,ref TrackedDevicePose_t pTrackedDevicePose) { + if ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) || + (System.Environment.OSVersion.Platform == System.PlatformID.Unix)) + { + GetControllerStateWithPoseUnion u; + VRControllerState_t_Packed state_packed = new VRControllerState_t_Packed(pControllerState); + u.pGetControllerStateWithPosePacked = null; + u.pGetControllerStateWithPose = FnTable.GetControllerStateWithPose; + bool packed_result = u.pGetControllerStateWithPosePacked(eOrigin,unControllerDeviceIndex,ref state_packed,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t_Packed)),ref pTrackedDevicePose); + + state_packed.Unpack(ref pControllerState); + return packed_result; + } bool result = FnTable.GetControllerStateWithPose(eOrigin,unControllerDeviceIndex,ref pControllerState,unControllerStateSize,ref pTrackedDevicePose); return result; } @@ -1939,6 +2046,11 @@ public class CVRApplications EVRApplicationError result = FnTable.LaunchInternalProcess(pchBinaryPath,pchArguments,pchWorkingDirectory); return result; } + public uint GetCurrentSceneProcessId() + { + uint result = FnTable.GetCurrentSceneProcessId(); + return result; + } } @@ -2269,6 +2381,10 @@ public class CVRCompositor EVRCompositorError result = FnTable.GetMirrorTextureD3D11(eEye,pD3D11DeviceOrResource,ref ppD3D11ShaderResourceView); return result; } + public void ReleaseMirrorTextureD3D11(IntPtr pD3D11ShaderResourceView) + { + FnTable.ReleaseMirrorTextureD3D11(pD3D11ShaderResourceView); + } public EVRCompositorError GetMirrorTextureGL(EVREye eEye,ref uint pglTextureId,IntPtr pglSharedTextureHandle) { pglTextureId = 0; @@ -2314,10 +2430,10 @@ public class CVROverlay EVROverlayError result = FnTable.FindOverlay(pchOverlayKey,ref pOverlayHandle); return result; } - public EVROverlayError CreateOverlay(string pchOverlayKey,string pchOverlayFriendlyName,ref ulong pOverlayHandle) + public EVROverlayError CreateOverlay(string pchOverlayKey,string pchOverlayName,ref ulong pOverlayHandle) { pOverlayHandle = 0; - EVROverlayError result = FnTable.CreateOverlay(pchOverlayKey,pchOverlayFriendlyName,ref pOverlayHandle); + EVROverlayError result = FnTable.CreateOverlay(pchOverlayKey,pchOverlayName,ref pOverlayHandle); return result; } public EVROverlayError DestroyOverlay(ulong ulOverlayHandle) @@ -2345,6 +2461,11 @@ public class CVROverlay uint result = FnTable.GetOverlayName(ulOverlayHandle,pchValue,unBufferSize,ref pError); return result; } + public EVROverlayError SetOverlayName(ulong ulOverlayHandle,string pchName) + { + EVROverlayError result = FnTable.SetOverlayName(ulOverlayHandle,pchName); + return result; + } public EVROverlayError GetOverlayImageData(ulong ulOverlayHandle,IntPtr pvBuffer,uint unBufferSize,ref uint punWidth,ref uint punHeight) { punWidth = 0; @@ -2467,6 +2588,16 @@ public class CVROverlay EVROverlayError result = FnTable.GetOverlayTextureBounds(ulOverlayHandle,ref pOverlayTextureBounds); return result; } + public uint GetOverlayRenderModel(ulong ulOverlayHandle,string pchValue,uint unBufferSize,ref HmdColor_t pColor,ref EVROverlayError pError) + { + uint result = FnTable.GetOverlayRenderModel(ulOverlayHandle,pchValue,unBufferSize,ref pColor,ref pError); + return result; + } + public EVROverlayError SetOverlayRenderModel(ulong ulOverlayHandle,string pchRenderModel,ref HmdColor_t pColor) + { + EVROverlayError result = FnTable.SetOverlayRenderModel(ulOverlayHandle,pchRenderModel,ref pColor); + return result; + } public EVROverlayError GetOverlayTransformType(ulong ulOverlayHandle,ref VROverlayTransformType peTransformType) { EVROverlayError result = FnTable.GetOverlayTransformType(ulOverlayHandle,ref peTransformType); @@ -2504,6 +2635,17 @@ public class CVROverlay EVROverlayError result = FnTable.GetOverlayTransformTrackedDeviceComponent(ulOverlayHandle,ref punDeviceIndex,pchComponentName,unComponentNameSize); return result; } + public EVROverlayError GetOverlayTransformOverlayRelative(ulong ulOverlayHandle,ref ulong ulOverlayHandleParent,ref HmdMatrix34_t pmatParentOverlayToOverlayTransform) + { + ulOverlayHandleParent = 0; + EVROverlayError result = FnTable.GetOverlayTransformOverlayRelative(ulOverlayHandle,ref ulOverlayHandleParent,ref pmatParentOverlayToOverlayTransform); + return result; + } + public EVROverlayError SetOverlayTransformOverlayRelative(ulong ulOverlayHandle,ulong ulOverlayHandleParent,ref HmdMatrix34_t pmatParentOverlayToOverlayTransform) + { + EVROverlayError result = FnTable.SetOverlayTransformOverlayRelative(ulOverlayHandle,ulOverlayHandleParent,ref pmatParentOverlayToOverlayTransform); + return result; + } public EVROverlayError ShowOverlay(ulong ulOverlayHandle) { EVROverlayError result = FnTable.ShowOverlay(ulOverlayHandle); @@ -2524,8 +2666,32 @@ public class CVROverlay EVROverlayError result = FnTable.GetTransformForOverlayCoordinates(ulOverlayHandle,eTrackingOrigin,coordinatesInOverlay,ref pmatTransform); return result; } +// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were +// originally mis-compiled with the wrong packing for Linux and OSX. + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate bool _PollNextOverlayEventPacked(ulong ulOverlayHandle,ref VREvent_t_Packed pEvent,uint uncbVREvent); + [StructLayout(LayoutKind.Explicit)] + struct PollNextOverlayEventUnion + { + [FieldOffset(0)] + public IVROverlay._PollNextOverlayEvent pPollNextOverlayEvent; + [FieldOffset(0)] + public _PollNextOverlayEventPacked pPollNextOverlayEventPacked; + } public bool PollNextOverlayEvent(ulong ulOverlayHandle,ref VREvent_t pEvent,uint uncbVREvent) { + if ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) || + (System.Environment.OSVersion.Platform == System.PlatformID.Unix)) + { + PollNextOverlayEventUnion u; + VREvent_t_Packed event_packed = new VREvent_t_Packed(); + u.pPollNextOverlayEventPacked = null; + u.pPollNextOverlayEvent = FnTable.PollNextOverlayEvent; + bool packed_result = u.pPollNextOverlayEventPacked(ulOverlayHandle,ref event_packed,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VREvent_t_Packed))); + + event_packed.Unpack(ref pEvent); + return packed_result; + } bool result = FnTable.PollNextOverlayEvent(ulOverlayHandle,ref pEvent,uncbVREvent); return result; } @@ -2776,8 +2942,32 @@ public class CVRRenderModels uint result = FnTable.GetComponentRenderModelName(pchRenderModelName,pchComponentName,pchComponentRenderModelName,unComponentRenderModelNameLen); return result; } +// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were +// originally mis-compiled with the wrong packing for Linux and OSX. + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + internal delegate bool _GetComponentStatePacked(string pchRenderModelName,string pchComponentName,ref VRControllerState_t_Packed pControllerState,ref RenderModel_ControllerMode_State_t pState,ref RenderModel_ComponentState_t pComponentState); + [StructLayout(LayoutKind.Explicit)] + struct GetComponentStateUnion + { + [FieldOffset(0)] + public IVRRenderModels._GetComponentState pGetComponentState; + [FieldOffset(0)] + public _GetComponentStatePacked pGetComponentStatePacked; + } public bool GetComponentState(string pchRenderModelName,string pchComponentName,ref VRControllerState_t pControllerState,ref RenderModel_ControllerMode_State_t pState,ref RenderModel_ComponentState_t pComponentState) { + if ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) || + (System.Environment.OSVersion.Platform == System.PlatformID.Unix)) + { + GetComponentStateUnion u; + VRControllerState_t_Packed state_packed = new VRControllerState_t_Packed(pControllerState); + u.pGetComponentStatePacked = null; + u.pGetComponentState = FnTable.GetComponentState; + bool packed_result = u.pGetComponentStatePacked(pchRenderModelName,pchComponentName,ref state_packed,ref pState,ref pComponentState); + + state_packed.Unpack(ref pControllerState); + return packed_result; + } bool result = FnTable.GetComponentState(pchRenderModelName,pchComponentName,ref pControllerState,ref pState,ref pComponentState); return result; } @@ -2986,6 +3176,8 @@ public enum ETextureType DirectX = 0, OpenGL = 1, Vulkan = 2, + IOSurface = 3, + DirectX12 = 4, } public enum EColorSpace { @@ -3008,6 +3200,7 @@ public enum ETrackedDeviceClass Controller = 2, GenericTracker = 3, TrackingReference = 4, + DisplayRedirect = 5, } public enum ETrackedControllerRole { @@ -3058,6 +3251,8 @@ public enum ETrackedDeviceProperty Prop_DriverVersion_String = 1031, Prop_Firmware_ForceUpdateRequired_Bool = 1032, Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, Prop_ReportsTimeSinceVSync_Bool = 2000, Prop_SecondsFromVsyncToPhotons_Float = 2001, Prop_DisplayFrequency_Float = 2002, @@ -3096,6 +3291,11 @@ public enum ETrackedDeviceProperty Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, Prop_DisplaySuppressed_Bool = 2036, Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, Prop_AttachedDeviceId_String = 3000, Prop_SupportedButtons_Uint64 = 3001, Prop_Axis0Type_Int32 = 3002, @@ -3120,6 +3320,15 @@ public enum ETrackedDeviceProperty Prop_NamedIconPathDeviceNotReady_String = 5006, Prop_NamedIconPathDeviceStandby_String = 5007, Prop_NamedIconPathDeviceAlertLow_String = 5008, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, Prop_VendorSpecific_Reserved_Start = 10000, Prop_VendorSpecific_Reserved_End = 10999, } @@ -3136,6 +3345,7 @@ public enum ETrackedPropertyError TrackedProp_StringExceedsMaximumLength = 8, TrackedProp_NotYetAvailable = 9, TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, } public enum EVRSubmitFlags { @@ -3170,6 +3380,7 @@ public enum EVREventType VREvent_TrackedDeviceRoleChanged = 108, VREvent_WatchdogWakeUpRequested = 109, VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, VREvent_ButtonPress = 200, VREvent_ButtonUnpress = 201, VREvent_ButtonTouch = 202, @@ -3216,6 +3427,7 @@ public enum EVREventType VREvent_ScreenshotFailed = 522, VREvent_SubmitScreenshotToDashboard = 523, VREvent_ScreenshotProgressToDashboard = 524, + VREvent_PrimaryDashboardDeviceChanged = 525, VREvent_Notification_Shown = 600, VREvent_Notification_Hidden = 601, VREvent_Notification_BeginInteraction = 602, @@ -3249,6 +3461,9 @@ public enum EVREventType VREvent_ApplicationTransitionNewAppStarted = 1302, VREvent_ApplicationListUpdated = 1303, VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, VREvent_Compositor_MirrorWindowShown = 1400, VREvent_Compositor_MirrorWindowHidden = 1401, VREvent_Compositor_ChaperoneBoundsShown = 1410, @@ -3305,6 +3520,7 @@ public enum EHiddenAreaMeshType k_eHiddenAreaMesh_Standard = 0, k_eHiddenAreaMesh_Inverse = 1, k_eHiddenAreaMesh_LineLoop = 2, + k_eHiddenAreaMesh_Max = 3, } public enum EVRControllerAxisType { @@ -3360,7 +3576,8 @@ public enum EVRApplicationType VRApplication_Utility = 4, VRApplication_VRMonitor = 5, VRApplication_SteamWatchdog = 6, - VRApplication_Max = 7, + VRApplication_Bootstrapper = 7, + VRApplication_Max = 8, } public enum EVRFirmwareError { @@ -3536,6 +3753,7 @@ public enum EVRApplicationProperty IsDashboardOverlay_Bool = 60, IsTemplate_Bool = 61, IsInstanced_Bool = 62, + IsInternal_Bool = 63, LastLaunchTime_Uint64 = 70, } public enum EVRApplicationTransitionState @@ -3863,6 +4081,12 @@ public enum EVRScreenshotError public uint m_nFormat; public uint m_nSampleCount; } +[StructLayout(LayoutKind.Sequential)] public struct D3D12TextureData_t +{ + public IntPtr m_pResource; // struct ID3D12Resource * + public IntPtr m_pCommandQueue; // struct ID3D12CommandQueue * + public uint m_nNodeMask; +} [StructLayout(LayoutKind.Sequential)] public struct VREvent_Controller_t { public uint button; @@ -3960,6 +4184,11 @@ public enum EVRScreenshotError { public uint unVRMessageOverlayResponse; } +[StructLayout(LayoutKind.Sequential)] public struct VREvent_Property_t +{ + public ulong container; + public ETrackedDeviceProperty prop; +} [StructLayout(LayoutKind.Sequential)] public struct VREvent_t { public uint eventType; @@ -3967,6 +4196,28 @@ public enum EVRScreenshotError public float eventAgeSeconds; public VREvent_Data_t data; } +// This structure is for backwards binary compatibility on Linux and OSX only +[StructLayout(LayoutKind.Sequential, Pack = 4)] public struct VREvent_t_Packed +{ + public uint eventType; + public uint trackedDeviceIndex; + public float eventAgeSeconds; + public VREvent_Data_t data; + public VREvent_t_Packed(VREvent_t unpacked) + { + this.eventType = unpacked.eventType; + this.trackedDeviceIndex = unpacked.trackedDeviceIndex; + this.eventAgeSeconds = unpacked.eventAgeSeconds; + this.data = unpacked.data; + } + public void Unpack(ref VREvent_t unpacked) + { + unpacked.eventType = this.eventType; + unpacked.trackedDeviceIndex = this.trackedDeviceIndex; + unpacked.eventAgeSeconds = this.eventAgeSeconds; + unpacked.data = this.data; + } +} [StructLayout(LayoutKind.Sequential)] public struct HiddenAreaMesh_t { public IntPtr pVertexData; // const struct vr::HmdVector2_t * @@ -3988,6 +4239,40 @@ public enum EVRScreenshotError public VRControllerAxis_t rAxis3; public VRControllerAxis_t rAxis4; } +// This structure is for backwards binary compatibility on Linux and OSX only +[StructLayout(LayoutKind.Sequential, Pack = 4)] public struct VRControllerState_t_Packed +{ + public uint unPacketNum; + public ulong ulButtonPressed; + public ulong ulButtonTouched; + public VRControllerAxis_t rAxis0; //VRControllerAxis_t[5] + public VRControllerAxis_t rAxis1; + public VRControllerAxis_t rAxis2; + public VRControllerAxis_t rAxis3; + public VRControllerAxis_t rAxis4; + public VRControllerState_t_Packed(VRControllerState_t unpacked) + { + this.unPacketNum = unpacked.unPacketNum; + this.ulButtonPressed = unpacked.ulButtonPressed; + this.ulButtonTouched = unpacked.ulButtonTouched; + this.rAxis0 = unpacked.rAxis0; + this.rAxis1 = unpacked.rAxis1; + this.rAxis2 = unpacked.rAxis2; + this.rAxis3 = unpacked.rAxis3; + this.rAxis4 = unpacked.rAxis4; + } + public void Unpack(ref VRControllerState_t unpacked) + { + unpacked.unPacketNum = this.unPacketNum; + unpacked.ulButtonPressed = this.ulButtonPressed; + unpacked.ulButtonTouched = this.ulButtonTouched; + unpacked.rAxis0 = this.rAxis0; + unpacked.rAxis1 = this.rAxis1; + unpacked.rAxis2 = this.rAxis2; + unpacked.rAxis3 = this.rAxis3; + unpacked.rAxis4 = this.rAxis4; + } +} [StructLayout(LayoutKind.Sequential)] public struct Compositor_OverlaySettings { public uint size; @@ -4116,6 +4401,25 @@ public enum EVRScreenshotError public char unHeight; public IntPtr rubTextureMapData; // const uint8_t * } +// This structure is for backwards binary compatibility on Linux and OSX only +[StructLayout(LayoutKind.Sequential, Pack = 4)] public struct RenderModel_TextureMap_t_Packed +{ + public char unWidth; + public char unHeight; + public IntPtr rubTextureMapData; // const uint8_t * + public RenderModel_TextureMap_t_Packed(RenderModel_TextureMap_t unpacked) + { + this.unWidth = unpacked.unWidth; + this.unHeight = unpacked.unHeight; + this.rubTextureMapData = unpacked.rubTextureMapData; + } + public void Unpack(ref RenderModel_TextureMap_t unpacked) + { + unpacked.unWidth = this.unWidth; + unpacked.unHeight = this.unHeight; + unpacked.rubTextureMapData = this.rubTextureMapData; + } +} [StructLayout(LayoutKind.Sequential)] public struct RenderModel_t { public IntPtr rVertexData; // const struct vr::RenderModel_Vertex_t * @@ -4124,6 +4428,31 @@ public enum EVRScreenshotError public uint unTriangleCount; public int diffuseTextureId; } +// This structure is for backwards binary compatibility on Linux and OSX only +[StructLayout(LayoutKind.Sequential, Pack = 4)] public struct RenderModel_t_Packed +{ + public IntPtr rVertexData; // const struct vr::RenderModel_Vertex_t * + public uint unVertexCount; + public IntPtr rIndexData; // const uint16_t * + public uint unTriangleCount; + public int diffuseTextureId; + public RenderModel_t_Packed(RenderModel_t unpacked) + { + this.rVertexData = unpacked.rVertexData; + this.unVertexCount = unpacked.unVertexCount; + this.rIndexData = unpacked.rIndexData; + this.unTriangleCount = unpacked.unTriangleCount; + this.diffuseTextureId = unpacked.diffuseTextureId; + } + public void Unpack(ref RenderModel_t unpacked) + { + unpacked.rVertexData = this.rVertexData; + unpacked.unVertexCount = this.unVertexCount; + unpacked.rIndexData = this.rIndexData; + unpacked.unTriangleCount = this.unTriangleCount; + unpacked.diffuseTextureId = this.diffuseTextureId; + } +} [StructLayout(LayoutKind.Sequential)] public struct RenderModel_ControllerMode_State_t { [MarshalAs(UnmanagedType.I1)] @@ -4200,6 +4529,20 @@ public class OpenVR public const uint k_unMaxTrackedDeviceCount = 16; public const uint k_unTrackedDeviceIndexOther = 4294967294; public const uint k_unTrackedDeviceIndexInvalid = 4294967295; + public const ulong k_ulInvalidPropertyContainer = 0; + public const uint k_unInvalidPropertyTag = 0; + public const uint k_unFloatPropertyTag = 1; + public const uint k_unInt32PropertyTag = 2; + public const uint k_unUint64PropertyTag = 3; + public const uint k_unBoolPropertyTag = 4; + public const uint k_unStringPropertyTag = 5; + public const uint k_unHmdMatrix34PropertyTag = 20; + public const uint k_unHmdMatrix44PropertyTag = 21; + public const uint k_unHmdVector3PropertyTag = 22; + public const uint k_unHmdVector4PropertyTag = 23; + public const uint k_unHiddenAreaPropertyTag = 30; + public const uint k_unOpenVRInternalReserved_Start = 1000; + public const uint k_unOpenVRInternalReserved_End = 10000; public const uint k_unMaxPropertyStringSize = 32768; public const uint k_unControllerStateAxisCount = 5; public const ulong k_ulOverlayHandleInvalid = 0; @@ -4213,12 +4556,12 @@ public class OpenVR public const string IVRApplications_Version = "IVRApplications_006"; public const string IVRChaperone_Version = "IVRChaperone_003"; public const string IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; - public const string IVRCompositor_Version = "IVRCompositor_019"; + public const string IVRCompositor_Version = "IVRCompositor_020"; public const uint k_unVROverlayMaxKeyLength = 128; public const uint k_unVROverlayMaxNameLength = 128; public const uint k_unMaxOverlayCount = 64; public const uint k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; - public const string IVROverlay_Version = "IVROverlay_014"; + public const string IVROverlay_Version = "IVROverlay_016"; public const string k_pch_Controller_Component_GDC2015 = "gdc2015"; public const string k_pch_Controller_Component_Base = "base"; public const string k_pch_Controller_Component_Tip = "tip"; @@ -4235,7 +4578,6 @@ public class OpenVR public const string k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; public const string k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; public const string k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - public const string k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion"; public const string k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; public const string k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; public const string k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; @@ -4280,7 +4622,6 @@ public class OpenVR public const string k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; public const string k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; public const string k_pch_Null_Section = "driver_null"; - public const string k_pch_Null_EnableNullDriver_Bool = "enable"; public const string k_pch_Null_SerialNumber_String = "serialNumber"; public const string k_pch_Null_ModelNumber_String = "modelNumber"; public const string k_pch_Null_WindowX_Int32 = "windowX"; @@ -4350,6 +4691,7 @@ public class OpenVR public const string k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; public const string k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; public const string k_pch_modelskin_Section = "modelskins"; + public const string k_pch_Driver_Enable_Bool = "enable"; public const string IVRScreenshots_Version = "IVRScreenshots_001"; public const string IVRResources_Version = "IVRResources_001"; diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_api.json b/examples/ThirdPartyLibs/openvr/headers/openvr_api.json index 24509ee00..43c3bf958 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_api.json +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_api.json @@ -3,6 +3,8 @@ ,{"typedef": "vr::glUInt_t","type": "uint32_t"} ,{"typedef": "vr::SharedTextureHandle_t","type": "uint64_t"} ,{"typedef": "vr::TrackedDeviceIndex_t","type": "uint32_t"} +,{"typedef": "vr::PropertyContainerHandle_t","type": "uint64_t"} +,{"typedef": "vr::PropertyTypeTag_t","type": "uint32_t"} ,{"typedef": "vr::VREvent_Data_t","type": "union VREvent_Data_t"} ,{"typedef": "vr::VRControllerState_t","type": "struct vr::VRControllerState001_t"} ,{"typedef": "vr::VROverlayHandle_t","type": "uint64_t"} @@ -37,6 +39,8 @@ {"name": "TextureType_DirectX","value": "0"} ,{"name": "TextureType_OpenGL","value": "1"} ,{"name": "TextureType_Vulkan","value": "2"} + ,{"name": "TextureType_IOSurface","value": "3"} + ,{"name": "TextureType_DirectX12","value": "4"} ]} , {"enumname": "vr::EColorSpace","values": [ {"name": "ColorSpace_Auto","value": "0"} @@ -56,6 +60,7 @@ ,{"name": "TrackedDeviceClass_Controller","value": "2"} ,{"name": "TrackedDeviceClass_GenericTracker","value": "3"} ,{"name": "TrackedDeviceClass_TrackingReference","value": "4"} + ,{"name": "TrackedDeviceClass_DisplayRedirect","value": "5"} ]} , {"enumname": "vr::ETrackedControllerRole","values": [ {"name": "TrackedControllerRole_Invalid","value": "0"} @@ -103,6 +108,8 @@ ,{"name": "Prop_DriverVersion_String","value": "1031"} ,{"name": "Prop_Firmware_ForceUpdateRequired_Bool","value": "1032"} ,{"name": "Prop_ViveSystemButtonFixRequired_Bool","value": "1033"} + ,{"name": "Prop_ParentDriver_Uint64","value": "1034"} + ,{"name": "Prop_ResourceRoot_String","value": "1035"} ,{"name": "Prop_ReportsTimeSinceVSync_Bool","value": "2000"} ,{"name": "Prop_SecondsFromVsyncToPhotons_Float","value": "2001"} ,{"name": "Prop_DisplayFrequency_Float","value": "2002"} @@ -141,6 +148,11 @@ ,{"name": "Prop_ScreenshotVerticalFieldOfViewDegrees_Float","value": "2035"} ,{"name": "Prop_DisplaySuppressed_Bool","value": "2036"} ,{"name": "Prop_DisplayAllowNightMode_Bool","value": "2037"} + ,{"name": "Prop_DisplayMCImageWidth_Int32","value": "2038"} + ,{"name": "Prop_DisplayMCImageHeight_Int32","value": "2039"} + ,{"name": "Prop_DisplayMCImageNumChannels_Int32","value": "2040"} + ,{"name": "Prop_DisplayMCImageData_Binary","value": "2041"} + ,{"name": "Prop_SecondsFromPhotonsToVblank_Float","value": "2042"} ,{"name": "Prop_AttachedDeviceId_String","value": "3000"} ,{"name": "Prop_SupportedButtons_Uint64","value": "3001"} ,{"name": "Prop_Axis0Type_Int32","value": "3002"} @@ -165,6 +177,15 @@ ,{"name": "Prop_NamedIconPathDeviceNotReady_String","value": "5006"} ,{"name": "Prop_NamedIconPathDeviceStandby_String","value": "5007"} ,{"name": "Prop_NamedIconPathDeviceAlertLow_String","value": "5008"} + ,{"name": "Prop_DisplayHiddenArea_Binary_Start","value": "5100"} + ,{"name": "Prop_DisplayHiddenArea_Binary_End","value": "5150"} + ,{"name": "Prop_UserConfigPath_String","value": "6000"} + ,{"name": "Prop_InstallPath_String","value": "6001"} + ,{"name": "Prop_HasDisplayComponent_Bool","value": "6002"} + ,{"name": "Prop_HasControllerComponent_Bool","value": "6003"} + ,{"name": "Prop_HasCameraComponent_Bool","value": "6004"} + ,{"name": "Prop_HasDriverDirectModeComponent_Bool","value": "6005"} + ,{"name": "Prop_HasVirtualDisplayComponent_Bool","value": "6006"} ,{"name": "Prop_VendorSpecific_Reserved_Start","value": "10000"} ,{"name": "Prop_VendorSpecific_Reserved_End","value": "10999"} ]} @@ -180,6 +201,7 @@ ,{"name": "TrackedProp_StringExceedsMaximumLength","value": "8"} ,{"name": "TrackedProp_NotYetAvailable","value": "9"} ,{"name": "TrackedProp_PermissionDenied","value": "10"} + ,{"name": "TrackedProp_InvalidOperation","value": "11"} ]} , {"enumname": "vr::EVRSubmitFlags","values": [ {"name": "Submit_Default","value": "0"} @@ -211,6 +233,7 @@ ,{"name": "VREvent_TrackedDeviceRoleChanged","value": "108"} ,{"name": "VREvent_WatchdogWakeUpRequested","value": "109"} ,{"name": "VREvent_LensDistortionChanged","value": "110"} + ,{"name": "VREvent_PropertyChanged","value": "111"} ,{"name": "VREvent_ButtonPress","value": "200"} ,{"name": "VREvent_ButtonUnpress","value": "201"} ,{"name": "VREvent_ButtonTouch","value": "202"} @@ -257,6 +280,7 @@ ,{"name": "VREvent_ScreenshotFailed","value": "522"} ,{"name": "VREvent_SubmitScreenshotToDashboard","value": "523"} ,{"name": "VREvent_ScreenshotProgressToDashboard","value": "524"} + ,{"name": "VREvent_PrimaryDashboardDeviceChanged","value": "525"} ,{"name": "VREvent_Notification_Shown","value": "600"} ,{"name": "VREvent_Notification_Hidden","value": "601"} ,{"name": "VREvent_Notification_BeginInteraction","value": "602"} @@ -290,6 +314,9 @@ ,{"name": "VREvent_ApplicationTransitionNewAppStarted","value": "1302"} ,{"name": "VREvent_ApplicationListUpdated","value": "1303"} ,{"name": "VREvent_ApplicationMimeTypeLoad","value": "1304"} + ,{"name": "VREvent_ApplicationTransitionNewAppLaunchComplete","value": "1305"} + ,{"name": "VREvent_ProcessConnected","value": "1306"} + ,{"name": "VREvent_ProcessDisconnected","value": "1307"} ,{"name": "VREvent_Compositor_MirrorWindowShown","value": "1400"} ,{"name": "VREvent_Compositor_MirrorWindowHidden","value": "1401"} ,{"name": "VREvent_Compositor_ChaperoneBoundsShown","value": "1410"} @@ -342,6 +369,7 @@ {"name": "k_eHiddenAreaMesh_Standard","value": "0"} ,{"name": "k_eHiddenAreaMesh_Inverse","value": "1"} ,{"name": "k_eHiddenAreaMesh_LineLoop","value": "2"} + ,{"name": "k_eHiddenAreaMesh_Max","value": "3"} ]} , {"enumname": "vr::EVRControllerAxisType","values": [ {"name": "k_eControllerAxis_None","value": "0"} @@ -392,7 +420,8 @@ ,{"name": "VRApplication_Utility","value": "4"} ,{"name": "VRApplication_VRMonitor","value": "5"} ,{"name": "VRApplication_SteamWatchdog","value": "6"} - ,{"name": "VRApplication_Max","value": "7"} + ,{"name": "VRApplication_Bootstrapper","value": "7"} + ,{"name": "VRApplication_Max","value": "8"} ]} , {"enumname": "vr::EVRFirmwareError","values": [ {"name": "VRFirmwareError_None","value": "0"} @@ -559,6 +588,7 @@ ,{"name": "VRApplicationProperty_IsDashboardOverlay_Bool","value": "60"} ,{"name": "VRApplicationProperty_IsTemplate_Bool","value": "61"} ,{"name": "VRApplicationProperty_IsInstanced_Bool","value": "62"} + ,{"name": "VRApplicationProperty_IsInternal_Bool","value": "63"} ,{"name": "VRApplicationProperty_LastLaunchTime_Uint64","value": "70"} ]} , {"enumname": "vr::EVRApplicationTransitionState","values": [ @@ -717,6 +747,34 @@ "constname": "k_unTrackedDeviceIndexOther","consttype": "const uint32_t", "constval": "4294967294"} ,{ "constname": "k_unTrackedDeviceIndexInvalid","consttype": "const uint32_t", "constval": "4294967295"} +,{ + "constname": "k_ulInvalidPropertyContainer","consttype": "const PropertyContainerHandle_t", "constval": "0"} +,{ + "constname": "k_unInvalidPropertyTag","consttype": "const PropertyTypeTag_t", "constval": "0"} +,{ + "constname": "k_unFloatPropertyTag","consttype": "const PropertyTypeTag_t", "constval": "1"} +,{ + "constname": "k_unInt32PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "2"} +,{ + "constname": "k_unUint64PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "3"} +,{ + "constname": "k_unBoolPropertyTag","consttype": "const PropertyTypeTag_t", "constval": "4"} +,{ + "constname": "k_unStringPropertyTag","consttype": "const PropertyTypeTag_t", "constval": "5"} +,{ + "constname": "k_unHmdMatrix34PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "20"} +,{ + "constname": "k_unHmdMatrix44PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "21"} +,{ + "constname": "k_unHmdVector3PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "22"} +,{ + "constname": "k_unHmdVector4PropertyTag","consttype": "const PropertyTypeTag_t", "constval": "23"} +,{ + "constname": "k_unHiddenAreaPropertyTag","consttype": "const PropertyTypeTag_t", "constval": "30"} +,{ + "constname": "k_unOpenVRInternalReserved_Start","consttype": "const PropertyTypeTag_t", "constval": "1000"} +,{ + "constname": "k_unOpenVRInternalReserved_End","consttype": "const PropertyTypeTag_t", "constval": "10000"} ,{ "constname": "k_unMaxPropertyStringSize","consttype": "const uint32_t", "constval": "32768"} ,{ @@ -744,7 +802,7 @@ ,{ "constname": "IVRChaperoneSetup_Version","consttype": "const char *const", "constval": "IVRChaperoneSetup_005"} ,{ - "constname": "IVRCompositor_Version","consttype": "const char *const", "constval": "IVRCompositor_019"} + "constname": "IVRCompositor_Version","consttype": "const char *const", "constval": "IVRCompositor_020"} ,{ "constname": "k_unVROverlayMaxKeyLength","consttype": "const uint32_t", "constval": "128"} ,{ @@ -754,7 +812,7 @@ ,{ "constname": "k_unMaxOverlayIntersectionMaskPrimitivesCount","consttype": "const uint32_t", "constval": "32"} ,{ - "constname": "IVROverlay_Version","consttype": "const char *const", "constval": "IVROverlay_014"} + "constname": "IVROverlay_Version","consttype": "const char *const", "constval": "IVROverlay_016"} ,{ "constname": "k_pch_Controller_Component_GDC2015","consttype": "const char *const", "constval": "gdc2015"} ,{ @@ -787,8 +845,6 @@ "constname": "k_pch_SteamVR_DisplayDebug_Bool","consttype": "const char *const", "constval": "displayDebug"} ,{ "constname": "k_pch_SteamVR_DebugProcessPipe_String","consttype": "const char *const", "constval": "debugProcessPipe"} -,{ - "constname": "k_pch_SteamVR_EnableDistortion_Bool","consttype": "const char *const", "constval": "enableDistortion"} ,{ "constname": "k_pch_SteamVR_DisplayDebugX_Int32","consttype": "const char *const", "constval": "displayDebugX"} ,{ @@ -877,8 +933,6 @@ "constname": "k_pch_Lighthouse_DBHistory_Bool","consttype": "const char *const", "constval": "dbhistory"} ,{ "constname": "k_pch_Null_Section","consttype": "const char *const", "constval": "driver_null"} -,{ - "constname": "k_pch_Null_EnableNullDriver_Bool","consttype": "const char *const", "constval": "enable"} ,{ "constname": "k_pch_Null_SerialNumber_String","consttype": "const char *const", "constval": "serialNumber"} ,{ @@ -1017,6 +1071,8 @@ "constname": "k_pch_Dashboard_ArcadeMode_Bool","consttype": "const char *const", "constval": "arcadeMode"} ,{ "constname": "k_pch_modelskin_Section","consttype": "const char *const", "constval": "modelskins"} +,{ + "constname": "k_pch_Driver_Enable_Bool","consttype": "const char *const", "constval": "enable"} ,{ "constname": "IVRScreenshots_Version","consttype": "const char *const", "constval": "IVRScreenshots_001"} ,{ @@ -1080,6 +1136,10 @@ { "fieldname": "m_nHeight", "fieldtype": "uint32_t"}, { "fieldname": "m_nFormat", "fieldtype": "uint32_t"}, { "fieldname": "m_nSampleCount", "fieldtype": "uint32_t"}]} +,{"struct": "vr::D3D12TextureData_t","fields": [ +{ "fieldname": "m_pResource", "fieldtype": "struct ID3D12Resource *"}, +{ "fieldname": "m_pCommandQueue", "fieldtype": "struct ID3D12CommandQueue *"}, +{ "fieldname": "m_nNodeMask", "fieldtype": "uint32_t"}]} ,{"struct": "vr::VREvent_Controller_t","fields": [ { "fieldname": "button", "fieldtype": "uint32_t"}]} ,{"struct": "vr::VREvent_Mouse_t","fields": [ @@ -1136,6 +1196,9 @@ { "fieldname": "nVisualMode", "fieldtype": "uint32_t"}]} ,{"struct": "vr::VREvent_MessageOverlay_t","fields": [ { "fieldname": "unVRMessageOverlayResponse", "fieldtype": "uint32_t"}]} +,{"struct": "vr::VREvent_Property_t","fields": [ +{ "fieldname": "container", "fieldtype": "PropertyContainerHandle_t"}, +{ "fieldname": "prop", "fieldtype": "enum vr::ETrackedDeviceProperty"}]} ,{"struct": "vr::(anonymous)","fields": [ { "fieldname": "reserved", "fieldtype": "struct vr::VREvent_Reserved_t"}, { "fieldname": "controller", "fieldtype": "struct vr::VREvent_Controller_t"}, @@ -1155,7 +1218,8 @@ { "fieldname": "screenshotProgress", "fieldtype": "struct vr::VREvent_ScreenshotProgress_t"}, { "fieldname": "applicationLaunch", "fieldtype": "struct vr::VREvent_ApplicationLaunch_t"}, { "fieldname": "cameraSurface", "fieldtype": "struct vr::VREvent_EditingCameraSurface_t"}, -{ "fieldname": "messageOverlay", "fieldtype": "struct vr::VREvent_MessageOverlay_t"}]} +{ "fieldname": "messageOverlay", "fieldtype": "struct vr::VREvent_MessageOverlay_t"}, +{ "fieldname": "property", "fieldtype": "struct vr::VREvent_Property_t"}]} ,{"struct": "vr::VREvent_t","fields": [ { "fieldname": "eventType", "fieldtype": "uint32_t"}, { "fieldname": "trackedDeviceIndex", "fieldtype": "TrackedDeviceIndex_t"}, @@ -2094,6 +2158,11 @@ { "paramname": "pchWorkingDirectory" ,"paramtype": "const char *"} ] } +,{ + "classname": "vr::IVRApplications", + "methodname": "GetCurrentSceneProcessId", + "returntype": "uint32_t" +} ,{ "classname": "vr::IVRChaperone", "methodname": "GetCalibrationState", @@ -2559,6 +2628,14 @@ { "paramname": "ppD3D11ShaderResourceView" ,"paramtype": "void **"} ] } +,{ + "classname": "vr::IVRCompositor", + "methodname": "ReleaseMirrorTextureD3D11", + "returntype": "void", + "params": [ +{ "paramname": "pD3D11ShaderResourceView" ,"paramtype": "void *"} + ] +} ,{ "classname": "vr::IVRCompositor", "methodname": "GetMirrorTextureGL", @@ -2628,7 +2705,7 @@ "returntype": "vr::EVROverlayError", "params": [ { "paramname": "pchOverlayKey" ,"paramtype": "const char *"}, -{ "paramname": "pchOverlayFriendlyName" ,"paramtype": "const char *"}, +{ "paramname": "pchOverlayName" ,"paramtype": "const char *"}, { "paramname": "pOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t *"} ] } @@ -2675,6 +2752,15 @@ { "paramname": "pError" ,"paramtype": "vr::EVROverlayError *"} ] } +,{ + "classname": "vr::IVROverlay", + "methodname": "SetOverlayName", + "returntype": "vr::EVROverlayError", + "params": [ +{ "paramname": "ulOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "pchName" ,"paramtype": "const char *"} + ] +} ,{ "classname": "vr::IVROverlay", "methodname": "GetOverlayImageData", @@ -2882,6 +2968,28 @@ { "paramname": "pOverlayTextureBounds" ,"paramtype": "struct vr::VRTextureBounds_t *"} ] } +,{ + "classname": "vr::IVROverlay", + "methodname": "GetOverlayRenderModel", + "returntype": "uint32_t", + "params": [ +{ "paramname": "ulOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "pchValue" ,"paramtype": "char *"}, +{ "paramname": "unBufferSize" ,"paramtype": "uint32_t"}, +{ "paramname": "pColor" ,"paramtype": "struct vr::HmdColor_t *"}, +{ "paramname": "pError" ,"paramtype": "vr::EVROverlayError *"} + ] +} +,{ + "classname": "vr::IVROverlay", + "methodname": "SetOverlayRenderModel", + "returntype": "vr::EVROverlayError", + "params": [ +{ "paramname": "ulOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "pchRenderModel" ,"paramtype": "const char *"}, +{ "paramname": "pColor" ,"paramtype": "const struct vr::HmdColor_t *"} + ] +} ,{ "classname": "vr::IVROverlay", "methodname": "GetOverlayTransformType", @@ -2952,6 +3060,26 @@ { "paramname": "unComponentNameSize" ,"paramtype": "uint32_t"} ] } +,{ + "classname": "vr::IVROverlay", + "methodname": "GetOverlayTransformOverlayRelative", + "returntype": "vr::EVROverlayError", + "params": [ +{ "paramname": "ulOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "ulOverlayHandleParent" ,"paramtype": "vr::VROverlayHandle_t *"}, +{ "paramname": "pmatParentOverlayToOverlayTransform" ,"paramtype": "struct vr::HmdMatrix34_t *"} + ] +} +,{ + "classname": "vr::IVROverlay", + "methodname": "SetOverlayTransformOverlayRelative", + "returntype": "vr::EVROverlayError", + "params": [ +{ "paramname": "ulOverlayHandle" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "ulOverlayHandleParent" ,"paramtype": "vr::VROverlayHandle_t"}, +{ "paramname": "pmatParentOverlayToOverlayTransform" ,"paramtype": "const struct vr::HmdMatrix34_t *"} + ] +} ,{ "classname": "vr::IVROverlay", "methodname": "ShowOverlay", diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h b/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h index daffdfb22..f89566817 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h @@ -17,7 +17,11 @@ #define EXTERN_C #endif +#if defined( _WIN32 ) #define OPENVR_FNTABLE_CALLTYPE __stdcall +#else +#define OPENVR_FNTABLE_CALLTYPE +#endif // OPENVR API export macro #if defined( _WIN32 ) && !defined( _X360 ) @@ -50,6 +54,9 @@ typedef char bool; #include #endif +typedef uint64_t PropertyContainerHandle_t; +typedef uint32_t PropertyTypeTag_t; + // OpenVR Constants @@ -58,6 +65,20 @@ static const unsigned int k_unTrackedDeviceIndex_Hmd = 0; static const unsigned int k_unMaxTrackedDeviceCount = 16; static const unsigned int k_unTrackedDeviceIndexOther = 4294967294; static const unsigned int k_unTrackedDeviceIndexInvalid = 4294967295; +static const unsigned long k_ulInvalidPropertyContainer = 0; +static const unsigned int k_unInvalidPropertyTag = 0; +static const unsigned int k_unFloatPropertyTag = 1; +static const unsigned int k_unInt32PropertyTag = 2; +static const unsigned int k_unUint64PropertyTag = 3; +static const unsigned int k_unBoolPropertyTag = 4; +static const unsigned int k_unStringPropertyTag = 5; +static const unsigned int k_unHmdMatrix34PropertyTag = 20; +static const unsigned int k_unHmdMatrix44PropertyTag = 21; +static const unsigned int k_unHmdVector3PropertyTag = 22; +static const unsigned int k_unHmdVector4PropertyTag = 23; +static const unsigned int k_unHiddenAreaPropertyTag = 30; +static const unsigned int k_unOpenVRInternalReserved_Start = 1000; +static const unsigned int k_unOpenVRInternalReserved_End = 10000; static const unsigned int k_unMaxPropertyStringSize = 32768; static const unsigned int k_unControllerStateAxisCount = 5; static const unsigned long k_ulOverlayHandleInvalid = 0; @@ -71,12 +92,12 @@ static const char * k_pch_MimeType_GameTheater = "vr/game_theater"; static const char * IVRApplications_Version = "IVRApplications_006"; static const char * IVRChaperone_Version = "IVRChaperone_003"; static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; -static const char * IVRCompositor_Version = "IVRCompositor_019"; +static const char * IVRCompositor_Version = "IVRCompositor_020"; static const unsigned int k_unVROverlayMaxKeyLength = 128; static const unsigned int k_unVROverlayMaxNameLength = 128; static const unsigned int k_unMaxOverlayCount = 64; static const unsigned int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; -static const char * IVROverlay_Version = "IVROverlay_014"; +static const char * IVROverlay_Version = "IVROverlay_016"; static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; static const char * k_pch_Controller_Component_Base = "base"; static const char * k_pch_Controller_Component_Tip = "tip"; @@ -93,7 +114,6 @@ static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; -static const char * k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion"; static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; @@ -138,7 +158,6 @@ static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguation static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; static const char * k_pch_Null_Section = "driver_null"; -static const char * k_pch_Null_EnableNullDriver_Bool = "enable"; static const char * k_pch_Null_SerialNumber_String = "serialNumber"; static const char * k_pch_Null_ModelNumber_String = "modelNumber"; static const char * k_pch_Null_WindowX_Int32 = "windowX"; @@ -208,6 +227,7 @@ static const char * k_pch_Dashboard_Section = "dashboard"; static const char * k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; static const char * k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; static const char * k_pch_modelskin_Section = "modelskins"; +static const char * k_pch_Driver_Enable_Bool = "enable"; static const char * IVRScreenshots_Version = "IVRScreenshots_001"; static const char * IVRResources_Version = "IVRResources_001"; @@ -224,6 +244,8 @@ typedef enum ETextureType ETextureType_TextureType_DirectX = 0, ETextureType_TextureType_OpenGL = 1, ETextureType_TextureType_Vulkan = 2, + ETextureType_TextureType_IOSurface = 3, + ETextureType_TextureType_DirectX12 = 4, } ETextureType; typedef enum EColorSpace @@ -249,6 +271,7 @@ typedef enum ETrackedDeviceClass ETrackedDeviceClass_TrackedDeviceClass_Controller = 2, ETrackedDeviceClass_TrackedDeviceClass_GenericTracker = 3, ETrackedDeviceClass_TrackedDeviceClass_TrackingReference = 4, + ETrackedDeviceClass_TrackedDeviceClass_DisplayRedirect = 5, } ETrackedDeviceClass; typedef enum ETrackedControllerRole @@ -302,6 +325,8 @@ typedef enum ETrackedDeviceProperty ETrackedDeviceProperty_Prop_DriverVersion_String = 1031, ETrackedDeviceProperty_Prop_Firmware_ForceUpdateRequired_Bool = 1032, ETrackedDeviceProperty_Prop_ViveSystemButtonFixRequired_Bool = 1033, + ETrackedDeviceProperty_Prop_ParentDriver_Uint64 = 1034, + ETrackedDeviceProperty_Prop_ResourceRoot_String = 1035, ETrackedDeviceProperty_Prop_ReportsTimeSinceVSync_Bool = 2000, ETrackedDeviceProperty_Prop_SecondsFromVsyncToPhotons_Float = 2001, ETrackedDeviceProperty_Prop_DisplayFrequency_Float = 2002, @@ -340,6 +365,11 @@ typedef enum ETrackedDeviceProperty ETrackedDeviceProperty_Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, ETrackedDeviceProperty_Prop_DisplaySuppressed_Bool = 2036, ETrackedDeviceProperty_Prop_DisplayAllowNightMode_Bool = 2037, + ETrackedDeviceProperty_Prop_DisplayMCImageWidth_Int32 = 2038, + ETrackedDeviceProperty_Prop_DisplayMCImageHeight_Int32 = 2039, + ETrackedDeviceProperty_Prop_DisplayMCImageNumChannels_Int32 = 2040, + ETrackedDeviceProperty_Prop_DisplayMCImageData_Binary = 2041, + ETrackedDeviceProperty_Prop_SecondsFromPhotonsToVblank_Float = 2042, ETrackedDeviceProperty_Prop_AttachedDeviceId_String = 3000, ETrackedDeviceProperty_Prop_SupportedButtons_Uint64 = 3001, ETrackedDeviceProperty_Prop_Axis0Type_Int32 = 3002, @@ -364,6 +394,15 @@ typedef enum ETrackedDeviceProperty ETrackedDeviceProperty_Prop_NamedIconPathDeviceNotReady_String = 5006, ETrackedDeviceProperty_Prop_NamedIconPathDeviceStandby_String = 5007, ETrackedDeviceProperty_Prop_NamedIconPathDeviceAlertLow_String = 5008, + ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_Start = 5100, + ETrackedDeviceProperty_Prop_DisplayHiddenArea_Binary_End = 5150, + ETrackedDeviceProperty_Prop_UserConfigPath_String = 6000, + ETrackedDeviceProperty_Prop_InstallPath_String = 6001, + ETrackedDeviceProperty_Prop_HasDisplayComponent_Bool = 6002, + ETrackedDeviceProperty_Prop_HasControllerComponent_Bool = 6003, + ETrackedDeviceProperty_Prop_HasCameraComponent_Bool = 6004, + ETrackedDeviceProperty_Prop_HasDriverDirectModeComponent_Bool = 6005, + ETrackedDeviceProperty_Prop_HasVirtualDisplayComponent_Bool = 6006, ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_Start = 10000, ETrackedDeviceProperty_Prop_VendorSpecific_Reserved_End = 10999, } ETrackedDeviceProperty; @@ -381,6 +420,7 @@ typedef enum ETrackedPropertyError ETrackedPropertyError_TrackedProp_StringExceedsMaximumLength = 8, ETrackedPropertyError_TrackedProp_NotYetAvailable = 9, ETrackedPropertyError_TrackedProp_PermissionDenied = 10, + ETrackedPropertyError_TrackedProp_InvalidOperation = 11, } ETrackedPropertyError; typedef enum EVRSubmitFlags @@ -418,6 +458,7 @@ typedef enum EVREventType EVREventType_VREvent_TrackedDeviceRoleChanged = 108, EVREventType_VREvent_WatchdogWakeUpRequested = 109, EVREventType_VREvent_LensDistortionChanged = 110, + EVREventType_VREvent_PropertyChanged = 111, EVREventType_VREvent_ButtonPress = 200, EVREventType_VREvent_ButtonUnpress = 201, EVREventType_VREvent_ButtonTouch = 202, @@ -464,6 +505,7 @@ typedef enum EVREventType EVREventType_VREvent_ScreenshotFailed = 522, EVREventType_VREvent_SubmitScreenshotToDashboard = 523, EVREventType_VREvent_ScreenshotProgressToDashboard = 524, + EVREventType_VREvent_PrimaryDashboardDeviceChanged = 525, EVREventType_VREvent_Notification_Shown = 600, EVREventType_VREvent_Notification_Hidden = 601, EVREventType_VREvent_Notification_BeginInteraction = 602, @@ -497,6 +539,9 @@ typedef enum EVREventType EVREventType_VREvent_ApplicationTransitionNewAppStarted = 1302, EVREventType_VREvent_ApplicationListUpdated = 1303, EVREventType_VREvent_ApplicationMimeTypeLoad = 1304, + EVREventType_VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, + EVREventType_VREvent_ProcessConnected = 1306, + EVREventType_VREvent_ProcessDisconnected = 1307, EVREventType_VREvent_Compositor_MirrorWindowShown = 1400, EVREventType_VREvent_Compositor_MirrorWindowHidden = 1401, EVREventType_VREvent_Compositor_ChaperoneBoundsShown = 1410, @@ -557,6 +602,7 @@ typedef enum EHiddenAreaMeshType EHiddenAreaMeshType_k_eHiddenAreaMesh_Standard = 0, EHiddenAreaMeshType_k_eHiddenAreaMesh_Inverse = 1, EHiddenAreaMeshType_k_eHiddenAreaMesh_LineLoop = 2, + EHiddenAreaMeshType_k_eHiddenAreaMesh_Max = 3, } EHiddenAreaMeshType; typedef enum EVRControllerAxisType @@ -617,7 +663,8 @@ typedef enum EVRApplicationType EVRApplicationType_VRApplication_Utility = 4, EVRApplicationType_VRApplication_VRMonitor = 5, EVRApplicationType_VRApplication_SteamWatchdog = 6, - EVRApplicationType_VRApplication_Max = 7, + EVRApplicationType_VRApplication_Bootstrapper = 7, + EVRApplicationType_VRApplication_Max = 8, } EVRApplicationType; typedef enum EVRFirmwareError @@ -802,6 +849,7 @@ typedef enum EVRApplicationProperty EVRApplicationProperty_VRApplicationProperty_IsDashboardOverlay_Bool = 60, EVRApplicationProperty_VRApplicationProperty_IsTemplate_Bool = 61, EVRApplicationProperty_VRApplicationProperty_IsInstanced_Bool = 62, + EVRApplicationProperty_VRApplicationProperty_IsInternal_Bool = 63, EVRApplicationProperty_VRApplicationProperty_LastLaunchTime_Uint64 = 70, } EVRApplicationProperty; @@ -994,11 +1042,14 @@ typedef enum EVRScreenshotError typedef uint32_t TrackedDeviceIndex_t; typedef uint32_t VRNotificationId; typedef uint64_t VROverlayHandle_t; + typedef void * glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; typedef uint64_t SharedTextureHandle_t; typedef uint32_t TrackedDeviceIndex_t; +typedef uint64_t PropertyContainerHandle_t; +typedef uint32_t PropertyTypeTag_t; typedef uint64_t VROverlayHandle_t; typedef uint64_t TrackedCameraHandle_t; typedef uint32_t ScreenshotHandle_t; @@ -1126,6 +1177,13 @@ typedef struct VRVulkanTextureData_t uint32_t m_nSampleCount; } VRVulkanTextureData_t; +typedef struct D3D12TextureData_t +{ + struct ID3D12Resource * m_pResource; // struct ID3D12Resource * + struct ID3D12CommandQueue * m_pCommandQueue; // struct ID3D12CommandQueue * + uint32_t m_nNodeMask; +} D3D12TextureData_t; + typedef struct VREvent_Controller_t { uint32_t button; @@ -1239,6 +1297,12 @@ typedef struct VREvent_MessageOverlay_t uint32_t unVRMessageOverlayResponse; } VREvent_MessageOverlay_t; +typedef struct VREvent_Property_t +{ + PropertyContainerHandle_t container; + enum ETrackedDeviceProperty prop; +} VREvent_Property_t; + typedef struct HiddenAreaMesh_t { struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * @@ -1384,6 +1448,9 @@ typedef struct RenderModel_Vertex_t float rfTextureCoord[2]; //float[2] } RenderModel_Vertex_t; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( push, 4 ) +#endif typedef struct RenderModel_TextureMap_t { uint16_t unWidth; @@ -1391,6 +1458,12 @@ typedef struct RenderModel_TextureMap_t uint8_t * rubTextureMapData; // const uint8_t * } RenderModel_TextureMap_t; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( push, 4 ) +#endif typedef struct RenderModel_t { struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * @@ -1400,6 +1473,9 @@ typedef struct RenderModel_t TextureID_t diffuseTextureId; } RenderModel_t; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif typedef struct RenderModel_ControllerMode_State_t { bool bScrollWheelVisible; @@ -1577,6 +1653,7 @@ struct VR_IVRApplications_FnTable char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); }; struct VR_IVRChaperone_FnTable @@ -1651,6 +1728,7 @@ struct VR_IVRCompositor_FnTable void (OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); void (OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView); + void (OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void * pD3D11ShaderResourceView); EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t * pglTextureId, glSharedTextureHandle_t * pglSharedTextureHandle); bool (OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); void (OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); @@ -1662,12 +1740,13 @@ struct VR_IVRCompositor_FnTable struct VR_IVROverlay_FnTable { EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pOverlayHandle); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayName, VROverlayHandle_t * pOverlayHandle); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchName); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); @@ -1690,6 +1769,8 @@ struct VR_IVROverlay_FnTable EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); + uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, struct HmdColor_t * pColor, EVROverlayError * pError); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchRenderModel, struct HmdColor_t * pColor); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); @@ -1697,6 +1778,8 @@ struct VR_IVROverlay_FnTable EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t * ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); + EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h b/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h index c2d550eba..e0732a0f5 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h @@ -21,19 +21,13 @@ struct VkPhysicalDevice_T; struct VkInstance_T; struct VkQueue_T; +// Forward declarations to avoid requiring d3d12.h +struct ID3D12Resource; +struct ID3D12CommandQueue; + namespace vr { - -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) typedef void* glSharedTextureHandle_t; typedef int32_t glInt_t; @@ -116,6 +110,8 @@ enum ETextureType TextureType_DirectX = 0, // Handle is an ID3D11Texture TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace @@ -164,6 +160,7 @@ enum ETrackedDeviceClass TrackedDeviceClass_Controller = 2, // Tracked controllers TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; @@ -199,6 +196,30 @@ enum ETrackingUniverseOrigin TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; +// Refers to a single container of properties +typedef uint64_t PropertyContainerHandle_t; +typedef uint32_t PropertyTypeTag_t; + +static const PropertyContainerHandle_t k_ulInvalidPropertyContainer = 0; +static const PropertyTypeTag_t k_unInvalidPropertyTag = 0; + +// Use these tags to set/get common types as struct properties +static const PropertyTypeTag_t k_unFloatPropertyTag = 1; +static const PropertyTypeTag_t k_unInt32PropertyTag = 2; +static const PropertyTypeTag_t k_unUint64PropertyTag = 3; +static const PropertyTypeTag_t k_unBoolPropertyTag = 4; +static const PropertyTypeTag_t k_unStringPropertyTag = 5; + +static const PropertyTypeTag_t k_unHmdMatrix34PropertyTag = 20; +static const PropertyTypeTag_t k_unHmdMatrix44PropertyTag = 21; +static const PropertyTypeTag_t k_unHmdVector3PropertyTag = 22; +static const PropertyTypeTag_t k_unHmdVector4PropertyTag = 23; + +static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; + +static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; +static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; + /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ @@ -241,6 +262,8 @@ enum ETrackedDeviceProperty Prop_DriverVersion_String = 1031, Prop_Firmware_ForceUpdateRequired_Bool = 1032, Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD Prop_ReportsTimeSinceVSync_Bool = 2000, @@ -281,6 +304,11 @@ enum ETrackedDeviceProperty Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, Prop_DisplaySuppressed_Bool = 2036, Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, // Properties that are unique to TrackedDeviceClass_Controller Prop_AttachedDeviceId_String = 3000, @@ -312,6 +340,19 @@ enum ETrackedDeviceProperty Prop_NamedIconPathDeviceStandby_String = 5007, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others Prop_NamedIconPathDeviceAlertLow_String = 5008, // PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + // Properties that are used by helpers, but are opaque to applications + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, + + // Properties that are unique to drivers + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, + // Vendors are free to expose private debug data in this reserved region Prop_VendorSpecific_Reserved_Start = 10000, Prop_VendorSpecific_Reserved_End = 10999, @@ -327,13 +368,14 @@ enum ETrackedPropertyError TrackedProp_WrongDataType = 1, TrackedProp_WrongDeviceClass = 2, TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). TrackedProp_InvalidDevice = 5, TrackedProp_CouldNotContactServer = 6, TrackedProp_ValueNotProvidedByDevice = 7, TrackedProp_StringExceedsMaximumLength = 8, TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -376,6 +418,14 @@ struct VRVulkanTextureData_t uint32_t m_nWidth, m_nHeight, m_nFormat, m_nSampleCount; }; +/** Data required for passing D3D12 textures to IVRCompositor::Submit. +* Be sure to call OpenVR_Shutdown before destroying these resources. */ +struct D3D12TextureData_t +{ + ID3D12Resource *m_pResource; + ID3D12CommandQueue *m_pCommandQueue; + uint32_t m_nNodeMask; +}; /** Status of the overall system or tracked objects */ enum EVRState @@ -399,7 +449,7 @@ enum EVREventType VREvent_TrackedDeviceActivated = 100, VREvent_TrackedDeviceDeactivated = 101, VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionStarted = 103, VREvent_TrackedDeviceUserInteractionEnded = 104, VREvent_IpdChanged = 105, VREvent_EnterStandbyMode = 106, @@ -407,6 +457,7 @@ enum EVREventType VREvent_TrackedDeviceRoleChanged = 108, VREvent_WatchdogWakeUpRequested = 109, VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, VREvent_ButtonPress = 200, // data is controller VREvent_ButtonUnpress = 201, // data is controller @@ -436,78 +487,83 @@ enum EVREventType VREvent_OverlayShown = 500, VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + + VREvent_PrimaryDashboardDeviceChanged = 525, VREvent_Notification_Shown = 600, VREvent_Notification_Hidden = 601, VREvent_Notification_BeginInteraction = 602, VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, VREvent_TrackedCamera_StartVideoStream = 1500, VREvent_TrackedCamera_StopVideoStream = 1501, @@ -515,26 +571,30 @@ enum EVREventType VREvent_TrackedCamera_ResumeVideoStream = 1503, VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, - VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlay_Closed = 1650, // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; /** Level of Hmd activity */ +// UserInteraction_Timeout means the device is in the process of timing out. +// InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) +// VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. +// VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, - k_EDeviceActivityLevel_UserInteraction = 1, - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, - k_EDeviceActivityLevel_Standby = 3, +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; @@ -711,6 +771,12 @@ struct VREvent_MessageOverlay_t uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; +struct VREvent_Property_t +{ + PropertyContainerHandle_t container; + ETrackedDeviceProperty prop; +}; + /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ typedef union { @@ -733,8 +799,16 @@ typedef union VREvent_ApplicationLaunch_t applicationLaunch; VREvent_EditingCameraSurface_t cameraSurface; VREvent_MessageOverlay_t messageOverlay; + VREvent_Property_t property; } VREvent_Data_t; + +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + /** An event posted by the server to all running applications */ struct VREvent_t { @@ -745,6 +819,9 @@ struct VREvent_t VREvent_Data_t data; }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif /** The mesh to draw into the stencil (or depth) buffer to perform * early stencil (or depth) kills of pixels that will never appear on the HMD. @@ -764,6 +841,8 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Standard = 0, k_eHiddenAreaMesh_Inverse = 1, k_eHiddenAreaMesh_LineLoop = 2, + + k_eHiddenAreaMesh_Max = 3, }; @@ -791,6 +870,12 @@ struct VRControllerAxis_t static const uint32_t k_unControllerStateAxisCount = 5; +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack( push, 4 ) +#endif + /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { @@ -805,6 +890,9 @@ struct VRControllerState001_t // Axis data for the controller's analog inputs VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; }; +#if defined(__linux__) || defined(__APPLE__) +#pragma pack( pop ) +#endif typedef VRControllerState001_t VRControllerState_t; @@ -887,6 +975,7 @@ enum EVRApplicationType // interfaces (like IVRSettings and IVRApplications) but not hardware. VRApplication_VRMonitor = 5, // Reserved for vrmonitor VRApplication_SteamWatchdog = 6,// Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; @@ -1132,16 +1221,7 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; namespace vr { -#if defined(__linux__) || defined(__APPLE__) - // The 32-bit version of gcc has the alignment requirement for uint64 and double set to - // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned. - // The 64-bit version of gcc has the alignment requirement for these types set to - // 8 meaning that unless we use #pragma pack(4) our structures will get bigger. - // The 64-bit structure packing has to match the 32-bit structure packing for each platform. - #pragma pack( push, 4 ) -#else - #pragma pack( push, 8 ) -#endif +#pragma pack( push, 8 ) enum ECameraVideoStreamFormat { @@ -1274,7 +1354,6 @@ namespace vr static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_EnableDistortion_Bool = "enableDistortion"; static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; @@ -1325,7 +1404,6 @@ namespace vr //----------------------------------------------------------------------------- // null keys static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_EnableNullDriver_Bool = "enable"; static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; static const char * const k_pch_Null_WindowX_Int32 = "windowX"; @@ -1426,6 +1504,10 @@ namespace vr // model skin keys static const char * const k_pch_modelskin_Section = "modelskins"; + //----------------------------------------------------------------------------- + // driver keys - These could be checked in any driver_ section + static const char * const k_pch_Driver_Enable_Bool = "enable"; + } // namespace vr // iservertrackeddevicedriver.h @@ -1543,37 +1625,11 @@ public: // Tracking Methods // ------------------------------------ virtual DriverPose_t GetPose() = 0; - - // ------------------------------------ - // Property Methods - // ------------------------------------ - - /** Returns a bool property. If the property is not available this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) = 0; - - /** Returns a float property. If the property is not available this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) = 0; - - /** Returns an int property. If the property is not available this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) = 0; - - /** Returns a uint64 property. If the property is not available this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) = 0; - - /** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */ - virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) = 0; - - /** Returns a string property. If the property is not available this function will return 0 and pError will be - * set to an error. Otherwise it returns the length of the number of bytes necessary to hold this string including - * the trailing null. If the buffer is too small the error will be TrackedProp_BufferTooSmall. Drivers may not - * return strings longer than k_unMaxPropertyStringSize. */ - virtual uint32_t GetStringTrackedDeviceProperty( ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) = 0; - }; -static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_004"; +static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_005"; } // ivrdisplaycomponent.h @@ -1745,73 +1801,21 @@ namespace vr class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; - -class IDriverLog -{ -public: - /** Writes a log message to the log file prefixed with the driver name */ - virtual void Log( const char *pchLogMessage ) = 0; -}; +typedef PropertyContainerHandle_t DriverHandle_t; /** This interface is provided by vrserver to allow the driver to notify * the system when something changes about a device. These changes must * not change the serial number or class of the device because those values * are permanently associated with the device's index. */ -class IServerDriverHost +class IVRDriverContext { public: - /** Notifies the server that a tracked device has been added. If this function returns true - * the server will call Activate on the device. If it returns false some kind of error - * has occurred and the device will not be activated. */ - virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber ) = 0; + /** Returns the requested interface. If the interface was not available it will return NULL and fill + * out the error. */ + virtual void *GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError = nullptr ) = 0; - /** Notifies the server that a tracked device's pose has been updated */ - virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose ) = 0; - - /** Notifies the server that the property cache for the specified device should be invalidated */ - virtual void TrackedDevicePropertiesChanged( uint32_t unWhichDevice ) = 0; - - /** Notifies the server that vsync has occurred on the the display attached to the device. This is - * only permitted on devices of the HMD class. */ - virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; - - /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; - - /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; - - /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; - - /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; - - /** notifies the server than a controller axis changed */ - virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; - - /** Notifies the server that the MC image has been updated for the display attached to the device. This is - * only permitted on devices of the HMD class. */ - virtual void MCImageUpdated() = 0; - - /** always returns a pointer to a valid interface pointer of IVRSettings */ - virtual IVRSettings *GetSettings( const char *pchInterfaceVersion ) = 0; - - /** Notifies the server that the physical IPD adjustment has been moved on the HMD */ - virtual void PhysicalIpdSet( uint32_t unWhichDevice, float fPhysicalIpdMeters ) = 0; - - /** Notifies the server that the proximity sensor on the specified device */ - virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; - - /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ - virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; - - /** Returns true if SteamVR is exiting */ - virtual bool IsExiting() = 0; - - /** Returns true and fills the event with the next event on the queue if there is one. If there are no events - * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + /** Returns the property container handle for this driver */ + virtual DriverHandle_t GetDriverHandle() = 0; }; @@ -1828,7 +1832,7 @@ public: * config files. * pchDriverInstallDir - The absolute path of the root directory for the driver. */ - virtual EVRInitError Init( IDriverLog *pDriverLog, vr::IServerDriverHost *pDriverHost, const char *pchUserDriverConfigDir, const char *pchDriverInstallDir ) = 0; + virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; @@ -1836,15 +1840,6 @@ public: /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ virtual const char * const *GetInterfaceVersions() = 0; - /** returns the number of HMDs that this driver manages that are physically connected. */ - virtual uint32_t GetTrackedDeviceCount() = 0; - - /** returns a single HMD */ - virtual ITrackedDeviceServerDriver *GetTrackedDeviceDriver( uint32_t unWhich ) = 0; - - /** returns a single HMD by ID */ - virtual ITrackedDeviceServerDriver* FindTrackedDeviceDriver( const char *pchId ) = 0; - /** Allows the driver do to some work in the main loop of the server. */ virtual void RunFrame() = 0; @@ -1865,108 +1860,535 @@ public: }; -static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_003"; +static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_004"; -/** This interface is provided by vrclient to allow the driver call back and query various information */ -class IClientDriverHost + + +/** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ +class IVRWatchdogProvider { public: - /** Returns the device class of a tracked device. If there has not been a device connected in this slot - * since the application started this function will return TrackedDevice_Invalid. For previous detected - * devices the function will return the previously observed device class. - * - * To determine which devices exist on the system, just loop from 0 to k_unMaxTrackedDeviceCount and check - * the device class. Every device with something other than TrackedDevice_Invalid is associated with an - * actual tracked device. */ - virtual ETrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + /** initializes the driver in watchdog mode. */ + virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; - /** Returns true if there is a device connected in this slot. */ - virtual bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + /** cleans up the driver right before it is unloaded */ + virtual void Cleanup() = 0; +}; - /** Returns a bool property. If the device index is not valid or the property is not a bool type this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; +static const char *IVRWatchdogProvider_Version = "IVRWatchdogProvider_001"; - /** Returns a float property. If the device index is not valid or the property is not a float type this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; +} +// ivrproperties.h +#include - /** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; +namespace vr +{ - /** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + enum EPropertyWriteType + { + PropertyWrite_Set = 0, + PropertyWrite_Erase = 1, + PropertyWrite_SetError = 2 + }; - /** Returns a string property. If the device index is not valid or the property is not a float type this function will + struct PropertyWrite_t + { + ETrackedDeviceProperty prop; + EPropertyWriteType writeType; + ETrackedPropertyError eSetError; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + ETrackedPropertyError eError; + }; + + struct PropertyRead_t + { + ETrackedDeviceProperty prop; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + uint32_t unRequiredBufferSize; + ETrackedPropertyError eError; + }; + + +class IVRProperties +{ +public: + + /** Reads a set of properties atomically. See the PropertyReadBatch_t struct for more information. */ + virtual ETrackedPropertyError ReadPropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount ) = 0; + + /** Writes a set of properties atomically. See the PropertyWriteBatch_t struct for more information. */ + virtual ETrackedPropertyError WritePropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount ) = 0; + + /** returns a string that corresponds with the specified property error. The string will be the name + * of the error enum value for all valid error codes */ + virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + + /** Returns a container handle given a tracked device index */ + virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) = 0; + +}; + +static const char * const IVRProperties_Version = "IVRProperties_001"; + +class CVRPropertyHelpers +{ +public: + CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {} + + /** Returns a scaler property. If the device index is not valid or the property value type does not match, + * this function will return false. */ + bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + float GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + int32_t GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + uint64_t GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + + /** Returns a single typed property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing - * null. Strings will generally fit in buffers of k_unTrackingStringSize characters. */ - virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0; + * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ + uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L ); - /** always returns a pointer to a valid interface pointer of IVRSettings */ - virtual void *GetGenericInterface( const char *pchInterfaceVersion ) = 0; + /** Returns a string property. If the device index is not valid or the property is not a string type this function will + * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing + * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ + uint32_t GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ); + + /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will + * return an empty string. */ + std::string GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr ); + + /** Sets a scaler property. The new value will be returned on any subsequent call to get this property in any process. */ + ETrackedPropertyError SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ); + ETrackedPropertyError SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ); + ETrackedPropertyError SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ); + ETrackedPropertyError SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ); + + /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ + ETrackedPropertyError SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ); + + /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ + ETrackedPropertyError SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ); + + /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ + ETrackedPropertyError SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ); + + /** Clears any value or error set for the property. */ + ETrackedPropertyError EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ); + + /* Turns a device index into a property container handle. */ + PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) { return m_pProperties->TrackedDeviceToPropertyContainer( nDevice ); } + +private: + template + T GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ); + + IVRProperties *m_pProperties; +}; + + +inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError ) +{ + PropertyRead_t batch; + batch.prop = prop; + batch.pvBuffer = pvBuffer; + batch.unBufferSize = unBufferSize; + + m_pProperties->ReadPropertyBatch( ulContainerHandle, &batch, 1 ); + + if ( pError ) + { + *pError = batch.eError; + } + + if ( punTag ) + { + *punTag = batch.unTag; + } + + return batch.unRequiredBufferSize; +} + + +/** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ +inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ) +{ + PropertyWrite_t batch; + batch.writeType = PropertyWrite_Set; + batch.prop = prop; + batch.pvBuffer = pvNewValue; + batch.unBufferSize = unNewValueSize; + batch.unTag = unTag; + + m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + + return batch.eError; +} + + +/** Returns a string property. If the device index is not valid or the property is not a string type this function will +* return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing +* null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ +inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) +{ + PropertyTypeTag_t unTag; + ETrackedPropertyError error; + uint32_t unRequiredSize = GetProperty( ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error ); + if ( unTag != k_unStringPropertyTag && error == TrackedProp_Success ) + { + error = TrackedProp_WrongDataType; + } + + if ( pError ) + { + *pError = error; + } + + if ( error != TrackedProp_Success ) + { + if ( pchValue && unBufferSize ) + { + *pchValue = '\0'; + } + } + + return unRequiredSize; +} + + +/** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will +* return an empty string. */ +inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError ) +{ + char buf[1024]; + vr::ETrackedPropertyError err; + uint32_t unRequiredBufferLen = GetStringProperty( ulContainer, prop, buf, sizeof(buf), &err ); + + std::string sResult; + + if ( err == TrackedProp_Success ) + { + sResult = buf; + } + else if ( err == TrackedProp_BufferTooSmall ) + { + char *pchBuffer = new char[unRequiredBufferLen]; + unRequiredBufferLen = GetStringProperty( ulContainer, prop, pchBuffer, unRequiredBufferLen, &err ); + sResult = pchBuffer; + delete[] pchBuffer; + } + + if ( peError ) + { + *peError = err; + } + + return sResult; +} + + +/** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ +inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ) +{ + if ( !pchNewValue ) + return TrackedProp_InvalidOperation; + + // this is strlen without the dependency on string.h + const char *pchCurr = pchNewValue; + while ( *pchCurr ) + { + pchCurr++; + } + + return SetProperty( ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag ); +} + + +template +inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ) +{ + T bValue; + ETrackedPropertyError eError; + PropertyTypeTag_t unReadTag; + GetProperty( ulContainerHandle, prop, &bValue, sizeof( bValue ), &unReadTag, &eError ); + if ( unReadTag != unTypeTag && eError == TrackedProp_Success ) + { + eError = TrackedProp_WrongDataType; + }; + + if ( pError ) + *pError = eError; + if ( eError != TrackedProp_Success ) + { + return bDefault; + } + else + { + return bValue; + } +} + + +inline bool CVRPropertyHelpers::GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +{ + return GetPropertyHelper( ulContainerHandle, prop, pError, false, k_unBoolPropertyTag ); +} + + +inline float CVRPropertyHelpers::GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +{ + return GetPropertyHelper( ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag ); +} + +inline int32_t CVRPropertyHelpers::GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +{ + return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag ); +} + +inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +{ + return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag ); +} + +inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ) +{ + return SetProperty( ulContainerHandle, prop, &bNewValue, sizeof( bNewValue ), k_unBoolPropertyTag ); +} + +inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ) +{ + return SetProperty( ulContainerHandle, prop, &fNewValue, sizeof( fNewValue ), k_unFloatPropertyTag ); +} + +inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ) +{ + return SetProperty( ulContainerHandle, prop, &nNewValue, sizeof( nNewValue ), k_unInt32PropertyTag ); +} + +inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ) +{ + return SetProperty( ulContainerHandle, prop, &ulNewValue, sizeof( ulNewValue ), k_unUint64PropertyTag ); +} + +/** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ +inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ) +{ + PropertyWrite_t batch; + batch.writeType = PropertyWrite_SetError; + batch.prop = prop; + batch.eSetError = eError; + + m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + + return batch.eError; +} + +/** Clears any value or error set for the property. */ +inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ) +{ + PropertyWrite_t batch; + batch.writeType = PropertyWrite_Erase; + batch.prop = prop; + + m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + + return batch.eError; + +} + +} + + +// ivrdriverlog.h +namespace vr +{ + +class IVRDriverLog +{ +public: + /** Writes a log message to the log file prefixed with the driver name */ + virtual void Log( const char *pchLogMessage ) = 0; +}; + + +static const char *IVRDriverLog_Version = "IVRDriverLog_001"; + +} +// ivrserverdriverhost.h +namespace vr +{ + +class ITrackedDeviceServerDriver; +struct TrackedDeviceDriverInfo_t; +struct DriverPose_t; + +/** This interface is provided by vrserver to allow the driver to notify +* the system when something changes about a device. These changes must +* not change the serial number or class of the device because those values +* are permanently associated with the device's index. */ +class IVRServerDriverHost +{ +public: + /** Notifies the server that a tracked device has been added. If this function returns true + * the server will call Activate on the device. If it returns false some kind of error + * has occurred and the device will not be activated. */ + virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver ) = 0; + + /** Notifies the server that a tracked device's pose has been updated */ + virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose, uint32_t unPoseStructSize ) = 0; + + /** Notifies the server that vsync has occurred on the the display attached to the device. This is + * only permitted on devices of the HMD class. */ + virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; + + /** notifies the server that the button was pressed */ + virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + + /** notifies the server that the button was unpressed */ + virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + + /** notifies the server that the button was pressed */ + virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + + /** notifies the server that the button was unpressed */ + virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + + /** notifies the server than a controller axis changed */ + virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; + + /** Notifies the server that the proximity sensor on the specified device */ + virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; + + /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ + virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; + + /** Returns true if SteamVR is exiting */ + virtual bool IsExiting() = 0; + + /** Returns true and fills the event with the next event on the queue if there is one. If there are no events + * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ + virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + + /** Provides access to device poses for drivers. Poses are in their "raw" tracking space which is uniquely + * defined by each driver providing poses for its devices. It is up to clients of this function to correlate + * poses across different drivers. Poses are indexed by their device id, and their associated driver and + * other properties can be looked up via IVRProperties. */ + virtual void GetRawTrackedDevicePoses( float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; +}; + +static const char *IVRServerDriverHost_Version = "IVRServerDriverHost_004"; + +} + +// ivrhiddenarea.h +namespace vr +{ + +class CVRHiddenAreaHelpers +{ +public: + CVRHiddenAreaHelpers( IVRProperties *pProperties ) : m_pProperties( pProperties ) {} + + /** Stores a hidden area mesh in a property */ + ETrackedPropertyError SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ); + + /** retrieves a hidden area mesh from a property. Returns the vert count read out of the property. */ + uint32_t GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ); + +private: + ETrackedDeviceProperty GetPropertyEnum( EVREye eEye, EHiddenAreaMeshType type ) + { + return (ETrackedDeviceProperty)(Prop_DisplayHiddenArea_Binary_Start + ((int)type * 2) + (int)eEye); + } + + IVRProperties *m_pProperties; +}; + + +inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ) +{ + ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); + CVRPropertyHelpers propHelpers( m_pProperties ); + return propHelpers.SetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t ) * unVertCount, k_unHiddenAreaPropertyTag ); +} + + +inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ) +{ + ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); + CVRPropertyHelpers propHelpers( m_pProperties ); + ETrackedPropertyError propError; + PropertyTypeTag_t unTag; + uint32_t unBytesNeeded = propHelpers.GetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t )*unVertCount, &unTag, &propError ); + if ( propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag ) + { + propError = TrackedProp_WrongDataType; + unBytesNeeded = 0; + } + + if ( peError ) + { + *peError = propError; + } + + return unBytesNeeded / sizeof( HmdVector2_t ); +} + +} +// ivrwatchdoghost.h +namespace vr +{ + +/** This interface is provided by vrclient to allow the driver to make everything wake up */ +class IVRWatchdogHost +{ +public: /** Client drivers in watchdog mode should call this when they have received a signal from hardware that should * cause SteamVR to start */ virtual void WatchdogWakeUp() = 0; }; +static const char *IVRWatchdogHost_Version = "IVRWatchdogHost_001"; -/** Defines the mode that the client driver should start in. */ -enum EClientDriverMode -{ - ClientDriverMode_Normal = 0, - ClientDriverMode_Watchdog = 1, // client should return VRInitError_Init_LowPowerWatchdogNotSupported if it can't support this mode }; -/** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ -class IClientTrackedDeviceProvider + +// ivrvirtualdisplay.h +namespace vr { -public: - /** initializes the driver. This will be called before any other methods are called, - * except BIsHmdPresent(). BIsHmdPresent is called outside of the Init/Cleanup pair. - * If Init returns anything other than VRInitError_None the driver DLL will be unloaded. - * - * pDriverHost will never be NULL, and will always be a pointer to a IClientDriverHost interface - * - * pchUserDriverConfigDir - The absolute path of the directory where the driver should store user - * config files. - * pchDriverInstallDir - The absolute path of the root directory for the driver. - */ - virtual EVRInitError Init( EClientDriverMode eDriverMode, IDriverLog *pDriverLog, vr::IClientDriverHost *pDriverHost, const char *pchUserDriverConfigDir, const char *pchDriverInstallDir ) = 0; + // ---------------------------------------------------------------------------------------------- + // Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). + // ---------------------------------------------------------------------------------------------- + class IVRVirtualDisplay + { + public: - /** cleans up the driver right before it is unloaded */ - virtual void Cleanup() = 0; + /** Submits final backbuffer for display. */ + virtual void Present( vr::SharedTextureHandle_t backbufferTextureHandle ) = 0; - /** Called when the client needs to inform an application if an HMD is attached that uses - * this driver. This method should be as lightweight as possible and should have no side effects - * such as hooking process functions or leaving resources loaded. Init will not be called before - * this method and Cleanup will not be called after it. - */ - virtual bool BIsHmdPresent( const char *pchUserConfigDir ) = 0; + /** Block until the last presented buffer start scanning out. */ + virtual void WaitForPresent() = 0; - /** called when the client inits an HMD to let the client driver know which one is in use */ - virtual EVRInitError SetDisplayId( const char *pchDisplayId ) = 0; + /** Provides timing data for synchronizing with display. */ + virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; + }; - /** Returns the stencil mesh information for the current HMD. If this HMD does not have a stencil mesh the vertex data and count will be - * NULL and 0 respectively. This mesh is meant to be rendered into the stencil buffer (or into the depth buffer setting nearz) before rendering - * each eye's view. The pixels covered by this mesh will never be seen by the user after the lens distortion is applied and based on visibility to the panels. - * This will improve perf by letting the GPU early-reject pixels the user will never see before running the pixel shader. - * NOTE: Render this mesh with backface culling disabled since the winding order of the vertices can be different per-HMD or per-eye. - */ - virtual HiddenAreaMesh_t GetHiddenAreaMesh( EVREye eEye, EHiddenAreaMeshType type ) = 0; - - /** Get the MC image for the current HMD. - * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t GetMCImage( uint32_t *pImgWidth, uint32_t *pImgHeight, uint32_t *pChannels, void *pDataBuffer, uint32_t unBufferLen ) = 0; -}; - -static const char *IClientTrackedDeviceProvider_Version = "IClientTrackedDeviceProvider_005"; + static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; + /** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ + VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); } + + namespace vr { static const char * const k_InterfaceVersions[] = @@ -1978,9 +2400,186 @@ namespace vr IVRControllerComponent_Version, IVRCameraComponent_Version, IServerTrackedDeviceProvider_Version, - IClientTrackedDeviceProvider_Version, + IVRWatchdogProvider_Version, + IVRVirtualDisplay_Version, nullptr }; + + inline IVRDriverContext *&VRDriverContext() + { + static IVRDriverContext *pHost; + return pHost; + } + + class COpenVRDriverContext + { + public: + COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } + void Clear(); + + EVRInitError InitServer(); + EVRInitError InitWatchdog(); + + IVRSettings *VRSettings() + { + if ( m_pVRSettings == nullptr ) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface( IVRSettings_Version, &eError ); + } + return m_pVRSettings; + } + + IVRProperties *VRPropertiesRaw() + { + if ( m_pVRProperties == nullptr ) + { + EVRInitError eError; + m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface( IVRProperties_Version, &eError ); + m_propertyHelpers = CVRPropertyHelpers( m_pVRProperties ); + m_hiddenAreaHelpers = CVRHiddenAreaHelpers( m_pVRProperties ); + } + return m_pVRProperties; + } + + CVRPropertyHelpers *VRProperties() + { + VRPropertiesRaw(); + return &m_propertyHelpers; + } + + CVRHiddenAreaHelpers *VRHiddenArea() + { + VRPropertiesRaw(); + return &m_hiddenAreaHelpers; + } + + IVRServerDriverHost *VRServerDriverHost() + { + if ( m_pVRServerDriverHost == nullptr ) + { + EVRInitError eError; + m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface( IVRServerDriverHost_Version, &eError ); + } + return m_pVRServerDriverHost; + } + + IVRWatchdogHost *VRWatchdogHost() + { + if ( m_pVRWatchdogHost == nullptr ) + { + EVRInitError eError; + m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface( IVRWatchdogHost_Version, &eError ); + } + return m_pVRWatchdogHost; + } + + IVRDriverLog *VRDriverLog() + { + if ( m_pVRDriverLog == nullptr ) + { + EVRInitError eError; + m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface( IVRDriverLog_Version, &eError ); + } + return m_pVRDriverLog; + } + + DriverHandle_t VR_CALLTYPE VRDriverHandle() + { + return VRDriverContext()->GetDriverHandle(); + } + + private: + IVRSettings *m_pVRSettings; + IVRProperties *m_pVRProperties; + CVRPropertyHelpers m_propertyHelpers; + CVRHiddenAreaHelpers m_hiddenAreaHelpers; + IVRServerDriverHost *m_pVRServerDriverHost; + IVRWatchdogHost *m_pVRWatchdogHost; + IVRDriverLog *m_pVRDriverLog; + }; + + inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() + { + static void *ctx[sizeof( COpenVRDriverContext ) / sizeof( void * )]; + return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor + } + + inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } + inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } + inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } + inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } + inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } + inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } + inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } + inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } + inline void COpenVRDriverContext::Clear() + { + m_pVRSettings = nullptr; + m_pVRProperties = nullptr; + m_pVRServerDriverHost = nullptr; + m_pVRDriverLog = nullptr; + m_pVRWatchdogHost = nullptr; + } + + inline EVRInitError COpenVRDriverContext::InitServer() + { + Clear(); + if ( !VRServerDriverHost() + || !VRSettings() + || !VRProperties() + || !VRDriverLog() ) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; + } + + inline EVRInitError COpenVRDriverContext::InitWatchdog() + { + Clear(); + if ( !VRWatchdogHost() + || !VRSettings() + || !VRDriverLog() ) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; + } + + inline EVRInitError InitServerDriverContext( IVRDriverContext *pContext ) + { + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitServer(); + } + + inline EVRInitError InitWatchdogDriverContext( IVRDriverContext *pContext ) + { + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); + } + + inline void CleanupDriverContext() + { + VRDriverContext() = nullptr; + OpenVRInternal_ModuleServerDriverContext().Clear(); + } + + #define VR_INIT_SERVER_DRIVER_CONTEXT( pContext ) \ + { \ + vr::EVRInitError eError = vr::InitServerDriverContext( pContext ); \ + if( eError != vr::VRInitError_None ) \ + return eError; \ + } + + #define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); + + #define VR_INIT_WATCHDOG_DRIVER_CONTEXT( pContext ) \ + { \ + vr::EVRInitError eError = vr::InitWatchdogDriverContext( pContext ); \ + if( eError != vr::VRInitError_None ) \ + return eError; \ + } + + #define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); } // End diff --git a/examples/ThirdPartyLibs/openvr/lib/linux32/libopenvr_api.so b/examples/ThirdPartyLibs/openvr/lib/linux32/libopenvr_api.so new file mode 100644 index 000000000..ccfeabae6 Binary files /dev/null and b/examples/ThirdPartyLibs/openvr/lib/linux32/libopenvr_api.so differ diff --git a/examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so b/examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so index 46470254e..d83a610fc 100644 Binary files a/examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so and b/examples/ThirdPartyLibs/openvr/lib/linux64/libopenvr_api.so differ diff --git a/examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib b/examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib index 1521479a9..130bad031 100644 Binary files a/examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib and b/examples/ThirdPartyLibs/openvr/lib/win32/openvr_api.lib differ diff --git a/examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib b/examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib index 9fdab5635..e8d9abf0e 100644 Binary files a/examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib and b/examples/ThirdPartyLibs/openvr/lib/win64/openvr_api.lib differ diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/compat.h b/examples/ThirdPartyLibs/openvr/samples/shared/compat.h index 0163b08f2..154f8b072 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/compat.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/compat.h @@ -15,6 +15,7 @@ #define vsprintf_s sprintf #define _stricmp strcmp #define stricmp strcmp +#define strnicmp strncasecmp #define strcpy_s(dst, n, src) int(strncpy(dst, src, n) != nullptr) #define fopen_s(fd, path, mode) int((*fd = fopen(path, mode)) != nullptr) #define _vsnprintf_s(buffer, size, fmt, ap) vsnprintf(buffer, size, fmt, ap) @@ -24,4 +25,4 @@ typedef int errno_t; #endif // _WIN32 -#endif // OPENVR_SAMPLES_SHARED_COMPAT_H_ \ No newline at end of file +#endif // OPENVR_SAMPLES_SHARED_COMPAT_H_ diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp index d148a5d84..2ea352406 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp +++ b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp @@ -1,22 +1,27 @@ //========= Copyright Valve Corporation ============// +#include "compat.h" +#include "strtools.h" #include "pathtools.h" -//#include "hmdplatform_private.h" -//#include "vrcommon/strtools.h" #if defined( _WIN32) #include #include #include #include -#elif defined OSX -#include -#include -#include "osxfilebridge.h" -#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet -#define _MAX_PATH MAX_PATH // yet another form of _PATH define we use -#elif defined(LINUX) +#include + +#undef GetEnvironmentVariable +#else #include #include +#include +#include +#endif +#if defined OSX +#include +#include +#include +#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet #endif #include @@ -26,44 +31,54 @@ /** Returns the path (including filename) to the current executable */ std::string Path_GetExecutablePath() { - bool bSuccess = false; - char rchPath[ 1024 ]; - size_t nBuff = sizeof(rchPath); #if defined( _WIN32 ) - bSuccess = ::GetModuleFileNameA(NULL, rchPath, (DWORD)nBuff) > 0; -#elif defined OSX - uint32_t _nBuff = nBuff; - bSuccess = _NSGetExecutablePath(rchPath, &_nBuff) == 0; - rchPath[nBuff-1] = '\0'; -#elif defined LINUX - ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 ); - if ( nRead != -1 ) - { - rchPath[ nRead ] = 0; - bSuccess = true; - } - else - { - rchPath[ 0 ] = '\0'; - } -#else - AssertMsg( false, "Implement Plat_GetExecutablePath" ); -#endif + wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH]; + char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8]; + ::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH ); + WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL ); + delete[] pwchPath; + std::string sPath = pchPath; + delete[] pchPath; + return sPath; +#elif defined( OSX ) + char rchPath[1024]; + uint32_t nBuff = sizeof( rchPath ); + bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0; + rchPath[nBuff-1] = '\0'; if( bSuccess ) return rchPath; else return ""; +#elif defined LINUX + char rchPath[1024]; + size_t nBuff = sizeof( rchPath ); + ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 ); + if ( nRead != -1 ) + { + rchPath[ nRead ] = 0; + return rchPath; + } + else + { + return ""; + } +#else + AssertMsg( false, "Implement Plat_GetExecutablePath" ); + return ""; +#endif + } /** Returns the path of the current working directory */ std::string Path_GetWorkingDirectory() { std::string sPath; - char buf[ 1024 ]; #if defined( _WIN32 ) - sPath = _getcwd( buf, sizeof( buf ) ); + wchar_t buf[MAX_UNICODE_PATH]; + sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) ); #else + char buf[ 1024 ]; sPath = getcwd( buf, sizeof( buf ) ); #endif return sPath; @@ -74,37 +89,14 @@ bool Path_SetWorkingDirectory( const std::string & sPath ) { bool bSuccess; #if defined( _WIN32 ) - bSuccess = 0 == _chdir( sPath.c_str() ); + std::wstring wsPath = UTF8to16( sPath.c_str() ); + bSuccess = 0 == _wchdir( wsPath.c_str() ); #else bSuccess = 0 == chdir( sPath.c_str() ); #endif return bSuccess; } -std::string Path_GetModulePath() -{ -#if defined( _WIN32 ) - char path[32768]; - HMODULE hm = NULL; - - if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - (LPCSTR) &Path_GetModulePath, - &hm)) - { - int ret = GetLastError(); - fprintf(stderr, "GetModuleHandle returned %d\n", ret); - return ""; - } - GetModuleFileNameA(hm, path, sizeof(path)); - FreeLibrary( hm ); - return path; -#else - Dl_info dl_info; - dladdr((void *)Path_GetModulePath, &dl_info); - return dl_info.dli_fname; -#endif -} - /** Returns the specified path without its filename */ std::string Path_StripFilename( const std::string & sPath, char slash ) { @@ -151,17 +143,45 @@ std::string Path_StripExtension( const std::string & sPath ) return sPath; } +/** returns just extension of the provided filename (if any). */ +std::string Path_GetExtension( const std::string & sPath ) +{ + for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ ) + { + if ( *i == '.' ) + { + return std::string( i.base(), sPath.end() ); + } + + // if we find a slash there is no extension + if ( *i == '\\' || *i == '/' ) + break; + } + + // we didn't find an extension + return ""; +} bool Path_IsAbsolute( const std::string & sPath ) { if( sPath.empty() ) return false; - if( sPath.find( ':' ) != std::string::npos ) - return true; +#if defined( WIN32 ) + if ( sPath.size() < 3 ) // must be c:\x or \\x at least + return false; - if( sPath[0] == '\\' || sPath[0] == '/' ) + if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases + { + if ( sPath[2] == '\\' || sPath[2] == '/' ) + return true; + } + else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path return true; +#else + if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash + return true; +#endif return false; } @@ -223,6 +243,8 @@ std::string Path_Join( const std::string & first, const std::string & second, ch // only insert a slash if we don't already have one std::string::size_type nLen = first.length(); + if( !nLen ) + return second; #if defined(_WIN32) if( first.back() == '\\' || first.back() == '/' ) nLen--; @@ -257,6 +279,41 @@ std::string Path_Join( return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash ); } + +std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash ) +{ + if ( slash == 0 ) + slash = Path_GetSlash(); + + std::string sPath = sRawPath; + std::string::size_type nCurrent = sRawPath.length(); + if ( nCurrent == 0 ) + return sPath; + + int nLastFound = -1; + nCurrent--; + while( nCurrent != 0 ) + { + if ( sRawPath[ nCurrent ] == slash ) + { + nLastFound = (int)nCurrent; + nCurrent--; + } + else + { + break; + } + } + + if ( nLastFound >= 0 ) + { + sPath.erase( nLastFound, std::string::npos ); + } + + return sPath; +} + + /** Removes redundant /.. elements in the path. Returns an empty path if the * specified path has a broken number of directories for its number of ..s */ std::string Path_Compact( const std::string & sRawPath, char slash ) @@ -336,17 +393,15 @@ std::string Path_Compact( const std::string & sRawPath, char slash ) return sPath; } -#define MAX_UNICODE_PATH 32768 -#define MAX_UNICODE_PATH_IN_UTF8 ( MAX_UNICODE_PATH * 4 ) /** Returns the path to the current DLL or exe */ -std::string GetThisModulePath() +std::string Path_GetThisModulePath() { // gets the path of vrclient.dll itself #ifdef WIN32 HMODULE hmodule = NULL; - ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(GetThisModulePath), &hmodule); + ::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(Path_GetThisModulePath), &hmodule ); wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH]; char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ]; @@ -361,7 +416,7 @@ std::string GetThisModulePath() #elif defined( OSX ) || defined( LINUX ) // get the addr of a function in vrclient.so and then ask the dlopen system about it Dl_info info; - dladdr( (void *)GetThisModulePath, &info ); + dladdr( (void *)Path_GetThisModulePath, &info ); return info.dli_fname; #endif @@ -379,19 +434,44 @@ bool Path_IsDirectory( const std::string & sPath ) sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() ); // see if the specified path actually exists. + +#if defined(POSIX) struct stat buf; - if ( stat ( sFixedPath.c_str(), &buf ) == -1) + if ( stat( sFixedPath.c_str(), &buf ) == -1 ) { return false; } -#if defined(LINUX) +#if defined( LINUX ) || defined( OSX ) return S_ISDIR( buf.st_mode ); #else - return ( buf.st_mode & _S_IFDIR ) != 0; + return (buf.st_mode & _S_IFDIR) != 0; +#endif + +#else + struct _stat buf; + std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() ); + if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 ) + { + return false; + } + + return (buf.st_mode & _S_IFDIR) != 0; #endif } +/** returns true if the specified path represents an app bundle */ +bool Path_IsAppBundle( const std::string & sPath ) +{ +#if defined(OSX) + NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ]; + bool bisAppBundle = ( nullptr != bundle ); + [ bundle release ]; + return bisAppBundle; +#else + return false; +#endif +} //----------------------------------------------------------------------------- // Purpose: returns true if the the path exists @@ -402,11 +482,20 @@ bool Path_Exists( const std::string & sPath ) if( sFixedPath.empty() ) return false; +#if defined( WIN32 ) + struct _stat buf; + std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() ); + if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 ) + { + return false; + } +#else struct stat buf; if ( stat ( sFixedPath.c_str(), &buf ) == -1) { return false; } +#endif return true; } @@ -475,11 +564,9 @@ unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize #if defined( POSIX ) f = fopen( strFilename.c_str(), "rb" ); #else - errno_t err = fopen_s(&f, strFilename.c_str(), "rb"); - if ( err != 0 ) - { - f = NULL; - } + std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); + // the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s + f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO ); #endif unsigned char* buf = NULL; @@ -508,6 +595,68 @@ unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize return buf; } +uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize ) +{ + FILE *f; +#if defined( POSIX ) + f = fopen( strFilename.c_str(), "rb" ); +#else + std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); + errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" ); + if ( err != 0 ) + { + f = NULL; + } +#endif + + uint32_t unSizeToReturn = 0; + + if ( f != NULL ) + { + fseek( f, 0, SEEK_END ); + uint32_t size = (uint32_t)ftell( f ); + fseek( f, 0, SEEK_SET ); + + if ( size > unSize || !pBuffer ) + { + unSizeToReturn = (uint32_t)size; + } + else + { + if ( fread( pBuffer, size, 1, f ) == 1 ) + { + unSizeToReturn = (uint32_t)size; + } + } + + fclose( f ); + } + + return unSizeToReturn; +} + +bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize) +{ + FILE *f; +#if defined( POSIX ) + f = fopen(strFilename.c_str(), "wb"); +#else + std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); + errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" ); + if (err != 0) + { + f = NULL; + } +#endif + + size_t written = 0; + if (f != NULL) { + written = fwrite(pData, sizeof(unsigned char), nSize, f); + fclose(f); + } + + return written = nSize ? true : false; +} std::string Path_ReadTextFile( const std::string &strFilename ) { @@ -520,7 +669,7 @@ std::string Path_ReadTextFile( const std::string &strFilename ) return ""; // convert CRLF -> LF - int outsize = 1; + size_t outsize = 1; for (int i=1; i < size; i++) { if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF @@ -529,7 +678,7 @@ std::string Path_ReadTextFile( const std::string &strFilename ) buf[outsize++] = buf[i]; // just copy } - std::string ret((char *)buf, (char *)(buf + outsize)); + std::string ret((char *)buf, outsize); delete[] buf; return ret; } @@ -541,7 +690,8 @@ bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pch #if defined( POSIX ) f = fopen( strFilename.c_str(), "w" ); #else - errno_t err = fopen_s(&f, strFilename.c_str(), "w"); + std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); + errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" ); if ( err != 0 ) { f = NULL; @@ -557,4 +707,113 @@ bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pch } return ok; -} \ No newline at end of file +} + +bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData ) +{ + std::string strTmpFilename = strFilename + ".tmp"; + + if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) ) + return false; + + // Platform specific atomic file replacement +#if defined( _WIN32 ) + std::wstring wsFilename = UTF8to16( strFilename.c_str() ); + std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() ); + if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) ) + { + // if we couldn't ReplaceFile, try a non-atomic write as a fallback + if ( !Path_WriteStringToTextFile( strFilename, pchData ) ) + return false; + } +#elif defined( POSIX ) + if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 ) + return false; +#else +#error Do not know how to write atomic file +#endif + + return true; +} + + +#if defined(WIN32) +#define FILE_URL_PREFIX "file:///" +#else +#define FILE_URL_PREFIX "file://" +#endif + +// ---------------------------------------------------------------------------------------------------------------------------- +// Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL) +// ---------------------------------------------------------------------------------------------------------------------------- +std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ) +{ + if ( !strnicmp( sRelativePath.c_str(), "http://", 7 ) + || !strnicmp( sRelativePath.c_str(), "https://", 8 ) + || !strnicmp( sRelativePath.c_str(), "file://", 7 ) ) + { + return sRelativePath; + } + else + { + std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath ); + if ( sAbsolute.empty() ) + return sAbsolute; + return std::string( FILE_URL_PREFIX ) + sAbsolute; + } +} + +// ----------------------------------------------------------------------------------------------------- +// Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned +// ----------------------------------------------------------------------------------------------------- +std::string Path_UrlToFilePath( const std::string & sFileUrl ) +{ + if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) ) + { + return sFileUrl.c_str() + strlen( FILE_URL_PREFIX ); + } + else + { + return ""; + } +} + + +// ----------------------------------------------------------------------------------------------------- +// Purpose: Returns the root of the directory the system wants us to store user documents in +// ----------------------------------------------------------------------------------------------------- +std::string GetUserDocumentsPath() +{ +#if defined( WIN32 ) + WCHAR rwchPath[MAX_PATH]; + + if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) ) + { + return ""; + } + + // Convert the path to UTF-8 and store in the output + std::string sUserPath = UTF16to8( rwchPath ); + + return sUserPath; +#elif defined( OSX ) + @autoreleasepool { + NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES ); + if ( [paths count] == 0 ) + { + return ""; + } + + return [[paths objectAtIndex:0] UTF8String]; + } +#elif defined( LINUX ) + // @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste + const char *pchHome = getenv( "HOME" ); + if ( pchHome == NULL ) + { + return ""; + } + return pchHome; +#endif +} + diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h index c38ec5612..7c34a7175 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h @@ -2,6 +2,7 @@ #pragma once #include +#include /** Returns the path (including filename) to the current executable */ std::string Path_GetExecutablePath(); @@ -13,7 +14,7 @@ std::string Path_GetWorkingDirectory(); bool Path_SetWorkingDirectory( const std::string & sPath ); /** returns the path (including filename) of the current shared lib or DLL */ -std::string Path_GetModulePath(); +std::string Path_GetThisModulePath(); /** Returns the specified path without its filename. * If slash is unspecified the native path separator of the current platform @@ -27,6 +28,9 @@ std::string Path_StripDirectory( const std::string & sPath, char slash = 0 ); * If there is a path the path is left intact. */ std::string Path_StripExtension( const std::string & sPath ); +/** returns just extension of the provided filename (if any). */ +std::string Path_GetExtension( const std::string & sPath ); + /** Returns true if the path is absolute */ bool Path_IsAbsolute( const std::string & sPath ); @@ -60,11 +64,14 @@ std::string Path_Join( * will be used. */ std::string Path_Compact( const std::string & sRawPath, char slash = 0 ); +//** Removed trailing slashes */ +std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash = 0 ); + /** returns true if the specified path exists and is a directory */ bool Path_IsDirectory( const std::string & sPath ); -/** Returns the path to the current DLL or exe */ -std::string GetThisModulePath(); +/** returns true if the specified path represents an app bundle */ +bool Path_IsAppBundle( const std::string & sPath ); /** returns true if the the path exists */ bool Path_Exists( const std::string & sPath ); @@ -75,11 +82,31 @@ std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartD /** Path operations to read or write text/binary files */ unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize ); +uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize ); +bool Path_WriteBinaryFile( const std::string &strFilename, unsigned char *pData, unsigned nSize ); std::string Path_ReadTextFile( const std::string &strFilename ); bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData ); +bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData ); + +/** Returns a file:// url for paths, or an http or https url if that's what was provided */ +std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ); + +/** Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned */ +std::string Path_UrlToFilePath( const std::string & sFileUrl ); + +/** Returns the root of the directory the system wants us to store user documents in */ +std::string GetUserDocumentsPath(); + +#ifndef MAX_UNICODE_PATH + #define MAX_UNICODE_PATH 32767 +#endif + +#ifndef MAX_UNICODE_PATH_IN_UTF8 + #define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4) +#endif //----------------------------------------------------------------------------- -#if defined(_WIN32) +#if defined(WIN32) #define DYNAMIC_LIB_EXT ".dll" #ifdef _WIN64 #define PLATSUBDIR "win64" @@ -91,8 +118,12 @@ bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pch #define PLATSUBDIR "osx32" #elif defined(LINUX) #define DYNAMIC_LIB_EXT ".so" +#if defined( LINUX32 ) #define PLATSUBDIR "linux32" #else +#define PLATSUBDIR "linux64" +#endif +#else #warning "Unknown platform for PLATSUBDIR" #define PLATSUBDIR "unknown_platform" #endif diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp new file mode 100644 index 000000000..6166db483 --- /dev/null +++ b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp @@ -0,0 +1,437 @@ +//========= Copyright Valve Corporation ============// +#include "strtools.h" +#include +#include +#include + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool StringHasPrefix( const std::string & sString, const std::string & sPrefix ) +{ + return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() ); +} + +bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix ) +{ + return 0 == strncmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() ); +} + + +bool StringHasSuffix( const std::string &sString, const std::string &sSuffix ) +{ + size_t cStrLen = sString.length(); + size_t cSuffixLen = sSuffix.length(); + + if ( cSuffixLen > cStrLen ) + return false; + + std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen ); + + return 0 == stricmp( sStringSuffix.c_str(), sSuffix.c_str() ); +} + +bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix ) +{ + size_t cStrLen = sString.length(); + size_t cSuffixLen = sSuffix.length(); + + if ( cSuffixLen > cStrLen ) + return false; + + std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen ); + + return 0 == strncmp( sStringSuffix.c_str(), sSuffix.c_str(),cSuffixLen ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +std::string UTF16to8(const wchar_t * in) +{ + std::string out; + unsigned int codepoint = 0; + for ( ; in && *in != 0; ++in ) + { + if (*in >= 0xd800 && *in <= 0xdbff) + codepoint = ((*in - 0xd800) << 10) + 0x10000; + else + { + if (*in >= 0xdc00 && *in <= 0xdfff) + codepoint |= *in - 0xdc00; + else + codepoint = *in; + + if (codepoint <= 0x7f) + out.append(1, static_cast(codepoint)); + else if (codepoint <= 0x7ff) + { + out.append(1, static_cast(0xc0 | ((codepoint >> 6) & 0x1f))); + out.append(1, static_cast(0x80 | (codepoint & 0x3f))); + } + else if (codepoint <= 0xffff) + { + out.append(1, static_cast(0xe0 | ((codepoint >> 12) & 0x0f))); + out.append(1, static_cast(0x80 | ((codepoint >> 6) & 0x3f))); + out.append(1, static_cast(0x80 | (codepoint & 0x3f))); + } + else + { + out.append(1, static_cast(0xf0 | ((codepoint >> 18) & 0x07))); + out.append(1, static_cast(0x80 | ((codepoint >> 12) & 0x3f))); + out.append(1, static_cast(0x80 | ((codepoint >> 6) & 0x3f))); + out.append(1, static_cast(0x80 | (codepoint & 0x3f))); + } + codepoint = 0; + } + } + return out; +} + +std::wstring UTF8to16(const char * in) +{ + std::wstring out; + unsigned int codepoint = 0; + int following = 0; + for ( ; in && *in != 0; ++in ) + { + unsigned char ch = *in; + if (ch <= 0x7f) + { + codepoint = ch; + following = 0; + } + else if (ch <= 0xbf) + { + if (following > 0) + { + codepoint = (codepoint << 6) | (ch & 0x3f); + --following; + } + } + else if (ch <= 0xdf) + { + codepoint = ch & 0x1f; + following = 1; + } + else if (ch <= 0xef) + { + codepoint = ch & 0x0f; + following = 2; + } + else + { + codepoint = ch & 0x07; + following = 3; + } + if (following == 0) + { + if (codepoint > 0xffff) + { + out.append(1, static_cast(0xd800 + (codepoint >> 10))); + out.append(1, static_cast(0xdc00 + (codepoint & 0x03ff))); + } + else + out.append(1, static_cast(codepoint)); + codepoint = 0; + } + } + return out; +} + + +void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource ) +{ + pchBuffer[ unBufferSizeBytes - 1 ] = '\0'; + strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 ); +} + + +// -------------------------------------------------------------------- +// Purpose: converts a string to upper case +// -------------------------------------------------------------------- +std::string StringToUpper( const std::string & sString ) +{ + std::string sOut; + sOut.reserve( sString.size() + 1 ); + for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ ) + { + sOut.push_back( (char)toupper( *i ) ); + } + + return sOut; +} + + +// -------------------------------------------------------------------- +// Purpose: converts a string to lower case +// -------------------------------------------------------------------- +std::string StringToLower( const std::string & sString ) +{ + std::string sOut; + sOut.reserve( sString.size() + 1 ); + for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ ) + { + sOut.push_back( (char)tolower( *i ) ); + } + + return sOut; +} + + +uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen ) +{ + uint32_t unLen = (uint32_t)sValue.length() + 1; + if( !pchBuffer || !unBufferLen ) + return unLen; + + if( unBufferLen < unLen ) + { + pchBuffer[0] = '\0'; + } + else + { + memcpy( pchBuffer, sValue.c_str(), unLen ); + } + + return unLen; +} + +void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen ) +{ + sDest.resize( unBufferLen + 1 ); + memcpy( const_cast< char* >( sDest.c_str() ), pchBuffer, unBufferLen ); + const_cast< char* >( sDest.c_str() )[ unBufferLen ] = '\0'; +} + +/** Returns a std::string from a uint64_t */ +std::string Uint64ToString( uint64_t ulValue ) +{ + char buf[ 22 ]; +#if defined( _WIN32 ) + sprintf_s( buf, "%llu", ulValue ); +#else + snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue ); +#endif + return buf; +} + + +/** returns a uint64_t from a string */ +uint64_t StringToUint64( const std::string & sValue ) +{ + return strtoull( sValue.c_str(), NULL, 0 ); +} + +//----------------------------------------------------------------------------- +// Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15. +//----------------------------------------------------------------------------- +char cIntToHexDigit( int nValue ) +{ + //Assert( nValue >= 0 && nValue <= 15 ); + return "0123456789ABCDEF"[ nValue & 15 ]; +} + +//----------------------------------------------------------------------------- +// Purpose: Helper for converting a hex char value to numeric, return -1 if the char +// is not a valid hex digit. +//----------------------------------------------------------------------------- +int iHexCharToInt( char cValue ) +{ + int32_t iValue = cValue; + if ( (uint32_t)( iValue - '0' ) < 10 ) + return iValue - '0'; + + iValue |= 0x20; + if ( (uint32_t)( iValue - 'a' ) < 6 ) + return iValue - 'a' + 10; + + return -1; +} + +//----------------------------------------------------------------------------- +// Purpose: Internal implementation of encode, works in the strict RFC manner, or +// with spaces turned to + like HTML form encoding. +//----------------------------------------------------------------------------- +void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace ) +{ + //AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" ); + + int iDestPos = 0; + for ( int i=0; i < nSourceLen; ++i ) + { + // worst case we need 3 additional chars + if( (iDestPos+3) > nDestLen ) + { + pchDest[0] = '\0'; +// AssertMsg( false, "Target buffer too short\n" ); + return; + } + + // We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped. + // These are the characters allowed by both the original RFC 1738 and the latest RFC 3986. + // Current specs also allow '~', but that is forbidden under original RFC 1738. + if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' ) + && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.' + ) + { + if ( bUsePlusForSpace && pchSource[i] == ' ' ) + { + pchDest[iDestPos++] = '+'; + } + else + { + pchDest[iDestPos++] = '%'; + uint8_t iValue = pchSource[i]; + if ( iValue == 0 ) + { + pchDest[iDestPos++] = '0'; + pchDest[iDestPos++] = '0'; + } + else + { + char cHexDigit1 = cIntToHexDigit( iValue % 16 ); + iValue /= 16; + char cHexDigit2 = cIntToHexDigit( iValue ); + pchDest[iDestPos++] = cHexDigit2; + pchDest[iDestPos++] = cHexDigit1; + } + } + } + else + { + pchDest[iDestPos++] = pchSource[i]; + } + } + + if( (iDestPos+1) > nDestLen ) + { + pchDest[0] = '\0'; + //AssertMsg( false, "Target buffer too short to terminate\n" ); + return; + } + + // Null terminate + pchDest[iDestPos++] = 0; +} + + +//----------------------------------------------------------------------------- +// Purpose: Internal implementation of decode, works in the strict RFC manner, or +// with spaces turned to + like HTML form encoding. +// +// Returns the amount of space used in the output buffer. +//----------------------------------------------------------------------------- +size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace ) +{ + if ( nDecodeDestLen < nEncodedSourceLen ) + { + //AssertMsg( false, "V_URLDecode needs a dest buffer at least as large as the source" ); + return 0; + } + + int iDestPos = 0; + for( int i=0; i < nEncodedSourceLen; ++i ) + { + if ( bUsePlusForSpace && pchEncodedSource[i] == '+' ) + { + pchDecodeDest[ iDestPos++ ] = ' '; + } + else if ( pchEncodedSource[i] == '%' ) + { + // Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that + + // First make sure we have 2 more chars + if ( i < nEncodedSourceLen - 2 ) + { + char cHexDigit1 = pchEncodedSource[i+1]; + char cHexDigit2 = pchEncodedSource[i+2]; + + // Turn the chars into a hex value, if they are not valid, then we'll + // just place the % and the following two chars direct into the string, + // even though this really shouldn't happen, who knows what bad clients + // may do with encoding. + bool bValid = false; + int iValue = iHexCharToInt( cHexDigit1 ); + if ( iValue != -1 ) + { + iValue *= 16; + int iValue2 = iHexCharToInt( cHexDigit2 ); + if ( iValue2 != -1 ) + { + iValue += iValue2; + pchDecodeDest[ iDestPos++ ] = (char)iValue; + bValid = true; + } + } + + if ( !bValid ) + { + pchDecodeDest[ iDestPos++ ] = '%'; + pchDecodeDest[ iDestPos++ ] = cHexDigit1; + pchDecodeDest[ iDestPos++ ] = cHexDigit2; + } + } + + // Skip ahead + i += 2; + } + else + { + pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i]; + } + } + + // We may not have extra room to NULL terminate, since this can be used on raw data, but if we do + // go ahead and do it as this can avoid bugs. + if ( iDestPos < nDecodeDestLen ) + { + pchDecodeDest[iDestPos] = 0; + } + + return (size_t)iDestPos; +} + +//----------------------------------------------------------------------------- +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +//----------------------------------------------------------------------------- +void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ) +{ + return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +//----------------------------------------------------------------------------- +size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ) +{ + return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true ); +} + +//----------------------------------------------------------------------------- +void V_StripExtension( std::string &in ) +{ + // Find the last dot. If it's followed by a dot or a slash, then it's part of a + // directory specifier like ../../somedir/./blah. + std::string::size_type test = in.rfind( '.' ); + if ( test != std::string::npos ) + { + // This handles things like ".\blah" or "c:\my@email.com\abc\def\geh" + // Which would otherwise wind up with "" and "c:\my@email", respectively. + if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test ) + { + in.resize( test ); + } + } +} + diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h new file mode 100644 index 000000000..b69ef15dc --- /dev/null +++ b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h @@ -0,0 +1,130 @@ +//========= Copyright Valve Corporation ============// +#pragma once + +#include +#include +#include + +/** returns true if the string has the prefix */ +bool StringHasPrefix( const std::string & sString, const std::string & sPrefix ); +bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix ); + +/** returns if the string has the suffix */ +bool StringHasSuffix( const std::string &sString, const std::string &sSuffix ); +bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix ); + +/** converts a UTF-16 string to a UTF-8 string */ +std::string UTF16to8(const wchar_t * in); + +/** converts a UTF-8 string to a UTF-16 string */ +std::wstring UTF8to16(const char * in); +#define Utf16FromUtf8 UTF8to16 + +/** safely copy a string into a buffer */ +void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource ); +template< size_t bufferSize > +void strcpy_safe( char (& buffer) [ bufferSize ], const char *pchSource ) +{ + strcpy_safe( buffer, bufferSize, pchSource ); +} + + +/** converts a string to upper case */ +std::string StringToUpper( const std::string & sString ); + +/** converts a string to lower case */ +std::string StringToLower( const std::string & sString ); + +// we stricmp (from WIN) but it isn't POSIX - OSX/LINUX have strcasecmp so just inline bridge to it +#if defined( OSX ) || defined( LINUX ) +#include +inline int stricmp(const char *pStr1, const char *pStr2) { return strcasecmp(pStr1,pStr2); } +#ifndef _stricmp +#define _stricmp stricmp +#endif +inline int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen ) { return strncasecmp( pStr1,pStr2, unBufferLen ); } +#define _strnicmp strnicmp + +#ifndef _vsnprintf_s +#define _vsnprintf_s vsnprintf +#endif + +#define _TRUNCATE ((size_t)-1) + +#endif + +#if defined( OSX ) +// behaviors ensure NULL-termination at least as well as _TRUNCATE does, but +// wcsncpy_s/strncpy_s can non-NULL-terminate, wcslcpy/strlcpy can not. +inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) +{ + return wcslcpy(strDest, strSource, numberOfElements); +} + +inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) +{ + return strlcpy(strDest, strSource, numberOfElements); +} + +#endif + +#if defined( LINUX ) +// this implementation does not return whether or not the destination was +// truncated, but that is straightforward to fix if anybody actually needs the +// return code. +#include "string.h" +inline void wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) +{ + wcsncpy(strDest, strSource, numberOfElements); + strDest[numberOfElements-1] = '\0'; +} + +inline void strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) +{ + strncpy(strDest, strSource, numberOfElements); + strDest[numberOfElements-1] = '\0'; +} + +#endif + +#if defined( _WIN32 ) && _MSC_VER < 1800 +inline uint64_t strtoull(const char *str, char **endptr, int base) { return _strtoui64( str, endptr, base ); } +#endif + +/* Handles copying a std::string into a buffer as would be provided in an API */ +uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen ); + +/* Handles copying a buffer into an std::string and auto adds null terminator */ +void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen ); + +/** Returns a std::string from a uint64_t */ +std::string Uint64ToString( uint64_t ulValue ); + +/** returns a uint64_t from a string */ +uint64_t StringToUint64( const std::string & sValue ); + +//----------------------------------------------------------------------------- +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +//----------------------------------------------------------------------------- +void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ); + +//----------------------------------------------------------------------------- +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// This version of the call isn't a strict RFC implementation, but uses + for space as is +// the standard in HTML form encoding, despite it not being part of the RFC. +// +// Dest buffer should be at least as large as source buffer to guarantee room for decode. +// Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. +//----------------------------------------------------------------------------- +size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); + +//----------------------------------------------------------------------------- +// Purpose: strip extension from a path +//----------------------------------------------------------------------------- +void V_StripExtension( std::string &in ); + +