mirror of
https://github.com/suyu-emu/Yucom.git
synced 2026-09-21 13:22:43 -07:00
lsteamclient: Reimplement alloc_callback_wtou(), convert_callback_utow() in manual code using generated table.
And try to handle the case of non-matching Windows callback length similar to before commit 6a5d5757ca2fbed232481f4e001114e7ba87560c. CW-Bug-Id: #23550
This commit is contained in:
+19
-52
@@ -1700,73 +1700,40 @@ with open('unixlib_generated.cpp', 'w') as file:
|
||||
out(u'}\n')
|
||||
out(u'\n')
|
||||
|
||||
out(u'void *alloc_callback_wtou(int id, void *callback, int *callback_len)\n')
|
||||
out(u'{\n')
|
||||
out(u' int len;\n')
|
||||
out(u'\n')
|
||||
out(u'#define MAKE_CASE(id, wlen) ((uint64_t)(id) << 48) | ((uint64_t)(wlen) << 24)\n')
|
||||
out(u' switch (MAKE_CASE(id, *callback_len))\n')
|
||||
out(u' {\n')
|
||||
out(u'#ifdef __i386__\n')
|
||||
values = set()
|
||||
for cbid, sdkver, abis in sorted(callbacks, key=lambda x: x[0]):
|
||||
name, value = abis["u32"].name, (cbid, abis["w32"].size)
|
||||
if name in all_versions[sdkver]: name = all_versions[sdkver][name]
|
||||
if value not in values:
|
||||
out(f' case MAKE_CASE({cbid}, {abis["w32"].size}): len = {abis["u32"].size}; break; /* {name} */\n')
|
||||
else:
|
||||
out(f' /* case MAKE_CASE({cbid}, {abis["w32"].size}): len = {abis["u32"].size}; break; {name} */\n')
|
||||
values.add(value)
|
||||
out(u'#endif\n')
|
||||
out(u'#ifdef __x86_64__\n')
|
||||
values = set()
|
||||
for cbid, sdkver, abis in sorted(callbacks, key=lambda x: x[0]):
|
||||
name, value = abis["u64"].name, (cbid, abis["w64"].size)
|
||||
if name in all_versions[sdkver]: name = all_versions[sdkver][name]
|
||||
if value not in values:
|
||||
out(f' case MAKE_CASE({cbid}, {abis["w64"].size}): len = {abis["u64"].size}; break; /* {name} */\n')
|
||||
else:
|
||||
out(f' /* case MAKE_CASE({cbid}, {abis["w64"].size}): len = {abis["u64"].size}; break; {name} */\n')
|
||||
values.add(value)
|
||||
out(u'#endif\n')
|
||||
out(u' default: return callback;\n')
|
||||
out(u' }\n')
|
||||
out(u'#undef MAKE_CASE\n')
|
||||
out(u'\n')
|
||||
out(u' callback = malloc( len );\n')
|
||||
out(u' *callback_len = len;\n')
|
||||
out(u' return callback;\n')
|
||||
out(u'}\n')
|
||||
out(u'\n')
|
||||
|
||||
out(u'void convert_callback_utow(int id, void *u_callback, int u_callback_len, void *w_callback, int w_callback_len)\n')
|
||||
out(u'{\n')
|
||||
out(u'#define MAKE_CASE(id, wlen, ulen) ((uint64_t)(id) << 48) | ((uint64_t)(wlen) << 24) | (uint64_t)(ulen)\n')
|
||||
out(u' switch (MAKE_CASE(id, w_callback_len, u_callback_len))\n')
|
||||
out(u' {\n')
|
||||
out(u'#ifdef __i386__\n')
|
||||
out(u'const struct callback_def callback_data[] =\n{\n');
|
||||
values = set()
|
||||
for cbid, sdkver, abis in sorted(callbacks, key=lambda x: x[0]):
|
||||
name, value = abis["u32"].name, (cbid, abis["w32"].size, abis["u32"].size)
|
||||
if name in all_versions[sdkver]: name = all_versions[sdkver][name]
|
||||
|
||||
w_from_u = f'{name}_w_from_u'
|
||||
if not w_from_u in written_converters:
|
||||
w_from_u = u'nullptr'
|
||||
|
||||
if value not in values:
|
||||
out(f' case MAKE_CASE({cbid}, {abis["w32"].size}, {abis["u32"].size}): *(w_{name} *)w_callback = *(u_{name} *)u_callback; break;\n')
|
||||
out(f' {{ {cbid}, {sdkver}, {abis["w32"].size}, {abis["u32"].size}, {w_from_u} }},\n')
|
||||
else:
|
||||
out(f' /* case MAKE_CASE({cbid}, {abis["w32"].size}, {abis["u32"].size}): *(w_{name} *)w_callback = *(u_{name} *)u_callback; break; */\n')
|
||||
out(f' /*{{ {cbid}, {sdkver}, {abis["w32"].size}, {abis["u32"].size}, {w_from_u} }},*/\n')
|
||||
values.add(value)
|
||||
out(u'};\n');
|
||||
out(u'#endif\n')
|
||||
out(u'#ifdef __x86_64__\n')
|
||||
out(u'const struct callback_def callback_data[] =\n{\n');
|
||||
values = set()
|
||||
for cbid, sdkver, abis in sorted(callbacks, key=lambda x: x[0]):
|
||||
name, value = abis["u64"].name, (cbid, abis["w64"].size, abis["u64"].size)
|
||||
if name in all_versions[sdkver]: name = all_versions[sdkver][name]
|
||||
|
||||
w_from_u = f'{name}_w_from_u'
|
||||
if not w_from_u in written_converters:
|
||||
w_from_u = u'nullptr'
|
||||
|
||||
if value not in values:
|
||||
out(f' case MAKE_CASE({cbid}, {abis["w64"].size}, {abis["u64"].size}): *(w_{name} *)w_callback = *(u_{name} *)u_callback; break;\n')
|
||||
out(f' {{ {cbid}, {sdkver}, {abis["w64"].size}, {abis["u64"].size}, {w_from_u} }},\n')
|
||||
else:
|
||||
out(f' /* case MAKE_CASE({cbid}, {abis["w64"].size}, {abis["u64"].size}): *(w_{name} *)w_callback = *(u_{name} *)u_callback; break; */\n')
|
||||
out(f' /*{{ {cbid}, {sdkver}, {abis["w64"].size}, {abis["u64"].size}, {w_from_u} }},*/\n')
|
||||
values.add(value)
|
||||
out(u'};\n');
|
||||
out(u'#endif\n')
|
||||
out(u' default: memcpy( w_callback, u_callback, u_callback_len ); break;\n')
|
||||
out(u' }\n')
|
||||
out(u'#undef MAKE_CASE\n')
|
||||
out(u'}\n')
|
||||
out(u'const unsigned int callback_data_size = ARRAY_SIZE(callback_data);\n');
|
||||
|
||||
@@ -57,6 +57,17 @@ typedef void (W_CDECL *w_void_SteamAPI_PostAPIResultInProcess_t)(void);
|
||||
u_void_SteamAPI_PostAPIResultInProcess_t manual_convert_DEPRECATED_Set_SteamAPI_CPostAPIResultInProcess__a( w_void_SteamAPI_PostAPIResultInProcess_t );
|
||||
u_void_SteamAPI_PostAPIResultInProcess_t manual_convert_DEPRECATED_Remove_SteamAPI_CPostAPIResultInProcess__a( w_void_SteamAPI_PostAPIResultInProcess_t );
|
||||
|
||||
struct callback_def
|
||||
{
|
||||
int id;
|
||||
int sdkver;
|
||||
int w_callback_len;
|
||||
int u_callback_len;
|
||||
void (*conv_w_from_u)(void *dst, const void *src);
|
||||
};
|
||||
extern const struct callback_def callback_data[];
|
||||
extern const unsigned int callback_data_size;
|
||||
|
||||
void callback_message_utow( const u_CallbackMsg_t *u_msg, w_CallbackMsg_t *w_msg );
|
||||
void *alloc_callback_wtou( int id, void *callback, int *callback_len );
|
||||
void convert_callback_utow( int id, void *u_callback, int u_callback_len, void *w_callback, int w_callback_len );
|
||||
|
||||
@@ -648,3 +648,90 @@ unsigned int steamclient_unix_path_to_dos_path( bool api_result, const char *src
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct callback_def *find_first_callback_def_by_id( int id )
|
||||
{
|
||||
unsigned int l, r, m;
|
||||
|
||||
l = 0;
|
||||
r = callback_data_size;
|
||||
while (l < r)
|
||||
{
|
||||
m = (l + r) /2;
|
||||
if (callback_data[m].id == id)
|
||||
{
|
||||
while (m && callback_data[m - 1].id == id) --m;
|
||||
return &callback_data[m];
|
||||
}
|
||||
if (id < callback_data[m].id) r = m;
|
||||
else l = m + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *alloc_callback_wtou( int id, void *callback, int *callback_len )
|
||||
{
|
||||
const struct callback_def *c, *end, *best;
|
||||
|
||||
if (!(c = find_first_callback_def_by_id( id ))) return callback;
|
||||
|
||||
end = callback_data + callback_data_size;
|
||||
best = NULL;
|
||||
while (c != end && c->id == id)
|
||||
{
|
||||
if (c->w_callback_len == *callback_len)
|
||||
{
|
||||
best = c;
|
||||
break;
|
||||
}
|
||||
if (!best && *callback_len >= c->w_callback_len) best = c;
|
||||
++c;
|
||||
}
|
||||
|
||||
if (!best)
|
||||
{
|
||||
WARN( "len %d is too small for callback %d.\n", *callback_len, id );
|
||||
return callback;
|
||||
}
|
||||
if (best->w_callback_len != *callback_len)
|
||||
WARN( "Found len %d for id %d, len %d.\n", best->w_callback_len, id, *callback_len );
|
||||
*callback_len = best->u_callback_len;
|
||||
return malloc( *callback_len );
|
||||
}
|
||||
|
||||
void convert_callback_utow(int id, void *u_callback, int u_callback_len, void *w_callback, int w_callback_len)
|
||||
{
|
||||
const struct callback_def *c, *end, *best;
|
||||
|
||||
if (!(c = find_first_callback_def_by_id( id )))
|
||||
{
|
||||
memcpy( w_callback, u_callback, u_callback_len );
|
||||
return;
|
||||
}
|
||||
|
||||
end = callback_data + callback_data_size;
|
||||
best = NULL;
|
||||
while (c != end && c->id == id)
|
||||
{
|
||||
if (c->w_callback_len == w_callback_len && c->u_callback_len == u_callback_len)
|
||||
{
|
||||
best = c;
|
||||
break;
|
||||
}
|
||||
if (!best && c->u_callback_len == u_callback_len && c->w_callback_len <= w_callback_len)
|
||||
best = c;
|
||||
++c;
|
||||
}
|
||||
if (!best)
|
||||
{
|
||||
ERR( "Could not find id %d, u_callback_len %d, w_callback_len %d.\n", id, u_callback_len, w_callback_len );
|
||||
memcpy( w_callback, u_callback, std::min(w_callback_len, u_callback_len) );
|
||||
return;
|
||||
}
|
||||
|
||||
if (best->w_callback_len != w_callback_len || best->u_callback_len != u_callback_len)
|
||||
WARN( "Found len %d, %d for id %d, len %d, %d.\n", best->w_callback_len, best->u_callback_len,
|
||||
id, w_callback_len, u_callback_len );
|
||||
|
||||
if (best->conv_w_from_u) best->conv_w_from_u( w_callback, u_callback );
|
||||
else memcpy( w_callback, u_callback, u_callback_len );
|
||||
}
|
||||
|
||||
+216
-448
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user