Skip to content

Commit

Permalink
Merge pull request #26 from Kuurama/main
Browse files Browse the repository at this point in the history
Fix OpenXR hmd detection
  • Loading branch information
Umbranoxio committed Dec 17, 2023
2 parents 0a2608d + 6afca3a commit c7c406a
Showing 1 changed file with 43 additions and 34 deletions.
77 changes: 43 additions & 34 deletions ScoreSaber/Core/Utils/OpenXRManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -24,13 +28,13 @@ internal static unsafe class OpenXRManager {

// 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
Expand All @@ -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;

Expand All @@ -68,7 +72,6 @@ private struct XrSystemGetInfo {
}

private static string AttemptGetHmd() {

try {
var openXRLoaderBaseAddress = GetModuleHandle("openxr_loader");

Expand All @@ -77,43 +80,49 @@ private struct XrSystemGetInfo {
}

// Get our xrInstance
var xrGetCurrentInstance = Marshal.GetDelegateForFunctionPointer<xrGetCurrentInstanceDelegate>(openXRLoaderBaseAddress + 0x38980);
var xrCurrentInstance = new IntPtr(*(long*)xrGetCurrentInstance());
var xrInstance = *(ulong*)new IntPtr((byte*)xrCurrentInstance.ToPointer() + 8);
var xrGetCurrentInstance = Marshal.GetDelegateForFunctionPointer<xrGetCurrentInstanceDelegate>(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<xrGetSystemDelegate>(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<xrGetInstanceProcAddrDelegate>(openXRLoaderBaseAddress + 0x5AE2);
IntPtr xrGetSystemPropertiesAddr;
ulong result = xrGetInstanceProcAddr(xrInstance, new StringBuilder("xrGetSystemProperties"), &xrGetSystemPropertiesAddr);
var getSystemPropertiesAddr = Marshal.GetDelegateForFunctionPointer<xrGetSystemPropertiesDelegate>(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;
}

}
}
}
}

0 comments on commit c7c406a

Please sign in to comment.