diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py index 2a5412f5..e7d25fea 100755 --- a/vrclient_x64/gen_wrapper.py +++ b/vrclient_x64/gen_wrapper.py @@ -121,6 +121,8 @@ EXEMPT_STRUCTS = { "HmdVector3_t", "HmdVector3d_t", "HmdVector4_t", + "IntersectionMaskCircle_t", + "IntersectionMaskRectangle_t", } # structs for which the size is important, either because of arrays or size parameters @@ -213,6 +215,7 @@ all_records = {} all_structs = {} all_sources = {} all_versions = {} +unique_structs = [] MANUAL_METHODS = { @@ -271,8 +274,24 @@ class BasicType: def __init__(self, type, abi): self._type = type.get_canonical() self._abi = abi + self._decl_order = 0 + self._conv_cache = {} + + self.size = self._type.get_size() + self.id = self._type.spelling + + @property + def order(self): + return self._decl_order + + def set_used(self, order=-1): + if self._decl_order <= order: + return + self._decl_order = order def needs_conversion(self, other): + if self._type.kind == TypeKind.POINTER and self._type.get_pointee().kind == TypeKind.FUNCTIONPROTO: + return self._abi != other._abi return False @@ -282,6 +301,7 @@ class Struct: self._sdkver = sdkver self._abi = abi self._fields = None + self._decl_order = 0 self._conv_cache = {} self.name = canonical_typename(self._cursor) @@ -291,6 +311,19 @@ class Struct: self.align = self.type.get_align() self.id = f'{abi}_{self.name}_{sdkver}' + if self._cursor.spelling in EXEMPT_STRUCTS: + self._fields = [Padding(0, self.size)] + + @property + def order(self): + return self._decl_order + + def set_used(self, order=-1): + if self._decl_order <= order: + return + self._decl_order = order + [f._type.set_used(order - 1) for f in self.fields] + @property def padded_fields(self): if self._fields: return self._fields @@ -391,6 +424,7 @@ class Class: self._sdkver = sdkver self._abi = abi self._methods = None + self._decl_order = 0 self.name = cursor.spelling self.filename = SDK_CLASSES.get(self.name, None) @@ -398,6 +432,7 @@ class Class: self.version = versions.get(self.name, "") self.type = self._cursor.type.get_canonical() + self.id = f'{abi}_{self.name}_{sdkver}' @property def methods(self): @@ -425,9 +460,21 @@ class Class: return self.name return f'{self.name}_{self.version}' + @property + def order(self): + return self._decl_order + + def set_used(self, order=-1): + if self._decl_order <= order: + return + self._decl_order = order + def needs_conversion(self, other): return self._abi[0] != other._abi[0] + def __eq__(self, other): + return self._abi[0] == other._abi[0] + def write_definition(self, out, prefix): out(f'struct {prefix}{self.full_name}\n') out(u'{\n') @@ -543,6 +590,11 @@ def declspec(decl, name, prefix): if decl.kind == TypeKind.ENUM: return f'uint{decl.get_size() * 8}_t{name}' + type_name = decl.spelling.removeprefix("const ") + type_name = decl.spelling.removeprefix("vr::") + if type_name.startswith(('IVR', 'ID3D')): + return f'{const}void /*{type_name}*/{name}' + real_name = canonical_typename(decl) real_name = real_name.removeprefix("const ") real_name = real_name.removeprefix("vr::") @@ -1492,6 +1544,43 @@ def load(sdkver): return versions, sources +def classify_struct(name): + if name in EXEMPT_STRUCTS: + return None + structs = all_structs[name] + + prev = [] + versions = {} + unique = True + + for sdkver in filter(lambda v: v in structs, reversed(SDK_VERSIONS)): + abis = [structs[sdkver][a] for a in ABIS] + + if any(abis[0].needs_conversion(a) for a in abis[1:]): + unique = False + + def is_always_compatible(other): + for a, b in zip(abis, other): + if a.needs_conversion(b): + return False + return True + + compat = next((k for k, v in prev if is_always_compatible(v)), None) + if compat: + versions[sdkver] = versions[compat] + else: + [abi.set_used() for abi in abis] # make sure order is computed + versions[sdkver] = f"{name}_{display_sdkver(sdkver)}" + prev += [(sdkver, abis)] + + if unique: + unique_structs.append(name) + + if len(set(versions.values())) == 1: + versions = {sdkver: name for sdkver in versions.keys()} + return versions + + def generate(sdkver, structs): print(f'generating SDK version {sdkver}...') for child in structs['u32'].values(): @@ -1553,6 +1642,31 @@ for i, sdkver in enumerate(reversed(SDK_VERSIONS)): print('parsing SDKs... 100%') +tmp_structs = {} + +for i, name in enumerate(all_structs.keys()): + print(f'classifying structs... {i * 100 // len(all_structs.keys())}%', end='\r') + versions = classify_struct(name) + for sdkver in SDK_VERSIONS: + if not versions or sdkver not in versions: continue + all_versions[sdkver][name] = versions[sdkver] + +def struct_order(tuple): + name, structs = tuple + order = (struct.order for abis in structs.values() + for struct in abis.values()) + return (min(order), name) + +for name, structs in sorted(all_structs.items(), key=struct_order): + tmp_structs[name] = {} + for sdkver in filter(lambda v: v in structs, SDK_VERSIONS): + tmp_structs[name][sdkver] = {a: structs[sdkver][a] for a in ABIS} + +all_structs = tmp_structs + +print('classifying structs... 100%') + + for klass in all_classes.values(): with open(f"vrclient_x64/win{klass.name}.c", "w") as file: out = file.write