steam_helper: Set up VR paths in steam.exe, not proton
This speeds up game launch times.
This commit is contained in:
parent
e1c5da52c6
commit
349df9c436
4 changed files with 326 additions and 85 deletions
|
@ -1149,7 +1149,7 @@ steam_configure: $(STEAMEXE_CONFIGURE_FILES)
|
||||||
|
|
||||||
steam: SHELL = $(CONTAINER_SHELL32)
|
steam: SHELL = $(CONTAINER_SHELL32)
|
||||||
steam: $(STEAMEXE_CONFIGURE_FILES) | $(WINE_BUILDTOOLS32) $(filter $(MAKECMDGOALS),wine64 wine32 wine)
|
steam: $(STEAMEXE_CONFIGURE_FILES) | $(WINE_BUILDTOOLS32) $(filter $(MAKECMDGOALS),wine64 wine32 wine)
|
||||||
+env PATH="$(abspath $(TOOLS_DIR32))/bin:$(PATH)" LDFLAGS="-m32" CXXFLAGS="-m32 -Wno-attributes $(COMMON_FLAGS) -g" CFLAGS="-m32 $(COMMON_FLAGS) -g" \
|
+env PATH="$(abspath $(TOOLS_DIR32))/bin:$(PATH)" LDFLAGS="-m32" CXXFLAGS="-std=gnu++11 -m32 -Wno-attributes $(COMMON_FLAGS) -g" CFLAGS="-m32 $(COMMON_FLAGS) -g" \
|
||||||
$(MAKE) -C $(STEAMEXE_OBJ)
|
$(MAKE) -C $(STEAMEXE_OBJ)
|
||||||
[ x"$(STRIP)" = x ] || $(STRIP) $(STEAMEXE_OBJ)/steam.exe.so
|
[ x"$(STRIP)" = x ] || $(STRIP) $(STEAMEXE_OBJ)/steam.exe.so
|
||||||
mkdir -pv $(DST_DIR)/lib/wine/
|
mkdir -pv $(DST_DIR)/lib/wine/
|
||||||
|
|
74
proton
74
proton
|
@ -513,79 +513,6 @@ class Session:
|
||||||
else:
|
else:
|
||||||
self.env["WINEDLLOVERRIDES"] = s
|
self.env["WINEDLLOVERRIDES"] = s
|
||||||
|
|
||||||
def setup_vr(self):
|
|
||||||
#parse linux openvr config and present it in win32 format to the app.
|
|
||||||
#logic from openvr's CVRPathRegistry_Public::GetPaths
|
|
||||||
|
|
||||||
#check environment for overrides
|
|
||||||
vr_runtime = None
|
|
||||||
if "VR_OVERRIDE" in self.env:
|
|
||||||
vr_runtime = self.env["VR_OVERRIDE"]
|
|
||||||
self.env.pop("VR_OVERRIDE")
|
|
||||||
|
|
||||||
vr_config = None
|
|
||||||
if "VR_CONFIG_PATH" in self.env:
|
|
||||||
vr_config = self.env["VR_CONFIG_PATH"]
|
|
||||||
self.env.pop("VR_CONFIG_PATH")
|
|
||||||
|
|
||||||
vr_log = None
|
|
||||||
if "VR_LOG_PATH" in self.env:
|
|
||||||
vr_log = self.env["VR_LOG_PATH"]
|
|
||||||
self.env.pop("VR_LOG_PATH")
|
|
||||||
|
|
||||||
#load from json if needed
|
|
||||||
if vr_runtime is None or \
|
|
||||||
vr_config is None or \
|
|
||||||
vr_log is None:
|
|
||||||
try:
|
|
||||||
path = os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config")
|
|
||||||
path = path + "/openvr/openvrpaths.vrpath"
|
|
||||||
|
|
||||||
with open(path, "r") as jfile:
|
|
||||||
j = json.load(jfile)
|
|
||||||
|
|
||||||
if vr_runtime is None:
|
|
||||||
vr_runtime = j["runtime"][0]
|
|
||||||
|
|
||||||
if vr_config is None:
|
|
||||||
vr_config = j["config"][0]
|
|
||||||
|
|
||||||
if vr_log is None:
|
|
||||||
vr_log = j["log"][0]
|
|
||||||
except (TypeError, ValueError, OSError):
|
|
||||||
#log("Missing or invalid openvrpaths.vrpath file! " + str(sys.exc_info()[1]))
|
|
||||||
pass
|
|
||||||
|
|
||||||
makedirs(g_compatdata.prefix_dir + "/drive_c/users/steamuser/Local Settings/Application Data/openvr")
|
|
||||||
|
|
||||||
#remove existing file
|
|
||||||
vrpaths_name = g_compatdata.prefix_dir + "/drive_c/users/steamuser/Local Settings/Application Data/openvr/openvrpaths.vrpath"
|
|
||||||
if os.path.exists(vrpaths_name):
|
|
||||||
os.remove(vrpaths_name)
|
|
||||||
|
|
||||||
#dump new file
|
|
||||||
if not vr_runtime is None:
|
|
||||||
try:
|
|
||||||
self.env["PROTON_VR_RUNTIME"] = vr_runtime
|
|
||||||
|
|
||||||
j = { "runtime": [ "C:\\vrclient\\", "C:\\vrclient" ] }
|
|
||||||
|
|
||||||
if not vr_config is None:
|
|
||||||
win_vr_config = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_config], env=self.env, stderr=self.log_file).decode("utf-8")
|
|
||||||
j["config"] = [ win_vr_config.strip() ]
|
|
||||||
|
|
||||||
if not vr_log is None:
|
|
||||||
win_vr_log = subprocess.check_output([g_proton.wine_bin, "winepath", "-w", vr_log], env=self.env, stderr=self.log_file).decode("utf-8")
|
|
||||||
j["log"] = [ win_vr_log.strip() ]
|
|
||||||
|
|
||||||
j["version"] = 1
|
|
||||||
j["jsonid"] = "vrpathreg"
|
|
||||||
|
|
||||||
with open(vrpaths_name, "w") as vfile:
|
|
||||||
json.dump(j, vfile, indent=2)
|
|
||||||
except (ValueError, OSError):
|
|
||||||
log("Unable to write VR config! " + str(sys.exc_info()[1]))
|
|
||||||
|
|
||||||
def dump_dbg_env(self, f):
|
def dump_dbg_env(self, f):
|
||||||
f.write("PATH=\"" + self.env["PATH"] + "\" \\\n")
|
f.write("PATH=\"" + self.env["PATH"] + "\" \\\n")
|
||||||
f.write("\tTERM=\"xterm\" \\\n") #XXX
|
f.write("\tTERM=\"xterm\" \\\n") #XXX
|
||||||
|
@ -696,7 +623,6 @@ class Session:
|
||||||
subprocess.call(args, env=local_env, stderr=self.log_file, stdout=self.log_file)
|
subprocess.call(args, env=local_env, stderr=self.log_file, stdout=self.log_file)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.setup_vr()
|
|
||||||
if "PROTON_DUMP_DEBUG_COMMANDS" in self.env and nonzero(self.env["PROTON_DUMP_DEBUG_COMMANDS"]):
|
if "PROTON_DUMP_DEBUG_COMMANDS" in self.env and nonzero(self.env["PROTON_DUMP_DEBUG_COMMANDS"]):
|
||||||
try:
|
try:
|
||||||
self.dump_dbg_scripts()
|
self.dump_dbg_scripts()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019, Valve Corporation
|
* Copyright (c) 2015, 2019, 2020 Valve Corporation
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without modification,
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
* Windows version of Steam running. */
|
* Windows version of Steam running. */
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <shlobj.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -46,6 +47,8 @@
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
|
#include "json/json.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(steam);
|
WINE_DEFAULT_DEBUG_CHANNEL(steam);
|
||||||
|
|
||||||
EXTERN_C HANDLE CDECL __wine_make_process_system(void);
|
EXTERN_C HANDLE CDECL __wine_make_process_system(void);
|
||||||
|
@ -117,6 +120,292 @@ static void setup_steam_registry(void)
|
||||||
SteamAPI_Shutdown();
|
SteamAPI_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string get_linux_vr_path(void)
|
||||||
|
{
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
e = getenv("VR_PATHREG_OVERRIDE");
|
||||||
|
if(e && *e)
|
||||||
|
return e;
|
||||||
|
|
||||||
|
e = getenv("XDG_CONFIG_HOME");
|
||||||
|
|
||||||
|
if(!e || !*e)
|
||||||
|
e = getenv("HOME");
|
||||||
|
|
||||||
|
if(!e || !*e)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return std::string(e) + "/.config/openvr/openvrpaths.vrpath";
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_windows_vr_path(WCHAR *out_path, bool create)
|
||||||
|
{
|
||||||
|
if(FAILED(SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE,
|
||||||
|
NULL, 0, out_path)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
lstrcatW(out_path, L"\\openvr");
|
||||||
|
|
||||||
|
if(create)
|
||||||
|
CreateDirectoryW(out_path, NULL);
|
||||||
|
|
||||||
|
lstrcatW(out_path, L"\\openvrpaths.vrpath");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR *str_to_wchar(const std::string &str)
|
||||||
|
{
|
||||||
|
DWORD sz = MultiByteToWideChar(CP_UNIXCP, 0, str.c_str(), -1, NULL, 0);
|
||||||
|
if(!sz)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
WCHAR *ret = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * sz);
|
||||||
|
if(!ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sz = MultiByteToWideChar(CP_UNIXCP, 0, str.c_str(), -1, ret, sz);
|
||||||
|
if(!sz)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string read_text_file(const WCHAR *filename)
|
||||||
|
{
|
||||||
|
HANDLE ifile = CreateFileW(filename, GENERIC_READ,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if(ifile == INVALID_HANDLE_VALUE)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
LARGE_INTEGER size;
|
||||||
|
|
||||||
|
if(!GetFileSizeEx(ifile, &size))
|
||||||
|
{
|
||||||
|
CloseHandle(ifile);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = (char *)HeapAlloc(GetProcessHeap(), 0, size.u.LowPart);
|
||||||
|
if(!buf)
|
||||||
|
{
|
||||||
|
CloseHandle(ifile);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD readed;
|
||||||
|
|
||||||
|
if(!ReadFile(ifile, buf, size.u.LowPart, &readed, NULL))
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
CloseHandle(ifile);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(ifile);
|
||||||
|
|
||||||
|
DWORD outsize = 1;
|
||||||
|
for(DWORD i = 1; i < readed; ++i)
|
||||||
|
{
|
||||||
|
if(buf[i] == '\n' && buf[i - 1] == '\r') // CRLF
|
||||||
|
buf[outsize - 1] = '\n';
|
||||||
|
else
|
||||||
|
buf[outsize++] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ret(buf, outsize);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool write_string_to_file(const WCHAR *filename, const std::string &contents)
|
||||||
|
{
|
||||||
|
HANDLE ofile = CreateFileW(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
if(ofile == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DWORD written;
|
||||||
|
|
||||||
|
if(!WriteFile(ofile, contents.data(), (DWORD)contents.length(), &written, NULL))
|
||||||
|
{
|
||||||
|
CloseHandle(ofile);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(ofile);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool convert_path_to_win(std::string &s)
|
||||||
|
{
|
||||||
|
WCHAR *path = wine_get_dos_file_name(s.c_str());
|
||||||
|
if(!path)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DWORD sz = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
|
||||||
|
if(!sz)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pathUTF8 = (char *)HeapAlloc(GetProcessHeap(), 0, sz);
|
||||||
|
if(!pathUTF8)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sz = WideCharToMultiByte(CP_UTF8, 0, path, -1, pathUTF8, sz, NULL, NULL);
|
||||||
|
if(!sz)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, pathUTF8);
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = pathUTF8;
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, pathUTF8);
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_json_array_paths(Json::Value &arr)
|
||||||
|
{
|
||||||
|
for(uint32_t i = 0; i < arr.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string path(arr[i].asString());
|
||||||
|
if(convert_path_to_win(path))
|
||||||
|
arr[i] = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void convert_environment_path(const char *nameA, const WCHAR *nameW)
|
||||||
|
{
|
||||||
|
/* get linux-side variable */
|
||||||
|
const char *e = getenv(nameA);
|
||||||
|
if(!e || !*e)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* convert to win and set */
|
||||||
|
WCHAR *path = wine_get_dos_file_name(e);
|
||||||
|
if(!path)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SetEnvironmentVariableW(nameW, path);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_env_from_unix(const WCHAR *name, const std::string &val)
|
||||||
|
{
|
||||||
|
WCHAR valW[MAX_PATH];
|
||||||
|
DWORD sz;
|
||||||
|
|
||||||
|
sz = MultiByteToWideChar(CP_UTF8, 0, val.c_str(), -1, valW, MAX_PATH);
|
||||||
|
if(!sz)
|
||||||
|
{
|
||||||
|
WINE_WARN("Invalid utf8 seq in vr runtime key\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEnvironmentVariableW(name, valW);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool convert_linux_vrpaths(void)
|
||||||
|
{
|
||||||
|
/* read in linux vrpaths */
|
||||||
|
std::string linux_vrpaths = get_linux_vr_path();
|
||||||
|
if(linux_vrpaths.empty())
|
||||||
|
{
|
||||||
|
WINE_TRACE("Couldn't get openvr vrpaths path\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR *linux_vrpathsW = str_to_wchar(linux_vrpaths);
|
||||||
|
if(!linux_vrpathsW)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string contents = read_text_file(linux_vrpathsW);
|
||||||
|
HeapFree(GetProcessHeap(), 0, linux_vrpathsW);
|
||||||
|
if(contents.empty())
|
||||||
|
{
|
||||||
|
WINE_TRACE("openvr vrpaths is empty\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value root;
|
||||||
|
Json::Reader reader;
|
||||||
|
|
||||||
|
if(!reader.parse(contents, root))
|
||||||
|
{
|
||||||
|
WINE_WARN("Invalid openvr vrpaths JSON\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pass original runtime path into Wine */
|
||||||
|
if(root.isMember("runtime") && root["runtime"].isArray() && root["runtime"].size() > 0)
|
||||||
|
{
|
||||||
|
set_env_from_unix(L"PROTON_VR_RUNTIME", root["runtime"][0].asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set hard-coded paths */
|
||||||
|
root["runtime"] = Json::Value(Json::ValueType::arrayValue);
|
||||||
|
root["runtime"][0] = "C:\\vrclient\\";
|
||||||
|
root["runtime"][1] = "C:\\vrclient";
|
||||||
|
|
||||||
|
/* map linux paths into windows filesystem */
|
||||||
|
if(root.isMember("config") && root["config"].isArray())
|
||||||
|
convert_json_array_paths(root["config"]);
|
||||||
|
|
||||||
|
if(root.isMember("log") && root["log"].isArray())
|
||||||
|
convert_json_array_paths(root["log"]);
|
||||||
|
|
||||||
|
/* external_drivers is currently unsupported in Proton */
|
||||||
|
root["external_drivers"] = Json::Value(Json::ValueType::nullValue);
|
||||||
|
|
||||||
|
/* write out windows vrpaths */
|
||||||
|
SetEnvironmentVariableW(L"VR_PATHREG_OVERRIDE", NULL);
|
||||||
|
SetEnvironmentVariableW(L"VR_OVERRIDE", NULL);
|
||||||
|
convert_environment_path("VR_CONFIG_PATH", L"VR_CONFIG_PATH");
|
||||||
|
convert_environment_path("VR_LOG_PATH", L"VR_LOG_PATH");
|
||||||
|
Json::StyledWriter writer;
|
||||||
|
|
||||||
|
WCHAR windows_vrpaths[MAX_PATH];
|
||||||
|
if(!get_windows_vr_path(windows_vrpaths, true))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
contents = writer.write(root);
|
||||||
|
|
||||||
|
write_string_to_file(windows_vrpaths, contents);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_vrpaths(void)
|
||||||
|
{
|
||||||
|
if(!convert_linux_vrpaths())
|
||||||
|
{
|
||||||
|
/* delete the windows file only if the linux conversion fails */
|
||||||
|
WCHAR windows_vrpaths[MAX_PATH];
|
||||||
|
if(get_windows_vr_path(windows_vrpaths, false))
|
||||||
|
{
|
||||||
|
DeleteFileW(windows_vrpaths);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static WCHAR *strchrW(WCHAR *h, WCHAR n)
|
static WCHAR *strchrW(WCHAR *h, WCHAR n)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
|
@ -293,6 +582,8 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
HANDLE child;
|
HANDLE child;
|
||||||
|
|
||||||
|
setup_vrpaths();
|
||||||
|
|
||||||
child = run_process();
|
child = run_process();
|
||||||
|
|
||||||
if (child == INVALID_HANDLE_VALUE)
|
if (child == INVALID_HANDLE_VALUE)
|
||||||
|
|
|
@ -43,6 +43,8 @@ typedef struct winRenderModel_t_1819 winRenderModel_t_1819;
|
||||||
typedef struct winRenderModel_TextureMap_t_1819 winRenderModel_TextureMap_t_1819;
|
typedef struct winRenderModel_TextureMap_t_1819 winRenderModel_TextureMap_t_1819;
|
||||||
#include "cppIVRRenderModels_IVRRenderModels_006.h"
|
#include "cppIVRRenderModels_IVRRenderModels_006.h"
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
|
WINE_DEFAULT_DEBUG_CHANNEL(vrclient);
|
||||||
|
|
||||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
|
||||||
|
@ -216,25 +218,47 @@ static void *(*vrclient_VRClientCoreFactory)(const char *name, int *return_code)
|
||||||
|
|
||||||
static int load_vrclient(void)
|
static int load_vrclient(void)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
WCHAR pathW[PATH_MAX];
|
||||||
|
char *pathU;
|
||||||
|
DWORD sz;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
static const char append_path[] = "/bin/linux64/vrclient.so";
|
||||||
|
#else
|
||||||
|
static const char append_path[] = "/bin/vrclient.so";
|
||||||
|
#endif
|
||||||
|
|
||||||
if(vrclient_lib)
|
if(vrclient_lib)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* PROTON_VR_RUNTIME is provided by the proton setup script */
|
/* PROTON_VR_RUNTIME is provided by the proton setup script */
|
||||||
if(!getenv("PROTON_VR_RUNTIME")){
|
if(!GetEnvironmentVariableW(L"PROTON_VR_RUNTIME", pathW, ARRAY_SIZE(pathW)))
|
||||||
|
{
|
||||||
TRACE("Linux OpenVR runtime is not available\n");
|
TRACE("Linux OpenVR runtime is not available\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, NULL, 0, NULL, NULL);
|
||||||
snprintf(path, PATH_MAX, "%s/bin/linux64/vrclient.so", getenv("PROTON_VR_RUNTIME"));
|
if(!sz)
|
||||||
#else
|
{
|
||||||
snprintf(path, PATH_MAX, "%s/bin/vrclient.so", getenv("PROTON_VR_RUNTIME"));
|
ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
|
||||||
#endif
|
return 0;
|
||||||
TRACE("got openvr runtime path: %s\n", path);
|
}
|
||||||
|
|
||||||
vrclient_lib = wine_dlopen(path, RTLD_NOW, NULL, 0);
|
pathU = HeapAlloc(GetProcessHeap(), 0, sz + sizeof(append_path));
|
||||||
|
|
||||||
|
sz = WideCharToMultiByte(CP_UNIXCP, 0, pathW, -1, pathU, sz, NULL, NULL);
|
||||||
|
if(!sz)
|
||||||
|
{
|
||||||
|
ERR("Can't convert path to unixcp! %s\n", wine_dbgstr_w(pathW));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(pathU, append_path);
|
||||||
|
|
||||||
|
TRACE("got openvr runtime path: %s\n", pathU);
|
||||||
|
|
||||||
|
vrclient_lib = wine_dlopen(pathU, RTLD_NOW, NULL, 0);
|
||||||
if(!vrclient_lib){
|
if(!vrclient_lib){
|
||||||
TRACE("unable to load vrclient.so\n");
|
TRACE("unable to load vrclient.so\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue