From 6afca3a7b30b6ff27a7d6a71a8b5f46f34d6e7af Mon Sep 17 00:00:00 2001 From: Kuurama <74458092+Kuurama@users.noreply.github.com> Date: Sun, 10 Dec 2023 00:52:46 +0100 Subject: [PATCH] Fix OpenXR hmd detection --- ScoreSaber/Core/Utils/OpenXRManager.cs | 77 ++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/ScoreSaber/Core/Utils/OpenXRManager.cs b/ScoreSaber/Core/Utils/OpenXRManager.cs index b4b023b..957ddce 100644 --- a/ScoreSaber/Core/Utils/OpenXRManager.cs +++ b/ScoreSaber/Core/Utils/OpenXRManager.cs @@ -6,10 +6,14 @@ namespace ScoreSaber.Core.Utils { internal static unsafe class OpenXRManager { - [DllImport("kernel32", CharSet = CharSet.Auto)] - private static extern IntPtr GetModuleHandle( - string lpModuleName); + private static extern IntPtr GetModuleHandle(string lpModuleName); + + [DllImport("openxr_loader", EntryPoint = "xrGetSystemProperties", CallingConvention = CallingConvention.Cdecl)] + private static extern ulong GetSystemProperties(long* instance, ulong systemId, XrSystemProperties* properties); + + [DllImport("openxr_loader", EntryPoint = "xrGetSystem", CallingConvention = CallingConvention.Cdecl)] + private static extern ulong GetSystem(long* instance, XrSystemGetInfo* getInfo, ulong* systemId); // delegate for xrGetInstanceProcAddr() https://registry.khronos.org/OpenXR/specs/1.0/man/html/xrGetInstanceProcAddr.html private delegate ulong xrGetInstanceProcAddrDelegate(ulong instance, StringBuilder name, IntPtr* function); @@ -24,13 +28,13 @@ private static extern IntPtr GetModuleHandle( // XrSystemProperties structure https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrSystemProperties.html private struct XrSystemProperties { - public ulong type; // 64 bit - public void* next; // 64 bit - public ulong systemId; // 64 bit - public int vendorId; // 32 bit - public fixed byte systemName[XR_MAX_SYSTEM_NAME_SIZE]; - public XrSystemGraphicsProperties graphicsProperties; - public XrSystemTrackingProperties trackingProperties; + public ulong type; // 64 bit + public void* next; // 64 bit + public ulong systemId; // 64 bit + public int vendorId; // 32 bit + public fixed byte systemName[XR_MAX_SYSTEM_NAME_SIZE]; + public XrSystemGraphicsProperties graphicsProperties; + public XrSystemTrackingProperties trackingProperties; }; // XrSystemGraphicsProperties structure https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrSystemGraphicsProperties.html @@ -48,18 +52,18 @@ private struct XrSystemTrackingProperties { // XrSystemGetInfo structure https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrSystemGetInfo.html private struct XrSystemGetInfo { - public ulong type; // 64 bit - public void* next; // 64 bit - public ulong formFactor;// 64 bit + public ulong type; // 64 bit + public void* next; // 64 bit + public ulong formFactor; // 64 bit } // https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrFormFactor.html private const int XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY = 1; // https://registry.khronos.org/OpenXR/specs/1.0/man/html/XrStructureType.html - private const int XR_TYPE_SYSTEM_GET_INFO = 4; + private const int XR_TYPE_SYSTEM_GET_INFO = 4; private const int XR_TYPE_SYSTEM_PROPERTIES = 5; - private const int XR_MAX_SYSTEM_NAME_SIZE = 256; + private const int XR_MAX_SYSTEM_NAME_SIZE = 256; internal static string hmdName = null; @@ -68,7 +72,6 @@ internal static void Initialize() { } private static string AttemptGetHmd() { - try { var openXRLoaderBaseAddress = GetModuleHandle("openxr_loader"); @@ -77,43 +80,49 @@ private static string AttemptGetHmd() { } // Get our xrInstance - var xrGetCurrentInstance = Marshal.GetDelegateForFunctionPointer(openXRLoaderBaseAddress + 0x38980); - var xrCurrentInstance = new IntPtr(*(long*)xrGetCurrentInstance()); - var xrInstance = *(ulong*)new IntPtr((byte*)xrCurrentInstance.ToPointer() + 8); + var xrGetCurrentInstance = Marshal.GetDelegateForFunctionPointer(openXRLoaderBaseAddress + 0x39480); + var xrCurrentInstance = new IntPtr(*(long*)xrGetCurrentInstance()); + var xrInstance = (long*)*(ulong*)new IntPtr((byte*)xrCurrentInstance.ToPointer() + 8); // Get our systemId var info = new XrSystemGetInfo { - type = XR_TYPE_SYSTEM_GET_INFO, + type = XR_TYPE_SYSTEM_GET_INFO, formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY }; - ulong systemId = 0; - var xrGetSystem = Marshal.GetDelegateForFunctionPointer(openXRLoaderBaseAddress + 0x2D0B); - var getSystemResult = xrGetSystem(xrInstance, &info, &systemId); + ulong systemId = 0; + var getSystemResult = GetSystem(xrInstance, &info, &systemId); - // Get our system properties - var xrGetInstanceProcAddr = Marshal.GetDelegateForFunctionPointer(openXRLoaderBaseAddress + 0x5AE2); - IntPtr xrGetSystemPropertiesAddr; - ulong result = xrGetInstanceProcAddr(xrInstance, new StringBuilder("xrGetSystemProperties"), &xrGetSystemPropertiesAddr); - var getSystemPropertiesAddr = Marshal.GetDelegateForFunctionPointer(xrGetSystemPropertiesAddr); + if (getSystemResult != 0) { + Plugin.Log.Info($"Failed to get system from OpenXR {getSystemResult}"); + return null; + } + // Get our system properties XrSystemProperties properties; properties.type = XR_TYPE_SYSTEM_PROPERTIES; - result = getSystemPropertiesAddr(xrInstance, systemId, &properties); + var result = GetSystemProperties(xrInstance, systemId, &properties); + + if (result != 0) { + Plugin.Log.Info($"Failed to get system properties from OpenXR {result}"); + return null; + } + + var systemNameStrBuilder = new StringBuilder(); - var systemName = ""; for (int charIndex = 0; charIndex < XR_MAX_SYSTEM_NAME_SIZE; charIndex++) { if (properties.systemName[charIndex] == 0) { break; } - systemName += ((char)properties.systemName[charIndex]); + + systemNameStrBuilder.Append(((char)properties.systemName[charIndex])); } - return systemName; + + return systemNameStrBuilder.ToString(); } catch (Exception ex) { Plugin.Log.Info($"Failed to get hmd from OpenXR {ex}"); return null; } - } } -} +} \ No newline at end of file