mirror of
https://github.com/ValveSoftware/Proton.git
synced 2024-12-28 15:45:50 +03:00
lsteamclient: Generate struct definitions for all abis.
CW-Bug-Id: #22729
This commit is contained in:
parent
cafc3fb8e7
commit
7c622566cf
@ -297,3 +297,4 @@ SOURCES = \
|
||||
struct_converters_157.cpp \
|
||||
struct_converters_158.cpp \
|
||||
unix_steam_client_manual.cpp \
|
||||
unixlib_generated.cpp \
|
||||
|
@ -510,6 +510,31 @@ class Struct:
|
||||
def fields(self):
|
||||
return [f for f in self.padded_fields if type(f) is not Padding]
|
||||
|
||||
def write_definition(self, out, prefix):
|
||||
version = all_versions[sdkver][self.name]
|
||||
kind = 'union' if type(self) is Union else 'struct'
|
||||
wrapped = len(prefix) > 0
|
||||
|
||||
out(f'#pragma pack( push, {self.align} )\n')
|
||||
out(f'{kind} {prefix}{version}\n')
|
||||
out(u'{\n')
|
||||
for f in self.padded_fields:
|
||||
if type(f) is Field:
|
||||
out(f' {declspec(f._cursor, f.name, prefix, wrapped)};\n')
|
||||
else:
|
||||
out(f' uint8_t __pad_{f.offset}[{f.size}];\n')
|
||||
out(u'};\n')
|
||||
out(u'#pragma pack( pop )\n\n')
|
||||
|
||||
def write_checks(self, out, prefix):
|
||||
version = all_versions[sdkver][self.name]
|
||||
|
||||
out(f'C_ASSERT( sizeof({prefix}{version}) >= {self.size} );\n')
|
||||
for f in self.fields:
|
||||
out(f'C_ASSERT( offsetof({prefix}{version}, {f.name}) == {f.offset} );\n')
|
||||
out(f'C_ASSERT( sizeof({prefix}{version}().{f.name}) >= {f.size} );\n')
|
||||
out(u'\n')
|
||||
|
||||
def needs_conversion(self, other):
|
||||
if other.id in self._conv_cache:
|
||||
return self._conv_cache[other.id]
|
||||
@ -751,13 +776,13 @@ def callconv(cursor, prefix):
|
||||
|
||||
|
||||
def declspec_func(decl, name, prefix):
|
||||
ret = declspec(decl.get_result(), "", prefix)
|
||||
params = [declspec(a, "", prefix) for a in decl.argument_types()]
|
||||
ret = declspec(decl.get_result(), "", prefix, False)
|
||||
params = [declspec(a, "", prefix, False) for a in decl.argument_types()]
|
||||
params = ", ".join(params) if len(params) else "void"
|
||||
return f'{ret} ({name})({params})'
|
||||
|
||||
|
||||
def declspec(decl, name, prefix):
|
||||
def declspec(decl, name, prefix, wrapped=False):
|
||||
call = callconv(decl, prefix)
|
||||
if type(decl) is Cursor:
|
||||
decl = decl.type
|
||||
@ -768,10 +793,16 @@ def declspec(decl, name, prefix):
|
||||
return declspec_func(decl, name, prefix)
|
||||
if decl.kind in (TypeKind.POINTER, TypeKind.LVALUEREFERENCE):
|
||||
decl = decl.get_pointee()
|
||||
return declspec(decl, f"*{call}{const}{name}", prefix)
|
||||
spec = declspec(decl, f"*{call}{const}{name}", prefix, False)
|
||||
if wrapped:
|
||||
return f'{prefix.upper()}PTR({spec}, {name})'
|
||||
return spec
|
||||
if decl.kind == TypeKind.CONSTANTARRAY:
|
||||
decl, count = decl.element_type, decl.element_count
|
||||
return declspec(decl, f"({const}{name})[{count}]", prefix)
|
||||
if wrapped:
|
||||
spec = declspec(decl, const, prefix, False)
|
||||
return f'{prefix.upper()}ARRAY({spec}, {count}, {name})'
|
||||
return declspec(decl, f"({const}{name})[{count}]", prefix, False)
|
||||
|
||||
if len(name):
|
||||
name = f' {name}'
|
||||
@ -782,6 +813,13 @@ def declspec(decl, name, prefix):
|
||||
return f'uint{decl.get_size() * 8}_t{name}'
|
||||
|
||||
type_name = decl.spelling.removeprefix("const ")
|
||||
if prefix not in (None, "win") and decl.kind == TypeKind.RECORD \
|
||||
and type_name in all_versions[sdkver] \
|
||||
and type_name not in EXEMPT_STRUCTS:
|
||||
if type_name in unique_structs:
|
||||
return f'{const}{all_versions[sdkver][type_name]}{name}'
|
||||
return f'{const}{prefix}{all_versions[sdkver][type_name]}{name}'
|
||||
|
||||
if prefix == "win" and param_needs_conversion(decl):
|
||||
return f"{const}win{type_name}_{sdkver}{name}"
|
||||
if type_name.startswith('ISteam'):
|
||||
@ -793,6 +831,8 @@ def declspec(decl, name, prefix):
|
||||
if type_name.startswith(('uint', 'unsigned')):
|
||||
return f'{const}uint{decl.get_size() * 8}_t{name}'
|
||||
|
||||
if 'unnamed union' in decl.spelling:
|
||||
return f'{const}struct {{ uint8_t _[{decl.get_size()}]; }}{name}'
|
||||
return f'{decl.spelling}{name}'
|
||||
|
||||
|
||||
@ -861,20 +901,20 @@ def handle_method_cpp(method, classname, cppname, out):
|
||||
type_name = underlying_typename(param)
|
||||
|
||||
if param.type.kind != TypeKind.POINTER:
|
||||
out(f' {declspec(param, f"lin_{name}", "u_")};\n')
|
||||
out(f' {declspec(param, f"lin_{name}", None)};\n')
|
||||
out(f' win_to_lin_struct_{type_name}_{sdkver}( ¶ms->{name}, &lin_{name} );\n')
|
||||
continue
|
||||
|
||||
pointee = param.type.get_pointee()
|
||||
if pointee.kind == TypeKind.POINTER:
|
||||
need_output[name] = param
|
||||
out(f' {declspec(pointee, f"lin_{name}", "u_")};\n')
|
||||
out(f' {declspec(pointee, f"lin_{name}", None)};\n')
|
||||
continue
|
||||
|
||||
if not pointee.is_const_qualified():
|
||||
need_output[name] = param
|
||||
|
||||
out(f' {declspec(pointee, f"lin_{name}", "u_")};\n')
|
||||
out(f' {declspec(pointee, f"lin_{name}", None)};\n')
|
||||
out(f' win_to_lin_struct_{type_name}_{sdkver}( params->{name}, &lin_{name} );\n')
|
||||
|
||||
for name, param in sorted(manual_convert.items()):
|
||||
@ -1506,8 +1546,8 @@ for i, name in enumerate(all_structs.keys()):
|
||||
if not versions or sdkver not in versions: continue
|
||||
all_versions[sdkver][name] = versions[sdkver]
|
||||
|
||||
def struct_order(tuple):
|
||||
name, structs = tuple
|
||||
def struct_order(x):
|
||||
name, structs = x if type(x) is tuple else (x, all_structs[x])
|
||||
order = (struct.order for abis in structs.values()
|
||||
for struct in abis.values())
|
||||
return (min(order), name)
|
||||
@ -1559,6 +1599,129 @@ with open('struct_converters.h', 'a') as file:
|
||||
|
||||
out(u'#endif /* __STRUCT_CONVERTERS_H */\n')
|
||||
|
||||
|
||||
declared = {}
|
||||
|
||||
with open('steamclient_structs_generated.h', 'w') as file:
|
||||
out = file.write
|
||||
|
||||
for name in sorted(unique_structs, key=struct_order):
|
||||
if name in EXEMPT_STRUCTS: continue
|
||||
for sdkver, abis in all_structs[name].items():
|
||||
if name not in all_versions[sdkver]: continue
|
||||
|
||||
version = all_versions[sdkver][name]
|
||||
if f'struct {version}' in declared: continue
|
||||
declared[f'struct {version}'] = True
|
||||
|
||||
kind = 'union' if type(abis['w64']) is Union else 'struct'
|
||||
|
||||
out(f'typedef {kind} {version} {version};\n')
|
||||
abis['w64'].write_definition(out, "")
|
||||
|
||||
for name, structs in all_structs.items():
|
||||
if name in EXEMPT_STRUCTS: continue
|
||||
if name in unique_structs: continue
|
||||
for sdkver, abis in structs.items():
|
||||
if name not in all_versions[sdkver]: continue
|
||||
|
||||
version = all_versions[sdkver][name]
|
||||
if f'typedef {version}' in declared: continue
|
||||
declared[f'typedef {version}'] = True
|
||||
|
||||
kind = 'union' if type(abis['w64']) is Union else 'struct'
|
||||
|
||||
if type(abis['w64']) is Class:
|
||||
out(f'typedef {kind} u_{version} u_{version};\n')
|
||||
out(f'typedef {kind} u_{version} u64_{version};\n')
|
||||
out(f'typedef {kind} u_{version} u32_{version};\n')
|
||||
out(f'typedef {kind} w_{version} w_{version};\n')
|
||||
out(f'typedef {kind} w_{version} w64_{version};\n')
|
||||
out(f'typedef {kind} w_{version} w32_{version};\n')
|
||||
continue
|
||||
|
||||
if abis["w64"].needs_conversion(abis["u64"]):
|
||||
out(f'typedef {kind} u64_{version} u64_{version};\n')
|
||||
else:
|
||||
out(f'typedef {kind} w64_{version} u64_{version};\n')
|
||||
out(f'typedef {kind} w64_{version} w64_{version};\n')
|
||||
|
||||
if abis["w32"].needs_conversion(abis["u32"]):
|
||||
out(f'typedef {kind} u32_{version} u32_{version};\n')
|
||||
else:
|
||||
out(f'typedef {kind} w32_{version} u32_{version};\n')
|
||||
out(f'typedef {kind} w32_{version} w32_{version};\n')
|
||||
|
||||
for name, structs in all_structs.items():
|
||||
if name in EXEMPT_STRUCTS: continue
|
||||
if name in unique_structs: continue
|
||||
for sdkver, abis in structs.items():
|
||||
if name not in all_versions[sdkver]: continue
|
||||
|
||||
version = all_versions[sdkver][name]
|
||||
if f'struct {version}' in declared: continue
|
||||
declared[f'struct {version}'] = True
|
||||
|
||||
kind = 'union' if type(abis['w64']) is Union else 'struct'
|
||||
|
||||
if type(abis['w64']) is Class:
|
||||
abis['w64'].write_definition(out, "w_")
|
||||
abis['u64'].write_definition(out, "u_")
|
||||
continue
|
||||
|
||||
abis['w64'].write_definition(out, "w64_")
|
||||
if abis["w64"].needs_conversion(abis["u64"]):
|
||||
abis['u64'].write_definition(out, "u64_")
|
||||
|
||||
abis['w32'].write_definition(out, "w32_")
|
||||
if abis["w32"].needs_conversion(abis["u32"]):
|
||||
abis['u32'].write_definition(out, "u32_")
|
||||
|
||||
out(u'#ifdef __i386__\n')
|
||||
out(f'typedef w32_{version} w_{version};\n')
|
||||
out(f'typedef u32_{version} u_{version};\n')
|
||||
out(u'#endif\n')
|
||||
out(u'#ifdef __x86_64__\n')
|
||||
out(f'typedef w64_{version} w_{version};\n')
|
||||
out(f'typedef u64_{version} u_{version};\n')
|
||||
out(u'#endif\n')
|
||||
out(u'\n')
|
||||
|
||||
|
||||
with open('unixlib_generated.cpp', 'w') as file:
|
||||
out = file.write
|
||||
|
||||
out(u'/* This file is auto-generated, do not edit. */\n\n')
|
||||
out(u'#include "steamclient_structs.h"\n\n')
|
||||
|
||||
for name in sorted(unique_structs, key=struct_order):
|
||||
for sdkver, abis in all_structs[name].items():
|
||||
if name not in all_versions[sdkver]: continue
|
||||
|
||||
version = all_versions[sdkver][name]
|
||||
if f'checks {version}' in declared: continue
|
||||
declared[f'checks {version}'] = True
|
||||
|
||||
abis['w64'].write_checks(out, "")
|
||||
|
||||
for name, structs in all_structs.items():
|
||||
if name in EXEMPT_STRUCTS: continue
|
||||
if name in unique_structs: continue
|
||||
for sdkver, abis in structs.items():
|
||||
if name not in all_versions[sdkver]: continue
|
||||
|
||||
version = all_versions[sdkver][name]
|
||||
if f'checks {version}' in declared: continue
|
||||
declared[f'checks {version}'] = True
|
||||
|
||||
if type(abis['w64']) is Class:
|
||||
continue
|
||||
|
||||
abis['w64'].write_checks(out, "w64_")
|
||||
abis['u64'].write_checks(out, "u64_")
|
||||
abis['w32'].write_checks(out, "w32_")
|
||||
abis['u32'].write_checks(out, "u32_")
|
||||
|
||||
getapifile = open("cb_getapi_table.dat", "w")
|
||||
cbsizefile = open("cb_getapi_sizes.dat", "w")
|
||||
|
||||
|
58
lsteamclient/steamclient_structs.h
Normal file
58
lsteamclient/steamclient_structs.h
Normal file
@ -0,0 +1,58 @@
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <windef.h>
|
||||
#include <winbase.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <array>
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define U64_ARRAY( type, count, name ) std::array<type, count> name
|
||||
#define U32_ARRAY( type, count, name ) std::array<type, count> name
|
||||
#define W64_ARRAY( type, count, name ) std::array<type, count> name
|
||||
#define W32_ARRAY( type, count, name ) std::array<type, count> name
|
||||
#else
|
||||
#define U64_ARRAY( type, count, name ) type name[count]
|
||||
#define U32_ARRAY( type, count, name ) type name[count]
|
||||
#define W64_ARRAY( type, count, name ) type name[count]
|
||||
#define W32_ARRAY( type, count, name ) type name[count]
|
||||
#endif
|
||||
|
||||
#define W_CDECL __cdecl
|
||||
#define W_STDCALL __stdcall
|
||||
#define U_CDECL __attribute__((sysv_abi))
|
||||
#define U_STDCALL __attribute__((sysv_abi))
|
||||
|
||||
#ifdef __i386__
|
||||
#define U64_PTR( decl, name ) uint64_t name
|
||||
#define U32_PTR( decl, name ) decl
|
||||
#define W64_PTR( decl, name ) uint64_t name
|
||||
#define W32_PTR( decl, name ) decl
|
||||
#define U_PTR U32_PTR
|
||||
#define W_PTR W32_PTR
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
#define U64_PTR( decl, name ) decl
|
||||
#define U32_PTR( decl, name ) uint32_t name
|
||||
#define W64_PTR( decl, name ) decl
|
||||
#define W32_PTR( decl, name ) uint32_t name
|
||||
#define U_PTR U64_PTR
|
||||
#define W_PTR W64_PTR
|
||||
#endif
|
||||
|
||||
typedef struct { uint8_t _[8]; } CSteamID;
|
||||
typedef struct { uint8_t _[8]; } CGameID;
|
||||
typedef struct { uint8_t _[20]; } SteamIPAddress_t;
|
||||
|
||||
#include "steamclient_structs_generated.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
9510
lsteamclient/steamclient_structs_generated.h
Normal file
9510
lsteamclient/steamclient_structs_generated.h
Normal file
File diff suppressed because it is too large
Load Diff
8438
lsteamclient/unixlib_generated.cpp
Normal file
8438
lsteamclient/unixlib_generated.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user