Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ValveSoftware/openvr.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Leiby <aaronl@valvesoftware.com>2022-08-18 20:39:17 +0300
committerAaron Leiby <aaronl@valvesoftware.com>2022-08-18 20:39:17 +0300
commit758906251fd932f59f50c510d8c375aa34229887 (patch)
tree3990d5c6b840aeec3c6db39cc9f64947b89660c0
parent4c85abcb7f7f1f02adaf3812018c99fc593bc341 (diff)
Merging using vr_steamvr_rel_to_sdk_release
Integration via vr_steamvr_main_to_rel of: Change 7445792 by aaronl: [ steamvr - vrsdk ] * Adding the scripts we use to codegen C# and C bindings to the public SDK. [git-p4: depot-paths = "//vr/steamvr/sdk_release/": change = 7445965]
-rw-r--r--codegen/README.md36
-rwxr-xr-xcodegen/api_shared.py1057
-rwxr-xr-xcodegen/openvr_capi.cpp.py88
-rwxr-xr-xcodegen/openvr_capi.h.py290
-rwxr-xr-xcodegen/openvr_interop.cs.py597
5 files changed, 2068 insertions, 0 deletions
diff --git a/codegen/README.md b/codegen/README.md
new file mode 100644
index 0000000..a042236
--- /dev/null
+++ b/codegen/README.md
@@ -0,0 +1,36 @@
+Codegen
+---
+The OpenVR SDK ships with metadata for its headers at [openvr_api.json](https://github.com/ValveSoftware/openvr/blob/master/headers/openvr_api.json).
+
+This can be used to generate bindings for other languages such as C or C#.
+
+We include the scripts we use to generate the existing bindings that ship as part of the SDK here.
+
+### Usage
+
+These scripts assume Python 2.7.
+
+We use [Artistic Style](http://astyle.sourceforge.net/) for formatting.
+
+#### C# bindings:
+
+```
+python openvr_interop.cs.py > openvr_interop.cs
+astyle -T -O openvr_interop.cs
+```
+
+#### C bindings:
+
+```
+python openvr_capi.h.py > openvr_capi.h
+astyle -T -O openvr_capi.h
+```
+
+#### C implementation:
+
+This file is build into openvr_api.dll and is used by both the C and C# bindings.
+
+```
+python openvr_capi.cpp.py > openvr_capi.cpp
+astyle -T -O openvr_capi.cpp
+``` \ No newline at end of file
diff --git a/codegen/api_shared.py b/codegen/api_shared.py
new file mode 100755
index 0000000..af064d6
--- /dev/null
+++ b/codegen/api_shared.py
@@ -0,0 +1,1057 @@
+import json
+import sys
+import operator
+from functools import reduce
+
+structlist = {}
+typedeflist = {}
+enumlist = {}
+
+# These are not exported to the json, so we just maintain the small subset here by hand for now.
+structparents = {
+ 'VRTextureWithPose_t' : 'Texture_t',
+ 'VRTextureWithDepth_t' : 'Texture_t',
+ 'VRTextureWithPoseAndDepth_t' : 'VRTextureWithPose_t' }
+
+structindices = {}
+
+def loadfile(filename, ns):
+ with open(filename) as data_file:
+ data = json.load(data_file)
+
+ i = 0
+ for struct in data['structs']:
+ if(len(struct) > 0 and len(struct['struct'])):
+ structname = struct['struct']
+ structlist[structname] = 'struct'
+ structindices[getclasswithoutnamespace(structname)] = i
+ i += 1
+
+ for typedef in data['typedefs']:
+ if(len(typedef) > 0 and len(typedef['typedef'])):
+ typedeflist[typedef['typedef']] = typedef['type']
+ for enum in data['enums']:
+ enumname = enum['enumname']
+ namespace = getnamespace(enumname)
+ if(len(enum) > 0 and len(enum['enumname'])):
+ enumlist[enum['enumname'].replace('::','_')] = enum['enumname']
+ return data
+
+
+def paramshavelength(params, paramname):
+ checkname = paramname[1:]
+ for param in params:
+ name = param['paramname']
+ name = name[3:len(name)-4]
+ sys.stdout.write ('// ' + name + ' ' + checkname + '\n');
+ if(name == checkname):
+ return True
+ return False
+
+def calculateinteropmethodname(classname, methodname):
+ return classname.replace('vr::', 'VR::').replace('::', '_') + '_' + methodname
+
+def unmanagedtype(thetype):
+ if(thetype == 'float'):
+ return 'R4'
+ if(thetype == 'double'):
+ return 'R8'
+ if(thetype == 'char'):
+ return 'I1'
+ if(thetype == 'byte'):
+ return 'U1'
+ if(thetype == 'ulong'):
+ return 'U8'
+ if(thetype == 'uint'):
+ return 'U4'
+ if(thetype == 'CSteamID'): # Special case for CSteamID which is a complex C def but is 64-bits.
+ return 'U8'
+ return 'Struct'
+
+def ctype(thetype):
+ thetype = thetype.replace('vr::','')
+ if(thetype[0:6] == 'const '):
+ thetype = thetype[6:]
+ if(thetype[0:6] == 'class '): # for C replaces classes by pointers
+ thetype = 'intptr_t'
+ if(thetype == 'ulong'):
+ return 'unsigned long long'
+ if(thetype == 'uint'):
+ return 'unsigned long'
+ return thetype
+
+def striparraysuffix(thetype):
+ if(thetype[len(thetype) - 1] == ']'):
+ thetype = thetype[0:thetype.find('[')-1]
+ if(thetype == '_Bool'):
+ thetype = 'bool'
+ return thetype
+
+def converttype(thetype):
+ if(thetype[0:11] == 'struct vr::'):
+ thetype = thetype[11:]
+ if(thetype[0:17] == 'const struct vr::'):
+ thetype = thetype[17:]
+ if(thetype[0:10] == 'class vr::'):
+ thetype = thetype[10:]
+ if(thetype == 'const char *const'):
+ thetype = 'string'
+ #thetype = thetype.replace('::', '_')
+ thetypewithnamespace = thetype
+ thetype = getclasswithoutnamespace(thetype)
+ if(thetype[0:6] == 'const '):
+ thetype = thetype[6:]
+ if(thetype == 'class CSteamID'):
+ thetype = 'ulong'
+ if(thetype == 'uint8'):
+ thetype = 'byte'
+ if(thetype == 'uint8_t'):
+ thetype = 'byte'
+ if(thetype == 'unsigned short'):
+ thetype = 'ushort'
+ if(thetype == 'unsigned char'):
+ thetype = 'byte'
+ #if(thetype == 'unsigned int'):
+ # thetype = 'uint'
+ if(thetype == 'uint16'):
+ thetype = 'ushort'
+ if(thetype == 'uint16_t'):
+ thetype = 'ushort'
+ if(thetype == 'uint32'):
+ thetype = 'uint'
+ if(thetype == 'uint32_t'):
+ thetype = 'uint'
+ if(thetype == 'uint64'):
+ thetype = 'ulong'
+ if(thetype == 'short'):
+ thetype = 'short'
+ if(thetype == 'int32'):
+ thetype = 'int'
+ if(thetype == 'int32_t'):
+ thetype = 'int'
+ if(thetype == 'int64'):
+ thetype = 'long'
+ if(thetype == 'uint64_t'):
+ thetype = 'ulong'
+ if(thetype == '_Bool'):
+ thetype = 'bool'
+ if(thetype == 'char *'):
+ thetype = 'string'
+ if(thetype == 'char **'):
+ thetype = 'string'
+ if(thetype == 'void *'):
+ thetype = 'IntPtr'
+ if(thetype == 'byte *'):
+ thetype = 'IntPtr'
+ if(thetype == 'uint8 *'):
+ thetype = 'IntPtr'
+ if(thetype == 'T *'):
+ thetype = 'IntPtr'
+ if(thetype == 'func_t'):
+ thetype = 'IntPtr'
+ if(thetype == 'RenderModel_t *'):
+ thetype = 'IntPtr'
+ if(thetype == 'RenderModel_TextureMap_t *'):
+ thetype = 'IntPtr'
+ if(thetype == 'struct VkPhysicalDevice_T *'):
+ thetype = 'IntPtr'
+ if(thetype == 'struct VkInstance_T *'):
+ thetype = 'IntPtr'
+ if(thetype == 'SteamLeaderboard_t'):
+ thetype = 'ulong'
+ if(thetype == 'SteamLeaderboardEntries_t'):
+ thetype = 'ulong'
+ if(thetype == 'ScreenshotHandle'):
+ thetype = 'uint'
+ if(thetype == 'AudioPlayback_Status'):
+ thetype = 'int'
+ if(thetype == 'FriendsGroupID_t'):
+ thetype = 'char'
+ if(thetype == 'EOverlayToStoreFlag'):
+ thetype = 'char'
+ if(thetype == 'ESteamAPICallFailure'):
+ thetype = 'int'
+ if(thetype == 'EGamepadTextInputMode'):
+ thetype = 'int'
+ if(thetype == 'EGamepadTextInputLineMode'):
+ thetype = 'int'
+ if(thetype == 'EUniverse'):
+ thetype = 'int'
+ if(thetype == 'ISteamHTMLSurface::EHTMLMouseButton'):
+ thetype = 'int'
+ if(thetype == 'ISteamHTMLSurface::EHTMLKeyModifiers'):
+ thetype = 'int'
+ if(thetype == 'SteamInventoryResult_t'):
+ thetype = 'int'
+ if(thetype == 'RTime32'):
+ thetype = 'ulong'
+ if(thetype == 'AccountID_t'):
+ thetype = 'uint'
+ if(thetype == 'AppId_t'):
+ thetype = 'uint'
+ if(thetype == 'VRComponentProperties'):
+ thetype = 'uint'
+ if(thetype == 'SteamAPICall_t'):
+ thetype = 'ulong'
+ if(thetype == 'UGCQueryHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'UGCUpdateHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'ClientUnifiedMessageHandle'):
+ thetype = 'ulong'
+ if(thetype == 'UGCFileWriteStreamHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'PublishedFileUpdateHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'SteamAPIWarningMessageHook_t'):
+ thetype = 'IntPtr'
+ if(thetype == 'SteamAPI_PostAPIResultInProcess_t'):
+ thetype = 'IntPtr'
+ if(thetype == 'SteamAPI_CheckCallbackRegistered_t'):
+ thetype = 'IntPtr'
+ if(thetype == 'class CGameID'):
+ thetype = 'ulong'
+ if(thetype == 'PublishedFileId_t'):
+ thetype = 'ulong'
+ if(thetype == 'UGCHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'SNetListenSocket_t'):
+ thetype = 'uint'
+ if(thetype == 'SNetSocket_t'):
+ thetype = 'uint'
+ if(thetype == 'TrackedDeviceIndex_t'):
+ thetype = 'uint'
+ if(thetype == 'VROverlayHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'PropertyTypeTag_t'):
+ thetype = 'uint'
+ if(thetype == 'PropertyContainerHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'SpatialAnchorHandle_t'):
+ thetype = 'uint'
+ if(thetype == 'DriverHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'VRActionHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'VRActionSetHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'VRInputValueHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'VRInputOriginHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'PathHandle_t'):
+ thetype = 'ulong'
+ if(thetype == 'VRNotificationId'):
+ thetype = 'uint'
+ if(thetype == 'TextureID_t'):
+ thetype = 'int'
+ if(thetype == 'WebConsoleHandle_t'):
+ thetype = 'ulong'
+
+ if(thetype[0:7] == 'struct '):
+ thetype = thetype[7:]
+ if(thetype[0:6] == 'class '):
+ thetype = thetype[6:]
+ if(thetype[0:6] == 'union '):
+ thetype = thetype[6:]
+ if(thetype[0] == 'H' and thetype[0:3] != "Hmd" and thetype[0:16] != "HiddenAreaMesh_t"):
+ thetype = 'uint'
+ if(thetype[0:5] == 'enum '):
+ thetype = thetype[5:]
+ if(thetype[len(thetype) - 1] == '*' and thetype[len(thetype) - 2] == '*'):
+ thetype = 'IntPtr'
+ if(thetype[len(thetype) - 1] == '*'):
+ if("VRControllerState_t" not in thetype):
+ thetype = converttype(thetypewithnamespace[:len(thetypewithnamespace)-2])
+ else:
+ thetype = converttype(thetype[:len(thetype)-2])
+# thetype = 'IntPtr'
+ if(thetype[len(thetype) - 1] == '&'):
+ thetype = 'IntPtr'
+ if(thetype[len(thetype) - 1] == ']'):
+ thetype = thetype[0:thetype.find('[')-1]
+ if(thetype in typedeflist):
+ thetype = converttype(typedeflist[thetype])
+ if(thetypewithnamespace in typedeflist):
+ thetype = converttype(typedeflist[thetypewithnamespace])
+ return thetype
+
+def getnamespace(classname):
+ if(classname.find('::') != -1):
+ return classname[:classname.find('::')]
+ else:
+ return ''
+
+def getclasswithoutnamespace(classname):
+ if(classname.rfind('::') != -1):
+ return classname[classname.rfind('::')+2:]
+ else:
+ return classname
+
+def outputenums(namespace, data):
+ for enum in data['enums']:
+ if(len(enum) > 0 and len(enum['enumname'])):
+ ns = getnamespace(enum['enumname'])
+ enumname = getclasswithoutnamespace(enum['enumname'])
+ if(ns == namespace or (namespace == '' and ns[:1] == 'I')):
+ print('public enum '+enumname+'\n{')
+ enumNameWithoutE = enumname
+ if( enumname.startswith( "E" ) ):
+ enumNameWithoutE = enumname[1:]
+ for enumvalue in enum['values']:
+ entry = enumvalue['name']
+ if(entry.startswith(enumname)): entry = entry[len(enumname):] # strip off enum name
+ if(entry.startswith(enumNameWithoutE)): entry = entry[len(enumNameWithoutE):] # strip off enum name
+ if(entry.startswith('_')): entry = entry[1:] # strip off leading underscore
+ print('\t'+entry+' = '+enumvalue['value']+',')
+ print('}')
+
+def outputstructfields(struct, data):
+
+ # recursively add base class fields first
+ basename = getclasswithoutnamespace(struct['struct'])
+ if basename in structparents:
+ parentname = structparents[basename]
+ i = structindices[parentname];
+ outputstructfields(data['structs'][i], data)
+
+ for enumvalue in struct['fields']:
+ fieldtype = enumvalue['fieldtype']
+ otype = converttype(fieldtype)
+ lastchar = fieldtype[len(fieldtype) - 1]
+ if(lastchar == ']'):
+ #print('\tpublic fixed '+otype+' '+enumvalue['fieldname']+ fieldtype[fieldtype.find('['):]+';')
+ dims = map(int, fieldtype[fieldtype.find('[')+1:-1].split(']['))
+ size = reduce(operator.mul, dims, 1)
+ utype = unmanagedtype(otype)
+ if(otype == 'char'):
+ #print('\t[MarshalAs(UnmanagedType.ByValTStr, SizeConst = '+str(size)+')]')
+ sys.stdout.write('public byte '+enumvalue['fieldname']+'0')
+ for i in range(1, size):
+ sys.stdout.write(',' + enumvalue['fieldname'] + str(i))
+ print(';')
+
+
+ print('public string ' + enumvalue['fieldname'] + '\n{')
+ print('get\n{')
+ print('return new string(new char[] {')
+ for i in range(0, size-1):
+ print('(char)' + enumvalue['fieldname'] + str(i) + ',')
+ print('(char)' + enumvalue['fieldname'] + str(size-1) + '}).TrimEnd(\'\\0\');')
+ print('}')
+ print('}')
+ else:
+ #print('\t[MarshalAs(UnmanagedType.ByValArray, SizeConst = '+str(size)+', ArraySubType = UnmanagedType.'+utype+')]')
+ for i in range(size):
+ print('\tpublic '+otype+' '+enumvalue['fieldname']+str(i)+';'+(' //'+otype+fieldtype[fieldtype.find('['):] if(i==0) else ''))
+ else:
+ if(otype == 'bool'): print('\t[MarshalAs(UnmanagedType.I1)]')
+ if(lastchar == '*'):
+ print('\tpublic IntPtr '+enumvalue['fieldname']+';'+' // '+fieldtype)
+ else:
+ print('\tpublic '+otype+' '+enumvalue['fieldname']+';')
+
+def outputstructs(namespace, data):
+ for struct in data['structs']:
+ if(len(struct) > 0 and len(struct['struct'])):
+ structname = struct['struct']
+ #print('//'+structname)
+ ns = getnamespace(structname)
+ basename = getclasswithoutnamespace(structname)
+ if(basename != '(anonymous)' and (ns == namespace or (namespace == '' and ns[:1] == 'I') or (namespace == '' and ns[:1] == 'C'))):
+ for key, value in typedeflist.items():
+ if(converttype(value) == basename):
+ basename = getclasswithoutnamespace(key)
+ break
+
+ print('[StructLayout(LayoutKind.Sequential)] public struct '+basename+'\n{')
+ outputstructfields(struct, data)
+
+ if (basename == 'HmdMatrix34_t'):
+ print('#if UNITY_5_3_OR_NEWER')
+ print('\n\tpublic Vector3 GetPosition()')
+ print('\t{')
+ print('\t\treturn new Vector3(m3, m7, -m11);')
+ print('\t}')
+
+ print('\n\tpublic bool IsRotationValid()')
+ print('\t{')
+ print('\t\treturn ((m2 != 0 || m6 != 0 || m10 != 0) && (m1 != 0 || m5 != 0 || m9 != 0));')
+ print('\t}')
+
+ print('\n\tpublic Quaternion GetRotation()')
+ print('\t{')
+ print('\t\tif (IsRotationValid())')
+ print('\t\t{')
+ print('\t\t\tfloat w = Mathf.Sqrt(Mathf.Max(0, 1 + m0 + m5 + m10)) / 2;')
+ print('\t\t\tfloat x = Mathf.Sqrt(Mathf.Max(0, 1 + m0 - m5 - m10)) / 2;')
+ print('\t\t\tfloat y = Mathf.Sqrt(Mathf.Max(0, 1 - m0 + m5 - m10)) / 2;')
+ print('\t\t\tfloat z = Mathf.Sqrt(Mathf.Max(0, 1 - m0 - m5 + m10)) / 2;')
+
+ print('\n\t\t\t_copysign(ref x, -m9 - -m6);')
+ print('\t\t\t_copysign(ref y, -m2 - -m8);')
+ print('\t\t\t_copysign(ref z, m4 - m1);')
+
+ print('\n\t\t\treturn new Quaternion(x, y, z, w);')
+ print('\t\t}')
+
+ print('\t\treturn Quaternion.identity;')
+ print('\t}')
+
+ print('\n\tprivate static void _copysign(ref float sizeval, float signval)')
+ print('\t{')
+ print('\t\tif (signval > 0 != sizeval > 0)')
+ print('\t\t\tsizeval = -sizeval;')
+ print('\t}')
+
+ print('#endif')
+ print('}')
+ else:
+ print('}')
+
+ # The following structures were originally compiled with pack(4) on Linux & OSX by mistake. Generate
+ # a packed version of the structure so we can workaround this in the C# interop code
+ if ((basename == 'RenderModel_t') or
+ (basename == 'VRControllerState_t') or
+ (basename == 'RenderModel_TextureMap_t') or
+ (basename == 'VREvent_t')):
+ print('// This structure is for backwards binary compatibility on Linux and OSX only')
+ print('[StructLayout(LayoutKind.Sequential, Pack = 4)] public struct '+basename+'_Packed\n{')
+ outputstructfields(struct, data)
+ print('\tpublic '+basename+'_Packed('+basename+' unpacked)');
+ print('\t{')
+ for enumvalue in struct['fields']:
+ fieldtype = enumvalue['fieldtype']
+ otype = converttype(fieldtype)
+ if fieldtype[-1] == ']':
+ dims = map(int, fieldtype[fieldtype.find('[')+1:-1].split(']['))
+ size = reduce(operator.mul, dims, 1)
+ utype = unmanagedtype(otype)
+ for i in range(size):
+ print('\t\tthis.'+enumvalue['fieldname']+str(i)+' = unpacked.'+enumvalue['fieldname']+str(i)+';')
+
+ else:
+ print('\t\tthis.'+enumvalue['fieldname']+' = unpacked.'+enumvalue['fieldname']+';')
+ print('\t}')
+
+ print('\tpublic void Unpack(ref '+basename+' unpacked)');
+ print('\t{')
+ for enumvalue in struct['fields']:
+ fieldtype = enumvalue['fieldtype']
+ otype = converttype(fieldtype)
+ if fieldtype[-1] == ']':
+ dims = map(int, fieldtype[fieldtype.find('[')+1:-1].split(']['))
+ size = reduce(operator.mul, dims, 1)
+ utype = unmanagedtype(otype)
+ for i in range(size):
+ print('\t\tunpacked.'+enumvalue['fieldname']+str(i)+' = this.'+enumvalue['fieldname']+str(i)+';')
+
+ else:
+ print('\t\tunpacked.'+enumvalue['fieldname']+' = this.'+enumvalue['fieldname']+';')
+ print('\t}')
+ print('}')
+
+
+def outputinterfaces(namespace, data):
+ lastclass = ''
+ lastmethod = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ returntype = converttype(method['returntype'])
+ if(method['returntype'][len(method['returntype']) - 1] == '*'):
+ # Native methods which return pointers are cast to IntPtr
+ returntype = 'IntPtr'
+
+ methodname = method['methodname']
+ if(methodname == lastmethod):
+ methodname = methodname + repr(count)
+ count = count + 1
+ else:
+ count = 0
+ lastmethod = method['methodname']
+
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ if(lastclass != ''):
+ print("\t}\n");
+
+ print("\t[StructLayout(LayoutKind.Sequential)]")
+ print("\tpublic struct " + classname + "\n\t{")
+ lastclass = classname
+
+
+ paramlist = []
+ if('params' in method):
+ for param in method['params']:
+ paramtype = converttype(param['paramtype'])
+ if(param['paramtype'][len(param['paramtype']) - 1] == '*' and param['paramtype'][len(param['paramtype']) - 2] == '*'):
+ paramlist.append('ref ' + paramtype + ' ' + param['paramname'])
+ elif(param['paramtype'][len(param['paramtype']) - 1] == '*'):
+ if('out_array_count' in param) or ('array_call' in param) or ('array_count' in param) or ('out_array_call' in param):
+ paramlist.append('[In, Out] ' + paramtype + '[] ' + param['paramname'])
+ elif('out_string_count' in param):
+ paramlist.append('System.Text.StringBuilder ' + param['paramname'])
+ elif('out_struct' in param):
+ paramlist.append('ref '+ paramtype +' ' + param['paramname'])
+ elif('out_string' in param):
+ paramlist.append('System.Text.StringBuilder ' + param['paramname'])
+# elif(structlist.has_key(paramtype)):
+# paramlist.append(paramtype+' ' + param['paramname'])
+# elif(paramtype[0:1] == 'I' and paramtype != 'IntPtr'):
+# paramlist.append('IntPtr ' + param['paramname'])
+ elif (paramtype == 'uint' or paramtype == 'int' or paramtype == 'char' or paramtype == 'bool'):
+ # Output params for ints,uints,char
+ paramlist.append('ref ' + paramtype + ' ' + param['paramname'])
+ elif (paramtype == 'string' and param['paramtype'] == 'const char *'):
+ # Managed strings on Windows need to be converted to Utf8 native ptrs
+ paramlist.append('IntPtr ' + param['paramname'])
+ elif (paramtype == 'string' or paramtype == 'IntPtr'):
+ # Strings and IntPtrs are just straight
+ paramlist.append(paramtype + ' ' + param['paramname'])
+ else:
+# paramlist.append('ref ' + converttype(paramtype) + ' ' + param['paramname'])
+ paramlist.append('ref ' + paramtype + ' ' + param['paramname'])
+ else:
+ paramlist.append(paramtype + ' ' + param['paramname'])
+
+ print("\t\t[UnmanagedFunctionPointer(CallingConvention.StdCall)]")
+ print("\t\tinternal delegate "+returntype+" _"+methodname+"("+", ".join(paramlist)+");")
+ print("\t\t[MarshalAs(UnmanagedType.FunctionPtr)]")
+ print("\t\tinternal _"+methodname+" "+methodname+";\n")
+ print("\t}\n\n");
+
+
+def outputfntables(namespace, data):
+ lastclass = ''
+ lastmethod = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ returntype = method['returntype']
+ if(returntype == 'class CSteamID'):
+ returntype = 'uint64'
+ methodname = method['methodname']
+ if(methodname == lastmethod):
+ methodname = methodname + repr(count)
+ count = count + 1
+ else:
+ count = 0
+ lastmethod = method['methodname']
+
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ if(lastclass != ''):
+ print("};\n");
+
+ fntablename = method['classname'].replace('vr::', 'VR::').replace('::', '_') + '_FnTable'
+ print("struct " + fntablename + "\n{")
+ lastclass = classname
+
+ sys.stdout.write ('\t'+ ctype(returntype) + ' (OPENVR_FNTABLE_CALLTYPE *' + methodname + ')')
+
+ paramlist = []
+ if('params' in method):
+ for param in method['params']:
+ paramlist.append(ctype(param['paramtype']) + ' ' + param['paramname'])
+
+ print('('+", ".join(paramlist)+");")
+
+ print("};\n");
+
+def outputfntabledecls(namespace, data):
+ lastclass = ''
+ lastmethod = ''
+ fntablename = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ returntype = method['returntype']
+ if(returntype == 'class CSteamID'):
+ returntype = 'uint64'
+ methodname = method['methodname']
+ if(methodname == lastmethod):
+ methodname = methodname + repr(count)
+ count = count + 1
+ else:
+ count = 0
+ lastmethod = method['methodname']
+
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ if(lastclass != ''):
+ print("};\n\n");
+
+ fntablename = method['classname'].replace('vr::', 'VR::').replace('::', '_') + '_FnTable'
+ print("static " + fntablename + " g_" + fntablename + " =\n{")
+ lastclass = classname
+
+ print('\t&' + fntablename + '_' + methodname + ',')
+
+ print("};\n\n");
+
+def outputfntableinit(namespace, data):
+ print("extern void *FindInterface( const char *pchInterfaceName );\n")
+ print("void InitializeInterfaceFnTables()\n{")
+ lastclass = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ instancename = 'g_p' + classname
+ print("\t" + instancename + " = ( " + namespace + "::" + classname + " * )FindInterface( " + namespace + "::" + classname + "_Version );")
+ lastclass = classname
+ print("}\n")
+
+def outputfntableaccess(namespace, data):
+ lastclass = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ fntablename = method['classname'].replace('vr::', 'VR::').replace('::', '_') + '_FnTable'
+ print('FnTableRegistration autoreg_'+fntablename+'( '+classname+'_Version, &g_'+fntablename+' );')
+ lastclass = classname
+
+def outputfntablefuncs(namespace, data):
+ lastclass = ''
+ lastmethod = ''
+ instancename = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ returntype = method['returntype']
+ if(returntype == 'class CSteamID'):
+ returntype = 'uint64'
+ methodname = method['methodname']
+ if(methodname == lastmethod):
+ methodname = methodname + repr(count)
+ count = count + 1
+ else:
+ count = 0
+ lastmethod = method['methodname']
+
+ classname = method['classname']
+
+ if(namespace != getnamespace(classname)):
+ continue
+
+ classname = getclasswithoutnamespace(classname)
+ if(classname != lastclass):
+ if(lastclass != ''):
+ print("\n\n");
+
+ instancename = 'g_p' + classname
+ print("/** " + classname + " FnTable functions */\n")
+ print("static " + namespace + "::" + classname + " *" + instancename + " = nullptr;\n")
+ lastclass = classname
+
+ creturntype = ctype(returntype)
+ sys.stdout.write ('static '+ creturntype + ' OPENVR_FNTABLE_CALLTYPE '+method['classname'].replace('vr::', 'VR::').replace('::', '_') + '_FnTable_' + methodname)
+ paramlist = []
+ if('params' in method):
+ for param in method['params']:
+ paramlist.append(ctype(param['paramtype'])+' '+param['paramname'])
+
+ print('('+", ".join(paramlist)+")\n{")
+
+ paramlist = []
+ if('params' in method):
+ for param in method['params']:
+ paramtype = param['paramtype']
+ cparamtype = ctype(paramtype)
+ if paramtype != cparamtype:
+ if paramtype.startswith('struct'):
+ paramlist.append('*('+paramtype+'*)&'+param['paramname'])
+ else:
+ paramlist.append('('+paramtype+')'+param['paramname'])
+ else:
+ paramlist.append(param['paramname'])
+
+ # if the method is a destructor
+ if(method['methodname'][:8] == 'Destruct'):
+ sys.stdout.write ('delete instance;')
+ # void returntype does not return
+ elif (returntype == 'void'):
+ sys.stdout.write (instancename+'->'+method['methodname']+'(')
+ if('params' in method):
+ sys.stdout.write(", ".join(paramlist))
+ sys.stdout.write (');')
+ elif (creturntype.startswith('struct') and creturntype != returntype):
+ sys.stdout.write (returntype+' result = '+instancename+'->'+method['methodname']+'(')
+ if('params' in method):
+ sys.stdout.write(", ".join(paramlist))
+ sys.stdout.write (');\n')
+ sys.stdout.write ('return *('+creturntype+'*)&result;')
+ else:
+ if creturntype != returntype:
+ sys.stdout.write ('return ('+creturntype+')'+instancename+'->'+method['methodname']+'(')
+ else:
+ sys.stdout.write ('return '+instancename+'->'+method['methodname']+'(')
+ if('params' in method):
+ sys.stdout.write(", ".join(paramlist))
+ sys.stdout.write (');')
+ sys.stdout.write ('\n}\n');
+
+
+###############################
+# OUTPUT CLASSES
+###############################
+
+def isparamptr(paramname, paramlist):
+ for param in paramlist:
+ if(param['paramname'] == paramname):
+ return param['paramtype'][len(param['paramtype']) - 1] == '*'
+
+
+def outputclasses(namespace, data):
+
+ print("""public class Utils
+ {
+ public static IntPtr ToUtf8(string managedString)
+ {
+ if (managedString == null)
+ {
+ return IntPtr.Zero;
+ }
+
+ int size = System.Text.Encoding.UTF8.GetByteCount(managedString) + 1;
+ if (buffer.Length < size) buffer = new byte[size];
+ int written = System.Text.Encoding.UTF8.GetBytes(managedString, 0, managedString.Length, buffer, 0);
+ buffer[written] = 0x00; // null terminate
+ IntPtr nativeUtf8 = Marshal.AllocHGlobal(written+1);
+ Marshal.Copy(buffer, 0, nativeUtf8, written+1);
+ return nativeUtf8;
+ }
+ private static byte[] buffer = new byte[1024];
+ }
+ """)
+
+ # the following methods take a mispacked VRControllerState_t on Linux and OSX so we generate
+ # a special hacky method to account for that on those platforms.
+ controller_packed_methods = ['GetControllerState', 'GetControllerStateWithPose', 'GetComponentState']
+ event_packed_methods = ['PollNextEvent', 'PollNextEventWithPost', 'PollNextOverlayEvent']
+ if(namespace == ''):
+ namespaceextra = ''
+ elif(namespace == 'vr'):
+ namespaceextra = 'VR_'
+ else:
+ namespaceextra = namespace+'_'
+ lastclass = ''
+ lastmethod = ''
+ for method in data['methods']:
+ if (len(method) > 0):
+ returntype = converttype(method['returntype'])
+
+ interfacename = method['classname']
+
+ if(namespace != getnamespace(interfacename)):
+ continue
+
+ interfacename = getclasswithoutnamespace(interfacename)
+ methodname = method['methodname']
+ if(methodname == lastmethod):
+ methodname = methodname + repr(count)
+ count = count + 1
+ else:
+ count = 0
+ lastmethod = method['methodname']
+
+ if(interfacename != lastclass):
+ if(lastclass != ''):
+ print("}\n\n");
+ classname = 'C' + interfacename[1:]
+ classshort = interfacename[1:]
+ print("public class " + classname+"\n{")
+ print(interfacename+" FnTable;")
+ print("internal " + classname + "(IntPtr pInterface)")
+ print("{")
+ print("\tFnTable = ("+interfacename+")Marshal.PtrToStructure(pInterface, typeof("+interfacename+"));")
+ print("}")
+
+ lastclass = interfacename
+
+ paramlist = []
+ # Native params are always ref and include count params
+ nativeparamlist = []
+ skipparam = ''
+ outarray = 0
+ outstruct = 0
+ twocalls = 0
+ skipref = 0
+ arraytype = ''
+ arrayname = ''
+ arrayreplace = ''
+ skipcount = ''
+ skiptype = ''
+ paramtypelist = []
+ if('params' in method):
+ for param in method['params']:
+ paramtype = converttype(param['paramtype'])
+ if(param['paramname'] != skipparam):
+ if('out_array_count' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('out ' + paramtype + ' [] ' + param['paramname'])
+ nativeparamlist.append(param['paramname'])
+ skipparam = param['out_array_count']
+ arraytype = paramtype
+ arrayname = param['paramname']
+ arrayreplace = 'null'
+ twocalls = 1
+ outarray = 1
+ skipref = 1
+ elif('out_string_count' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('out string ' + param['paramname'])
+ nativeparamlist.append('pStrBuffer')
+ skipparam = param['out_string_count']
+ arraytype = paramtype
+ arrayname = 'pStrBuffer'
+ arrayreplace = 'null'
+ twocalls = 1
+ skipref = 1
+ elif('out_array_call' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('out ' + paramtype + ' [] ' + param['paramname'])
+ nativeparamlist.append(param['paramname'])
+ skipparam = param['out_array_call'].split(',')[0]
+ arraytype = paramtype
+ arrayname = param['paramname']
+ arrayreplace = 'null'
+ outarray = 1
+ skipref = 0
+ elif('out_string_count' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('out ' + paramtype + ' ' + param['paramname'])
+ nativeparamlist.append('ref ' + param['paramname'])
+ skipparam = param['out_string_count']
+ elif('out_struct' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('out ' + paramtype + ' ' + param['paramname'])
+ nativeparamlist.append('ref ' + param['paramname'])
+ elif('array_count' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append(paramtype + ' [] ' + param['paramname'])
+ nativeparamlist.append(param['paramname'])
+ skipparam = param['array_count']
+ skipcount = param['paramname']
+# elif(paramtype[0:1] == 'I' and paramtype != 'IntPtr' and not enumlist.has_key(paramtype)):
+# #print("//" + paramtype)
+# paramlist.append(param['paramname'])
+# paramtypelist.append(paramtype + ' ' + param['paramname'])
+# #nativeparamlist.append('ptr')
+# nativeparamlist.append(param['paramname'] + '.GetIntPtr()')
+# elif (structlist.has_key(paramtype)):
+# paramlist.append(' ' + param['paramname'])
+# paramtypelist.append(' ' + paramtype + ' ' + param['paramname'])
+# nativeparamlist.append(' ' + param['paramname'])
+ elif (param['paramtype'][len(param['paramtype']) - 1] == '*' and param['paramtype'][len(param['paramtype']) - 2] == '*'):
+ paramlist.append('ref ' + param['paramname'])
+ paramtypelist.append('ref ' + paramtype + ' ' + param['paramname'])
+ nativeparamlist.append('ref ' + param['paramname'])
+ if(paramtype != 'uint' and paramtype != 'int' and paramtype != 'char' and paramtype != 'bool'):
+ outstruct = 1
+ arraytype = paramtype
+ arrayname = param['paramname']
+ arrayreplace = 'null'
+ elif (param['paramtype'][len(param['paramtype']) - 1] == '*' and paramtype != 'string' and paramtype != 'IntPtr'):
+ paramlist.append('ref ' + param['paramname'])
+ paramtypelist.append('ref ' + paramtype + ' ' + param['paramname'])
+ nativeparamlist.append('ref ' + param['paramname'])
+ if(paramtype != 'uint' and paramtype != 'int' and paramtype != 'char' and paramtype != 'bool'):
+ outstruct = 1
+ arraytype = paramtype
+ arrayname = param['paramname']
+ arrayreplace = 'null'
+ elif ('out_string' in param):
+ paramlist.append(param['paramname'])
+ paramtypelist.append('System.Text.StringBuilder ' + param['paramname'])
+ nativeparamlist.append(param['paramname'])
+ elif (paramtype == 'string' and param['paramtype'] == 'const char *'):
+ paramlist.append(param['paramname'])
+ paramtypelist.append(paramtype + ' ' + param['paramname'])
+ nativeparamlist.append(param['paramname']+'Utf8')
+ else:
+ paramlist.append(param['paramname'])
+ paramtypelist.append(paramtype + ' ' + param['paramname'])
+ nativeparamlist.append(param['paramname'])
+ else:
+ skiptype = paramtype
+ if(skipref):
+ nativeparamlist.append('ref ' + param['paramname'])
+ elif(skipcount != ''):
+ nativeparamlist.append("(" + paramtype +") " + skipcount + ".Length" )
+ else:
+ nativeparamlist.append(param['paramname'])
+ skipparam = 0
+ if methodname in controller_packed_methods or methodname in event_packed_methods:
+ if methodname in controller_packed_methods:
+ packedlist=[w.replace('VRControllerState_t','VRControllerState_t_Packed').replace('string', 'IntPtr') for w in paramtypelist]
+ else:
+ packedlist=[w.replace('VREvent_t','VREvent_t_Packed') for w in paramtypelist]
+ print('// This is a terrible hack to workaround the fact that VRControllerState_t and VREvent_t were ')
+ print('// originally mis-compiled with the wrong packing for Linux and OSX.')
+ print('[UnmanagedFunctionPointer(CallingConvention.StdCall)]')
+ print('internal delegate '+returntype+' _'+methodname+'Packed('+','.join(packedlist)+');')
+ print('[StructLayout(LayoutKind.Explicit)]')
+ print('struct '+methodname+'Union\n{')
+ print('\t[FieldOffset(0)]\n\tpublic '+interfacename+'._'+methodname+' p'+methodname+';')
+ print('\t[FieldOffset(0)]\n\tpublic _'+methodname+'Packed p'+methodname+'Packed;\n}')
+
+ sys.stdout.write ('public '+returntype+' '+methodname+'('+','.join(paramtypelist)+')\n{\n')
+ # PROCESS THE STUFF BEFORE THE API CALLS
+ if('params' in method):
+ for param in method['params']:
+ if(skipparam != param['paramname']):
+ paramtype = converttype(param['paramtype'])
+ if('out_array_count' in param and skipparam != param['out_array_count']):
+ skipparam = param['out_array_count']
+ sys.stdout.write( '\t'+skiptype+' '+skipparam+' = 0;\n' )
+ elif('out_string_count' in param and skipparam != param['out_string_count']):
+ skipparam = param['out_string_count']
+ #if(isparamptr(skipparam, param)):
+ sys.stdout.write( '\t'+skiptype+' '+skipparam+' = 0;\n' )
+ elif('out_array_call' in param):
+ vals = param['out_array_call'].split(',')
+ sys.stdout.write( '\tint '+vals[0]+' = '+vals[1]+' ('+vals[2]+');\n' )
+ sys.stdout.write( '\t'+param['paramname']+' = new '+paramtype+'['+vals[0]+'];\n' )
+ elif('out_struct' in param):
+ sys.stdout.write( '\t'+param['paramname']+' = new '+paramtype+'();\n' )
+ elif (param['paramtype'][len(param['paramtype']) - 1] == '*' and (paramtype == 'int' or paramtype == 'uint' or paramtype == 'float' or paramtype == 'long' or paramtype == 'ulong' or paramtype == 'double') and not 'array_count' in param):
+ # Out parameters need to be initialized to zero
+ sys.stdout.write( '\t'+param['paramname']+' = 0;\n' )
+ elif (param['paramtype'][len(param['paramtype']) - 2:] == '**' and (paramtype == 'string')):
+ # Out parameters need to be initialized to zero
+ sys.stdout.write( '\t'+param['paramname']+' = "";\n' )
+ elif (param['paramtype'][len(param['paramtype']) - 1] == '*' and (paramtype == 'char')):
+ # Out parameters need to be initialized to zero
+ sys.stdout.write( '\t'+param['paramname']+' = (char) 0;\n' )
+ elif (param['paramtype'][len(param['paramtype']) - 1] == '*' and (paramtype == 'bool')):
+ # Out parameters need to be initialized to zero
+ sys.stdout.write( '\t'+param['paramname']+' = false;\n' )
+ elif (paramtype == 'string' and param['paramtype'] == 'const char *'):
+ # In strings need to be converted to UTF-8
+ sys.stdout.write( '\tIntPtr '+param['paramname']+'Utf8 = Utils.ToUtf8('+param['paramname']+');\n')
+ #elif(paramtype[0:1] == 'I' and paramtype != 'IntPtr' and not enumlist.has_key(paramtype)):
+ # Returning an interface ptr needs ptr defined
+ # sys.stdout.write( '\tIntPtr ptr = IntPtr.Zero;\n' )
+
+
+ # PROCESS THE FIRST OPTIONAL API CALL
+ if(twocalls):
+ paramsnull = ','.join(map((lambda x: (arrayreplace if (x==arrayname) else x)),nativeparamlist))
+ sys.stdout.write ('\t'+('' if (returntype=='void') else (returntype+' result = '))+'FnTable.'+methodname+'('+paramsnull+');\n')
+
+ # PROCESS IN BETWEEN THE API CALLS
+ # Allocate the array or buffer
+ if('params' in method):
+ for param in method['params']:
+ if('out_array_count' in param):
+ sys.stdout.write( '\t'+param['paramname']+'= new ' + converttype(param['paramtype']) + '['+param['out_array_count']+'];\n' )
+ if('out_string_count' in param):
+ sys.stdout.write( '\tSystem.Text.StringBuilder pStrBuffer = new System.Text.StringBuilder((int)'+skipparam+');\n' )
+
+
+ # PROCESS THE FINAL API CALL
+ if methodname in controller_packed_methods:
+ packedparamlist = [w.replace('pControllerState','state_packed')
+ .replace('unControllerStateSize','(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t_Packed))')
+ for w in nativeparamlist]
+
+ print('#if !UNITY_METRO')
+ print('\tif ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) ||')
+ print('\t (System.Environment.OSVersion.Platform == System.PlatformID.Unix))')
+ print('\t{')
+ print('\t\t'+methodname+'Union u;')
+ print('\t\tVRControllerState_t_Packed state_packed = new VRControllerState_t_Packed(pControllerState);')
+ print('\t\tu.p'+methodname+'Packed = null;')
+ print('\t\tu.p'+methodname+' = FnTable.'+methodname+';')
+ print('\t\t'+returntype+' packed_result = u.p'+methodname+'Packed('+','.join(packedparamlist)+');\n')
+ print('\t\tstate_packed.Unpack(ref pControllerState);')
+ print('\t\treturn packed_result;')
+ print('\t}')
+ print('#endif')
+ if methodname in event_packed_methods:
+ packedparamlist = [w.replace('pEvent','event_packed')
+ .replace('uncbVREvent','(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VREvent_t_Packed))')
+ for w in nativeparamlist]
+
+ print('#if !UNITY_METRO')
+ print('\tif ((System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) ||')
+ print('\t (System.Environment.OSVersion.Platform == System.PlatformID.Unix))')
+ print('\t{')
+ print('\t\t'+methodname+'Union u;')
+ print('\t\tVREvent_t_Packed event_packed = new VREvent_t_Packed();')
+ print('\t\tu.p'+methodname+'Packed = null;')
+ print('\t\tu.p'+methodname+' = FnTable.'+methodname+';')
+ print('\t\t'+returntype+' packed_result = u.p'+methodname+'Packed('+','.join(packedparamlist)+');\n')
+ print('\t\tevent_packed.Unpack(ref pEvent);')
+ print('\t\treturn packed_result;')
+ print('\t}')
+ print('#endif')
+
+
+ savereturn = returntype
+ if(method['returntype'][len(method['returntype']) - 1] == '*'):
+ returntype = 'IntPtr'
+ if(returntype == 'void'):
+ if(len(nativeparamlist) > 0):
+ sys.stdout.write ('\tFnTable.'+methodname+'('+','.join(nativeparamlist)+');\n')
+ else:
+ sys.stdout.write ('\tFnTable.'+methodname+'();\n')
+ else:
+ if(len(nativeparamlist) > 0):
+ #if(returntype[0:1] == 'I' and returntype != 'IntPtr'):
+ # sys.stdout.write ('\tC'+returntype[1:]+' result = new C'+returntype[1:]+'(FnTable.'+methodname+'('+','.join(nativeparamlist)+'));\n')
+ if(returntype == 'string'):
+ sys.stdout.write ('\tstring result = Marshal.PtrToStringAuto(FnTable.'+methodname+'('+','.join(nativeparamlist)+'));\n')
+ else:
+ sys.stdout.write ('\t'+('' if twocalls else returntype)+' result = FnTable.'+methodname+'('+','.join(nativeparamlist)+');\n')
+ else:
+ if(returntype == 'string'):
+ sys.stdout.write ('\tstring result = Marshal.PtrToStringAuto(FnTable.'+methodname+'());\n')
+ else:
+ sys.stdout.write ('\t'+('' if twocalls else returntype)+' result = FnTable.'+methodname+'();\n')
+
+
+ # PROCESS AFTER THE API CALL
+ if('params' in method):
+ for param in method['params']:
+ paramtype = converttype(param['paramtype'])
+ if('out_string_count' in param):
+ sys.stdout.write( '\t'+param['paramname']+' = pStrBuffer.ToString();\n' )
+ elif (paramtype == 'string' and param['paramtype'] == 'const char *'):
+ sys.stdout.write( '\tMarshal.FreeHGlobal('+param['paramname']+'Utf8);\n')
+ #elif(paramtype[0:1] == 'I' and paramtype != 'IntPtr' and not enumlist.has_key(paramtype)):
+ # Interface. Need to construct a class wrapper
+ #sys.stdout.write( '\t'+param['paramname']+'= new C' + paramtype[1:] + '(ptr);\n' )
+
+ if(method['returntype'][len(method['returntype']) - 1] == '*'):
+ if(savereturn == 'string'):
+ sys.stdout.write ('\treturn Marshal.PtrToStringAnsi(result);\n')
+ else:
+ sys.stdout.write ('\treturn ('+savereturn+') Marshal.PtrToStructure(result, typeof('+savereturn+'));\n')
+ elif(returntype != 'void'):
+ sys.stdout.write ('\treturn result;\n')
+ sys.stdout.write ('}\n')
diff --git a/codegen/openvr_capi.cpp.py b/codegen/openvr_capi.cpp.py
new file mode 100755
index 0000000..33e7e8d
--- /dev/null
+++ b/codegen/openvr_capi.cpp.py
@@ -0,0 +1,88 @@
+print ("""//======= Copyright (c) Valve Corporation, All rights reserved. ===============
+//
+// Purpose: This is a flattened version of the OpenVR_API interfaces.
+// This file is auto-generated, do not edit it.
+//
+//=============================================================================
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <ShellAPI.h>
+#endif
+
+#if defined(OSX)
+#include <sys/syslimits.h>
+#include <signal.h>
+#define MAX_PATH PATH_MAX
+#elif defined(LINUX)
+#include <linux/limits.h>
+#include <signal.h>
+#define MAX_PATH PATH_MAX
+#elif defined(WIN32)
+#else
+#error
+#endif
+
+#ifdef POSIX
+#include <fcntl.h>
+#include <dlfcn.h> // dlopen,dlclose, et al
+#include <unistd.h>
+#include <stdarg.h>
+#define HMODULE void *
+#define GetProcAddress dlsym
+#define OutputDebugString( pchMsg ) fputs( pchMsg, stderr )
+#define _strnicmp strncasecmp
+//#include "../../common/linuxhelpers_nodeps.h"
+#endif
+
+#ifdef OSX
+#include <sys/sysctl.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "openvr.h"
+#include "ivrsystem.h"
+#include "ivrchaperone.h"
+#include "ivrchaperonesetup.h"
+#include "ivrcompositor.h"
+#include "ivroverlay.h"
+#include "ivrrendermodels.h"
+#include "ivrnotifications.h"
+#include "ivrblockqueue.h"
+
+#include "../vrclient/interface_adapters_client.h"
+#include "_dynamic_openvr_api_flat.h"
+
+class FnTableRegistration
+{
+public:
+ FnTableRegistration( const char *pchInterfaceName, void *pInterface )
+ {
+ char buffer[255];
+ sprintf(buffer, "FnTable:%s", pchInterfaceName);
+ m_pInterfaceRegistration = new GenericInterfaceRegistration( buffer, pInterface );
+ }
+ ~FnTableRegistration()
+ {
+ delete m_pInterfaceRegistration;
+ }
+private:
+ GenericInterfaceRegistration *m_pInterfaceRegistration;
+};
+
+""")
+
+
+import json
+import sys
+with open('_dynamic_openvr_api.json') as data_file:
+ data = json.load(data_file)
+
+import api_shared
+api_shared.outputfntablefuncs('vr', data)
+api_shared.outputfntabledecls('vr', data)
+api_shared.outputfntableinit('vr', data)
+api_shared.outputfntableaccess('vr', data)
+
diff --git a/codegen/openvr_capi.h.py b/codegen/openvr_capi.h.py
new file mode 100755
index 0000000..1b912cd
--- /dev/null
+++ b/codegen/openvr_capi.h.py
@@ -0,0 +1,290 @@
+import sys
+import api_shared
+import operator
+from functools import reduce
+
+print ("""//======= Copyright (c) Valve Corporation, All rights reserved. ===============
+//
+// Purpose: Header for flatted SteamAPI. Use this for binding to other languages.
+// This file is auto-generated, do not edit it.
+//
+//=============================================================================
+
+#ifndef __OPENVR_API_FLAT_H__
+#define __OPENVR_API_FLAT_H__
+#if defined( _WIN32 ) || defined( __clang__ )
+#pragma once
+#endif
+
+#ifdef __cplusplus
+#define EXTERN_C extern "C"
+#else
+#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 )
+ #if defined( OPENVR_API_EXPORTS )
+ #define S_API EXTERN_C __declspec( dllexport )
+ #elif defined( OPENVR_API_NODLL )
+ #define S_API EXTERN_C
+ #else
+ #define S_API extern "C" __declspec( dllimport )
+ #endif // OPENVR_API_EXPORTS
+#elif defined( __GNUC__ )
+ #if defined( OPENVR_API_EXPORTS )
+ #define S_API EXTERN_C __attribute__ ((visibility("default")))
+ #else
+ #define S_API EXTERN_C
+ #endif // OPENVR_API_EXPORTS
+#else // !WIN32
+ #if defined( OPENVR_API_EXPORTS )
+ #define S_API EXTERN_C
+ #else
+ #define S_API EXTERN_C
+ #endif // OPENVR_API_EXPORTS
+#endif
+
+#include <stdint.h>
+
+#if defined( __WIN32 )
+typedef char bool;
+#else
+#include <stdbool.h>
+#endif
+
+typedef uint64_t PropertyContainerHandle_t;
+typedef uint32_t PropertyTypeTag_t;
+typedef uint64_t VRActionHandle_t;
+typedef uint64_t VRActionSetHandle_t;
+typedef uint64_t VRInputValueHandle_t;
+typedef uint64_t PathHandle_t;
+""")
+
+
+
+data = api_shared.loadfile('_dynamic_openvr_api.json', 'vr')
+converttype = api_shared.converttype
+striparraysuffix = api_shared.striparraysuffix
+structlist = api_shared.structlist
+structparents = api_shared.structparents
+structindices = api_shared.structindices
+typedeflist = api_shared.typedeflist
+enumlist = api_shared.enumlist
+getnamespace = api_shared.getnamespace
+getclasswithoutnamespace = api_shared.getclasswithoutnamespace
+unmanagedtype = api_shared.unmanagedtype
+ctype = api_shared.ctype
+namespace = 'vr'
+
+def OutputStructFields(struct):
+
+ # recursively add base class fields first
+ basename = getclasswithoutnamespace(struct['struct'])
+ if basename in structparents:
+ parentname = structparents[basename]
+ i = structindices[parentname];
+ OutputStructFields(data['structs'][i])
+
+ for enumvalue in struct['fields']:
+ fieldtype = enumvalue['fieldtype']
+ otype = striparraysuffix(fieldtype)
+ lastchar = fieldtype[len(fieldtype) - 1]
+ if(lastchar == ']'):
+ #print('\t//fixed '+otype+' '+enumvalue['fieldname']+ fieldtype[fieldtype.find('['):]+';')
+ dims = map(int, fieldtype[fieldtype.find('[')+1:-1].split(']['))
+ size = reduce(operator.mul, dims, 1)
+ utype = unmanagedtype(otype)
+ print('\t'+('char ' if(otype=='char') else ctype(otype)+' ')+enumvalue['fieldname']+ fieldtype[fieldtype.find('['):]+'; //'+otype+fieldtype[fieldtype.find('['):])
+ else:
+ if(lastchar == '*'):
+ print('\t'+ctype(fieldtype)+' '+enumvalue['fieldname']+';'+' // '+fieldtype)
+ else:
+ print('\t'+ctype(otype)+' '+enumvalue['fieldname']+';')
+
+########
+# Output constants into OpenVR class
+print ("""
+// OpenVR Constants
+""")
+for const in data['consts']:
+ if(len(const) > 0):
+ consttype = converttype(const['consttype'])
+ constval = const['constval']
+ if(consttype == 'string'):
+ constval = '\"' + constval + '\"'
+ consttype = 'char *'
+ print('static const '+ctype(consttype)+' '+const['constname']+' = '+constval+';')
+
+######
+# Output enums
+print ("""
+// OpenVR Enums
+""")
+for enum in data['enums']:
+ if(len(enum) > 0 and len(enum['enumname'])):
+ ns = getnamespace(enum['enumname'])
+ enumname = getclasswithoutnamespace(enum['enumname'])
+ if(ns == namespace or (namespace == '' and ns[:1] == 'I')):
+ print('typedef enum '+enumname+'\n{')
+ for enumvalue in enum['values']:
+ entry = enumvalue['name']
+ if(entry.startswith(enumname)): entry = entry[len(enumname):] # strip off enum name
+ if(entry.startswith('_')): entry = entry[1:] # strip off leading underscore
+ print('\t'+enumname+'_'+entry+' = '+enumvalue['value']+',')
+ print('} '+enumname+';\n')
+
+########
+# Output typedefs into OpenVR class
+
+print ("""
+// OpenVR typedefs
+
+typedef uint32_t TrackedDeviceIndex_t;
+typedef uint32_t VRNotificationId;
+typedef uint64_t VROverlayHandle_t;
+""")
+
+for typedef in data['typedefs']:
+ if(len(typedef) > 0):
+ thetype = typedef['type']
+ if(thetype[0:6] != 'union ' and thetype[0:7] != 'struct '):
+ thetypedef = getclasswithoutnamespace(typedef['typedef']) # remove the vr:: bit from thetypedef
+ thetype = getclasswithoutnamespace(thetype)
+ print('typedef '+thetype+' '+thetypedef+';')
+
+######
+# Output structs
+print ("""
+// OpenVR Structs
+""")
+for struct in data['structs']:
+ if(len(struct) > 0 and len(struct['struct'])):
+ structname = struct['struct']
+ #print('//'+structname)
+ ns = getnamespace(structname)
+ basename = getclasswithoutnamespace(structname)
+ if(basename != 'VREvent_t' and basename != 'VROverlayIntersectionMaskPrimitive_t' and basename != '(anonymous)' and (ns == namespace or (namespace == '' and ns[:1] == 'I') or (namespace == '' and ns[:1] == 'C'))):
+ #if basename != '(anonymous)':
+ unsafe = 0
+ for enumvalue in struct['fields']:
+ fieldtype = enumvalue['fieldtype']
+ if(fieldtype[len(fieldtype) - 1] == ']'):
+ unsafe = 1
+
+ pack = ((basename == 'RenderModel_t') or
+ (basename == 'VRControllerState_t') or
+ (basename=='RenderModel_TextureMap_t') or
+ (basename=='VREvent_t'))
+
+ # resolve typedefs used to rename structs
+ for key, value in typedeflist.items():
+ if(converttype(value) == basename):
+ basename = getclasswithoutnamespace(key)
+ break
+
+ if (pack):
+ print('#if defined(__linux__) || defined(__APPLE__)\n#pragma pack( push, 4 )\n#endif')
+ if(unsafe == 1):
+ print('typedef struct '+basename+'\n{') # this was for potentially putting unsafe fields in
+ else:
+ print('typedef struct '+basename+'\n{')
+
+ OutputStructFields(struct)
+
+ print('} '+basename+';\n')
+ if pack:
+ print('#if defined(__linux__) || defined(__APPLE__)\n#pragma pack( pop )\n#endif')
+
+print ("""
+typedef union
+{
+ VREvent_Reserved_t reserved;
+ VREvent_Controller_t controller;
+ VREvent_Mouse_t mouse;
+ VREvent_Scroll_t scroll;
+ VREvent_Process_t process;
+ VREvent_Notification_t notification;
+ VREvent_Overlay_t overlay;
+ VREvent_Status_t status;
+ VREvent_Keyboard_t keyboard;
+ VREvent_Ipd_t ipd;
+ VREvent_Chaperone_t chaperone;
+ VREvent_PerformanceTest_t performanceTest;
+ VREvent_TouchPadMove_t touchPadMove;
+ VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset;
+ VREvent_Screenshot_t screenshot;
+ VREvent_ScreenshotProgress_t screenshotProgress;
+ VREvent_ApplicationLaunch_t applicationLaunch;
+ VREvent_EditingCameraSurface_t cameraSurface;
+ VREvent_MessageOverlay_t messageOverlay;
+ VREvent_Property_t property;
+ VREvent_HapticVibration_t hapticVibration;
+ VREvent_WebConsole_t webConsole;
+ VREvent_InputBindingLoad_t inputBinding;
+ VREvent_InputActionManifestLoad_t actionManifest;
+ VREvent_SpatialAnchor_t spatialAnchor;
+} 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
+{
+ uint32_t eventType; // EVREventType enum
+ TrackedDeviceIndex_t trackedDeviceIndex;
+ float eventAgeSeconds;
+ // event data must be the end of the struct as its size is variable
+ VREvent_Data_t data;
+};
+
+#if defined(__linux__) || defined(__APPLE__)
+#pragma pack( pop )
+#endif
+""")
+
+print ("""
+typedef union
+{
+ IntersectionMaskRectangle_t m_Rectangle;
+ IntersectionMaskCircle_t m_Circle;
+} VROverlayIntersectionMaskPrimitive_Data_t;
+
+struct VROverlayIntersectionMaskPrimitive_t
+{
+ EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType;
+ VROverlayIntersectionMaskPrimitive_Data_t m_Primitive;
+};
+""")
+
+print ("""
+// OpenVR Function Pointer Tables
+""")
+api_shared.outputfntables(namespace, data)
+
+print ("""
+#if 0
+// Global entry points
+S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType );
+S_API void VR_ShutdownInternal();
+S_API bool VR_IsHmdPresent();
+S_API intptr_t VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError );
+S_API bool VR_IsRuntimeInstalled();
+S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error );
+S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error );
+#endif
+
+#endif // __OPENVR_API_FLAT_H__
+
+""")
+
diff --git a/codegen/openvr_interop.cs.py b/codegen/openvr_interop.cs.py
new file mode 100755
index 0000000..cfabeb2
--- /dev/null
+++ b/codegen/openvr_interop.cs.py
@@ -0,0 +1,597 @@
+import sys
+import api_shared
+calculateinteropmethodname = api_shared.calculateinteropmethodname
+
+print ("""//======= Copyright (c) Valve Corporation, All rights reserved. ===============
+//
+// Purpose: This file contains C#/managed code bindings for the OpenVR interfaces
+// This file is auto-generated, do not edit it.
+//
+//=============================================================================
+#if !OPENVR_XR_API
+
+using System;
+using System.Runtime.InteropServices;
+using Valve.VR;
+
+#if UNITY_5_3_OR_NEWER
+using UnityEngine;
+#endif
+
+namespace Valve.VR
+{
+""")
+
+
+
+data = api_shared.loadfile('_dynamic_openvr_api.json', 'vr')
+converttype = api_shared.converttype
+structlist = api_shared.structlist
+typedeflist = api_shared.typedeflist
+enumlist = api_shared.enumlist
+lastmethod = ''
+
+
+############## define Csharp interfaces ######################
+
+api_shared.outputinterfaces('vr', data)
+
+############ define csharp classes
+
+api_shared.outputclasses('vr', data)
+
+print("}\n\n");
+
+# Output the OpenVRInterop class
+print('public class OpenVRInterop\n{')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_InitInternal", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern uint InitInternal(ref EVRInitError peError, EVRApplicationType eApplicationType);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_InitInternal2", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern uint InitInternal2(ref EVRInitError peError, EVRApplicationType eApplicationType,[In, MarshalAs(UnmanagedType.LPStr)] string pStartupInfo);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_ShutdownInternal", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern void ShutdownInternal();')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_IsHmdPresent", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern bool IsHmdPresent();')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_IsRuntimeInstalled", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern bool IsRuntimeInstalled();')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_RuntimePath", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern string RuntimePath();')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_GetRuntimePath", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern bool GetRuntimePath(System.Text.StringBuilder pchPathBuffer, uint unBufferSize, ref uint punRequiredBufferSize);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_GetStringForHmdError", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern IntPtr GetStringForHmdError(EVRInitError error);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_GetGenericInterface", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern IntPtr GetGenericInterface([In, MarshalAs(UnmanagedType.LPStr)] string pchInterfaceVersion, ref EVRInitError peError);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_IsInterfaceVersionValid", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern bool IsInterfaceVersionValid([In, MarshalAs(UnmanagedType.LPStr)] string pchInterfaceVersion);')
+print('[DllImportAttribute("openvr_api", EntryPoint = "VR_GetInitToken", CallingConvention = CallingConvention.Cdecl)]')
+print('internal static extern uint GetInitToken();')
+print("}\n\n");
+
+api_shared.outputenums('vr', data)
+
+print("""
+ [StructLayout(LayoutKind.Explicit)] public struct VREvent_Data_t
+ {
+ [FieldOffset(0)] public VREvent_Reserved_t reserved;
+ [FieldOffset(0)] public VREvent_Controller_t controller;
+ [FieldOffset(0)] public VREvent_Mouse_t mouse;
+ [FieldOffset(0)] public VREvent_Scroll_t scroll;
+ [FieldOffset(0)] public VREvent_Process_t process;
+ [FieldOffset(0)] public VREvent_Notification_t notification;
+ [FieldOffset(0)] public VREvent_Overlay_t overlay;
+ [FieldOffset(0)] public VREvent_Status_t status;
+ [FieldOffset(0)] public VREvent_Ipd_t ipd;
+ [FieldOffset(0)] public VREvent_Chaperone_t chaperone;
+ [FieldOffset(0)] public VREvent_PerformanceTest_t performanceTest;
+ [FieldOffset(0)] public VREvent_TouchPadMove_t touchPadMove;
+ [FieldOffset(0)] public VREvent_SeatedZeroPoseReset_t seatedZeroPoseReset;
+ [FieldOffset(0)] public VREvent_Screenshot_t screenshot;
+ [FieldOffset(0)] public VREvent_ScreenshotProgress_t screenshotProgress;
+ [FieldOffset(0)] public VREvent_ApplicationLaunch_t applicationLaunch;
+ [FieldOffset(0)] public VREvent_EditingCameraSurface_t cameraSurface;
+ [FieldOffset(0)] public VREvent_MessageOverlay_t messageOverlay;
+ [FieldOffset(0)] public VREvent_Property_t property;
+ [FieldOffset(0)] public VREvent_HapticVibration_t hapticVibration;
+ [FieldOffset(0)] public VREvent_WebConsole_t webConsole;
+ [FieldOffset(0)] public VREvent_InputBindingLoad_t inputBinding;
+ [FieldOffset(0)] public VREvent_SpatialAnchor_t spatialAnchor;
+ [FieldOffset(0)] public VREvent_InputActionManifestLoad_t actionManifest;
+ [FieldOffset(0)] public VREvent_ProgressUpdate_t progressUpdate;
+ [FieldOffset(0)] public VREvent_ShowUI_t showUi;
+ [FieldOffset(0)] public VREvent_ShowDevTools_t showDevTools;
+ [FieldOffset(0)] public VREvent_HDCPError_t hdcpError;
+ [FieldOffset(0)] public VREvent_Keyboard_t keyboard; // This has to be at the end due to a mono bug
+ }
+ """)
+
+print("""
+ [StructLayout(LayoutKind.Explicit)] public struct VROverlayIntersectionMaskPrimitive_Data_t
+ {
+ [FieldOffset(0)] public IntersectionMaskRectangle_t m_Rectangle;
+ [FieldOffset(0)] public IntersectionMaskCircle_t m_Circle;
+ }
+ """)
+
+api_shared.outputstructs('vr', data)
+
+
+# Output the OpenVR class
+print('\npublic class OpenVR\n{')
+print("""
+ public static uint InitInternal(ref EVRInitError peError, EVRApplicationType eApplicationType)
+ {
+ return OpenVRInterop.InitInternal(ref peError, eApplicationType);
+ }
+
+ public static uint InitInternal2(ref EVRInitError peError, EVRApplicationType eApplicationType, string pchStartupInfo)
+ {
+ return OpenVRInterop.InitInternal2(ref peError, eApplicationType, pchStartupInfo);
+ }
+
+ public static void ShutdownInternal()
+ {
+ OpenVRInterop.ShutdownInternal();
+ }
+
+ public static bool IsHmdPresent()
+ {
+ return OpenVRInterop.IsHmdPresent();
+ }
+
+ public static bool IsRuntimeInstalled()
+ {
+ return OpenVRInterop.IsRuntimeInstalled();
+ }
+
+ public static string RuntimePath()
+ {
+ try
+ {
+ uint pathSize = 512;
+ uint requiredPathSize = 512;
+ System.Text.StringBuilder path = new System.Text.StringBuilder((int)pathSize);
+ bool success = OpenVRInterop.GetRuntimePath(path, pathSize, ref requiredPathSize);
+ if (success == false)
+ {
+ return null;
+ }
+
+ return path.ToString();
+ } catch
+ {
+ return OpenVRInterop.RuntimePath(); //this api is deprecated but here to support older unity versions
+ }
+ }
+
+ public static string GetStringForHmdError(EVRInitError error)
+ {
+ return Marshal.PtrToStringAnsi(OpenVRInterop.GetStringForHmdError(error));
+ }
+
+ public static IntPtr GetGenericInterface(string pchInterfaceVersion, ref EVRInitError peError)
+ {
+ return OpenVRInterop.GetGenericInterface(pchInterfaceVersion, ref peError);
+ }
+
+ public static bool IsInterfaceVersionValid(string pchInterfaceVersion)
+ {
+ return OpenVRInterop.IsInterfaceVersionValid(pchInterfaceVersion);
+ }
+
+ public static uint GetInitToken()
+ {
+ return OpenVRInterop.GetInitToken();
+ }
+""")
+
+########
+# Output constants into OpenVR class
+
+for const in data['consts']:
+ if(len(const) > 0):
+ consttype = converttype(const['consttype'])
+ constval = const['constval']
+ if(consttype == 'string'):
+ constval = '\"' + constval + '\"'
+ print('public const '+consttype+' '+const['constname']+' = '+constval+';')
+
+########
+# Output static constructors into OpenVR class
+#lastclass = ''
+#lastmethod = ''
+#for method in data['methods']:
+# if (len(method) > 0):
+# returntype = converttype(method['returntype'])
+#
+# methodname = method['methodname']
+# if(methodname == lastmethod):
+# methodname = methodname + `count`
+# count = count + 1
+# else:
+# count = 0
+# lastmethod = method['methodname']
+#
+# interfacename = method['classname']
+# namespace = api_shared.getnamespace(interfacename)
+# if(interfacename.find('::') == -1):
+# classname= 'C' + interfacename[1:]
+# else:
+# interfacename = interfacename[interfacename.find('::') + 2:]
+# classname = 'C' + interfacename[1:]
+# if(namespace != ''):
+# if(interfacename != lastclass):
+# shortname = interfacename[1:]
+# print('public static '+interfacename+' '+shortname+'()\n{\nreturn new '+classname+'(OpenVRInterop.'+shortname+'());\n}\n')
+# lastclass = interfacename
+
+########
+# Output interface wrappers into OpenVR class
+
+print("""
+ static uint VRToken { get; set; }
+
+ const string FnTable_Prefix = "FnTable:";
+
+ class COpenVRContext
+ {
+ public COpenVRContext() { Clear(); }
+
+ public void Clear()
+ {
+ m_pVRSystem = null;
+ m_pVRChaperone = null;
+ m_pVRChaperoneSetup = null;
+ m_pVRCompositor = null;
+ m_pVRHeadsetView = null;
+ m_pVROverlay = null;
+ m_pVROverlayView = null;
+ m_pVRRenderModels = null;
+ m_pVRExtendedDisplay = null;
+ m_pVRSettings = null;
+ m_pVRApplications = null;
+ m_pVRScreenshots = null;
+ m_pVRTrackedCamera = null;
+ m_pVRInput = null;
+ m_pVRIOBuffer = null;
+ m_pVRSpatialAnchors = null;
+ m_pVRNotifications = null;
+ m_pVRDebug = null;
+ }
+
+ void CheckClear()
+ {
+ if (VRToken != GetInitToken())
+ {
+ Clear();
+ VRToken = GetInitToken();
+ }
+ }
+
+ public CVRSystem VRSystem()
+ {
+ CheckClear();
+ if (m_pVRSystem == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRSystem_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRSystem = new CVRSystem(pInterface);
+ }
+ return m_pVRSystem;
+ }
+
+ public CVRChaperone VRChaperone()
+ {
+ CheckClear();
+ if (m_pVRChaperone == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRChaperone_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRChaperone = new CVRChaperone(pInterface);
+ }
+ return m_pVRChaperone;
+ }
+
+ public CVRChaperoneSetup VRChaperoneSetup()
+ {
+ CheckClear();
+ if (m_pVRChaperoneSetup == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRChaperoneSetup_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRChaperoneSetup = new CVRChaperoneSetup(pInterface);
+ }
+ return m_pVRChaperoneSetup;
+ }
+
+ public CVRCompositor VRCompositor()
+ {
+ CheckClear();
+ if (m_pVRCompositor == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRCompositor_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRCompositor = new CVRCompositor(pInterface);
+ }
+ return m_pVRCompositor;
+ }
+
+ public CVRHeadsetView VRHeadsetView()
+ {
+ CheckClear();
+ if (m_pVRHeadsetView == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRHeadsetView_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRHeadsetView = new CVRHeadsetView(pInterface);
+ }
+ return m_pVRHeadsetView;
+ }
+
+ public CVROverlay VROverlay()
+ {
+ CheckClear();
+ if (m_pVROverlay == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVROverlay_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVROverlay = new CVROverlay(pInterface);
+ }
+ return m_pVROverlay;
+ }
+
+ public CVROverlayView VROverlayView()
+ {
+ CheckClear();
+ if (m_pVROverlayView == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVROverlayView_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVROverlayView = new CVROverlayView(pInterface);
+ }
+ return m_pVROverlayView;
+ }
+
+ public CVRRenderModels VRRenderModels()
+ {
+ CheckClear();
+ if (m_pVRRenderModels == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRRenderModels_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRRenderModels = new CVRRenderModels(pInterface);
+ }
+ return m_pVRRenderModels;
+ }
+
+ public CVRExtendedDisplay VRExtendedDisplay()
+ {
+ CheckClear();
+ if (m_pVRExtendedDisplay == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRExtendedDisplay_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRExtendedDisplay = new CVRExtendedDisplay(pInterface);
+ }
+ return m_pVRExtendedDisplay;
+ }
+
+ public CVRSettings VRSettings()
+ {
+ CheckClear();
+ if (m_pVRSettings == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRSettings_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRSettings = new CVRSettings(pInterface);
+ }
+ return m_pVRSettings;
+ }
+
+ public CVRApplications VRApplications()
+ {
+ CheckClear();
+ if (m_pVRApplications == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRApplications_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRApplications = new CVRApplications(pInterface);
+ }
+ return m_pVRApplications;
+ }
+
+ public CVRScreenshots VRScreenshots()
+ {
+ CheckClear();
+ if (m_pVRScreenshots == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRScreenshots_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRScreenshots = new CVRScreenshots(pInterface);
+ }
+ return m_pVRScreenshots;
+ }
+
+ public CVRTrackedCamera VRTrackedCamera()
+ {
+ CheckClear();
+ if (m_pVRTrackedCamera == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRTrackedCamera_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRTrackedCamera = new CVRTrackedCamera(pInterface);
+ }
+ return m_pVRTrackedCamera;
+ }
+
+ public CVRInput VRInput()
+ {
+ CheckClear();
+ if (m_pVRInput == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix+IVRInput_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRInput = new CVRInput(pInterface);
+ }
+ return m_pVRInput;
+ }
+
+ public CVRIOBuffer VRIOBuffer()
+ {
+ CheckClear();
+ if (m_pVRIOBuffer == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix + IVRIOBuffer_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRIOBuffer = new CVRIOBuffer(pInterface);
+ }
+ return m_pVRIOBuffer;
+ }
+
+ public CVRSpatialAnchors VRSpatialAnchors()
+ {
+ CheckClear();
+ if (m_pVRSpatialAnchors == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix + IVRSpatialAnchors_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRSpatialAnchors = new CVRSpatialAnchors(pInterface);
+ }
+ return m_pVRSpatialAnchors;
+ }
+
+ public CVRDebug VRDebug()
+ {
+ CheckClear();
+ if (m_pVRDebug == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix + IVRDebug_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRDebug = new CVRDebug(pInterface);
+ }
+ return m_pVRDebug;
+ }
+
+ public CVRNotifications VRNotifications()
+ {
+ CheckClear();
+ if (m_pVRNotifications == null)
+ {
+ var eError = EVRInitError.None;
+ var pInterface = OpenVRInterop.GetGenericInterface(FnTable_Prefix + IVRNotifications_Version, ref eError);
+ if (pInterface != IntPtr.Zero && eError == EVRInitError.None)
+ m_pVRNotifications = new CVRNotifications(pInterface);
+ }
+ return m_pVRNotifications;
+ }
+
+ private CVRSystem m_pVRSystem;
+ private CVRChaperone m_pVRChaperone;
+ private CVRChaperoneSetup m_pVRChaperoneSetup;
+ private CVRCompositor m_pVRCompositor;
+ private CVRHeadsetView m_pVRHeadsetView;
+ private CVROverlay m_pVROverlay;
+ private CVROverlayView m_pVROverlayView;
+ private CVRRenderModels m_pVRRenderModels;
+ private CVRExtendedDisplay m_pVRExtendedDisplay;
+ private CVRSettings m_pVRSettings;
+ private CVRApplications m_pVRApplications;
+ private CVRScreenshots m_pVRScreenshots;
+ private CVRTrackedCamera m_pVRTrackedCamera;
+ private CVRInput m_pVRInput;
+ private CVRIOBuffer m_pVRIOBuffer;
+ private CVRSpatialAnchors m_pVRSpatialAnchors;
+ private CVRNotifications m_pVRNotifications;
+ private CVRDebug m_pVRDebug;
+ };
+
+ private static COpenVRContext _OpenVRInternal_ModuleContext = null;
+ static COpenVRContext OpenVRInternal_ModuleContext
+ {
+ get
+ {
+ if (_OpenVRInternal_ModuleContext == null)
+ _OpenVRInternal_ModuleContext = new COpenVRContext();
+ return _OpenVRInternal_ModuleContext;
+ }
+ }
+
+ public static CVRSystem System { get { return OpenVRInternal_ModuleContext.VRSystem(); } }
+ public static CVRChaperone Chaperone { get { return OpenVRInternal_ModuleContext.VRChaperone(); } }
+ public static CVRChaperoneSetup ChaperoneSetup { get { return OpenVRInternal_ModuleContext.VRChaperoneSetup(); } }
+ public static CVRCompositor Compositor { get { return OpenVRInternal_ModuleContext.VRCompositor(); } }
+ public static CVRHeadsetView HeadsetView { get { return OpenVRInternal_ModuleContext.VRHeadsetView(); } }
+ public static CVROverlay Overlay { get { return OpenVRInternal_ModuleContext.VROverlay(); } }
+ public static CVROverlayView OverlayView { get { return OpenVRInternal_ModuleContext.VROverlayView(); } }
+ public static CVRRenderModels RenderModels { get { return OpenVRInternal_ModuleContext.VRRenderModels(); } }
+ public static CVRExtendedDisplay ExtendedDisplay { get { return OpenVRInternal_ModuleContext.VRExtendedDisplay(); } }
+ public static CVRSettings Settings { get { return OpenVRInternal_ModuleContext.VRSettings(); } }
+ public static CVRApplications Applications { get { return OpenVRInternal_ModuleContext.VRApplications(); } }
+ public static CVRScreenshots Screenshots { get { return OpenVRInternal_ModuleContext.VRScreenshots(); } }
+ public static CVRTrackedCamera TrackedCamera { get { return OpenVRInternal_ModuleContext.VRTrackedCamera(); } }
+ public static CVRInput Input { get { return OpenVRInternal_ModuleContext.VRInput(); } }
+ public static CVRIOBuffer IOBuffer { get { return OpenVRInternal_ModuleContext.VRIOBuffer(); } }
+ public static CVRSpatialAnchors SpatialAnchors { get { return OpenVRInternal_ModuleContext.VRSpatialAnchors(); } }
+ public static CVRNotifications Notifications { get { return OpenVRInternal_ModuleContext.VRNotifications(); } }
+ public static CVRDebug Debug { get { return OpenVRInternal_ModuleContext.VRDebug(); } }
+
+
+ /** Finds the active installation of vrclient.dll and initializes it */
+ public static CVRSystem Init(ref EVRInitError peError, EVRApplicationType eApplicationType = EVRApplicationType.VRApplication_Scene, string pchStartupInfo= "")
+ {
+ try
+ {
+ VRToken = InitInternal2(ref peError, eApplicationType, pchStartupInfo);
+ }
+ catch (EntryPointNotFoundException)
+ {
+ VRToken = InitInternal(ref peError, eApplicationType);
+ }
+
+ OpenVRInternal_ModuleContext.Clear();
+
+ if (peError != EVRInitError.None)
+ return null;
+
+ bool bInterfaceValid = IsInterfaceVersionValid(IVRSystem_Version);
+ if (!bInterfaceValid)
+ {
+ ShutdownInternal();
+ peError = EVRInitError.Init_InterfaceNotFound;
+ return null;
+ }
+
+ return OpenVR.System;
+ }
+
+ /** unloads vrclient.dll. Any interface pointers from the interface are
+ * invalid after this point */
+ public static void Shutdown()
+ {
+ ShutdownInternal();
+ }
+""")
+
+print("}\n\n");
+
+print ("""
+}
+#endif
+""")