diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py index 282acde8..c2c94861 100755 --- a/vrclient_x64/gen_wrapper.py +++ b/vrclient_x64/gen_wrapper.py @@ -342,6 +342,10 @@ def ivrrendermodels_load_into_texture_d3d11_async(cppname, method): assert "005" in cppname or "006" in cppname return "ivrrendermodels_load_into_texture_d3d11_async" +def ivrmailbox_undoc3(cppname, method): + assert "001" in cppname + return "ivrmailbox_undoc3" + method_overrides = [ ("IVRClientCore", "Init", ivrclientcore_init), ("IVRClientCore", "GetGenericInterface", ivrclientcore_get_generic_interface), @@ -355,6 +359,7 @@ method_overrides = [ ("IVRRenderModels", "LoadTextureD3D11_Async", ivrrendermodels_load_texture_d3d11_async), ("IVRRenderModels", "FreeTextureD3D11", ivrrendermodels_free_texture_d3d11), ("IVRRenderModels", "LoadIntoTextureD3D11_Async", ivrrendermodels_load_into_texture_d3d11_async), + ("IVRMailbox", "undoc3", ivrmailbox_undoc3), ] method_overrides_data = [ diff --git a/vrclient_x64/vrclient_x64/json_converter.cpp b/vrclient_x64/vrclient_x64/json_converter.cpp new file mode 100644 index 00000000..076d95b3 --- /dev/null +++ b/vrclient_x64/vrclient_x64/json_converter.cpp @@ -0,0 +1,109 @@ +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(vrclient); + +#include "vrclient_private.h" + +#include "json/json.h" + +extern "C" { + +static bool ends_with(const std::string &s, char c) +{ + auto e = s.end(); + if(e != s.begin()){ + --e; + return *e == c; + } + return false; +} + +static bool convert_path_to_win(std::string &s) +{ + bool need_slash = ends_with(s, '\\') || ends_with(s, '/'); + + DWORD sz = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); + if(!sz) + { + return false; + } + + WCHAR *dos_path = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, sz * sizeof(WCHAR)); + if(!dos_path) + { + return false; + } + + sz = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, dos_path, sz); + if(!sz) + { + HeapFree(GetProcessHeap(), 0, dos_path); + return false; + } + + char *unix_path = wine_get_unix_file_name(dos_path); + if(!unix_path) + { + HeapFree(GetProcessHeap(), 0, dos_path); + return false; + } + + /* XXX assuming the system encoding is UTF-8 */ + s = unix_path; + + if(need_slash) + s += '/'; + + HeapFree(GetProcessHeap(), 0, unix_path); + HeapFree(GetProcessHeap(), 0, dos_path); + + return true; +} + +char *json_convert_paths(const char *input) +{ + Json::Reader reader; + Json::Value root; + + if(!reader.parse(input, root)) + return NULL; + + if(root.isMember("type") && + root["type"].isString() && + root["type"] == "set_paths") + { + if(root.isMember("webroot") && + root["webroot"].isString()) + { + std::string path(root["webroot"].asString()); + if(convert_path_to_win(path)) + root["webroot"] = path; + } + + if(root.isMember("models") && + root["models"].isString()) + { + std::string path(root["models"].asString()); + if(convert_path_to_win(path)) + root["models"] = path; + } + + Json::FastWriter writer; + + std::string contents(writer.write(root)); + + char *ret = (char *)malloc(contents.length() + 1); + if(!ret) + return NULL; + + size_t len = contents.copy(ret, contents.length()); + ret[len] = 0; + + return ret; + } + + return NULL; +} + +} diff --git a/vrclient_x64/vrclient_x64/vrclient_main.c b/vrclient_x64/vrclient_x64/vrclient_main.c index 79bf03de..ea8e375e 100644 --- a/vrclient_x64/vrclient_x64/vrclient_main.c +++ b/vrclient_x64/vrclient_x64/vrclient_main.c @@ -1270,6 +1270,20 @@ EVRRenderModelError ivrrendermodels_load_into_texture_d3d11_async( return error; } +vrmb_typeb ivrmailbox_undoc3( + vrmb_typeb (*cpp_func)(void *, vrmb_typea, const char *, const char *), + void *linux_side, vrmb_typea a, const char *b, const char *c, unsigned int version) +{ + vrmb_typeb r; + char *converted = json_convert_paths(c); + + r = cpp_func(linux_side, a, b, converted ? converted : c); + + free(converted); + + return r; +} + void destroy_compositor_data(struct compositor_data *data) { IWineD3D11Device *wined3d_device; diff --git a/vrclient_x64/vrclient_x64/vrclient_private.h b/vrclient_x64/vrclient_x64/vrclient_private.h index e7fe066a..e8d82521 100644 --- a/vrclient_x64/vrclient_x64/vrclient_private.h +++ b/vrclient_x64/vrclient_x64/vrclient_private.h @@ -6,6 +6,16 @@ #define VRCLIENT_HAVE_DXVK #endif +#if __cplusplus +extern "C" { +#endif + +char *json_convert_paths(const char *input); + +#if __cplusplus +} +#endif + /* TODO these should be generated */ typedef struct __winISteamClient winISteamClient; typedef struct __winISteamUser winISteamUser; diff --git a/vrclient_x64/vrclient_x64/winIVRMailbox.c b/vrclient_x64/vrclient_x64/winIVRMailbox.c index dae5cff5..f7b65885 100644 --- a/vrclient_x64/vrclient_x64/winIVRMailbox.c +++ b/vrclient_x64/vrclient_x64/winIVRMailbox.c @@ -43,7 +43,7 @@ DEFINE_THISCALL_WRAPPER(winIVRMailbox_IVRMailbox_001_undoc3, 20) vrmb_typeb __thiscall winIVRMailbox_IVRMailbox_001_undoc3(winIVRMailbox_IVRMailbox_001 *_this, vrmb_typea a, const char * b, const char * c) { TRACE("%p\n", _this); - return cppIVRMailbox_IVRMailbox_001_undoc3(_this->linux_side, a, b, c); + return ivrmailbox_undoc3(cppIVRMailbox_IVRMailbox_001_undoc3, _this->linux_side, a, b, c, 1); } DEFINE_THISCALL_WRAPPER(winIVRMailbox_IVRMailbox_001_undoc4, 24)