|
| 1 | +import itertools |
1 | 2 | import locale
|
2 | 3 | import logging
|
3 | 4 | import os
|
@@ -308,6 +309,109 @@ def _get_fixed_locale_env():
|
308 | 309 | return fixed_env
|
309 | 310 |
|
310 | 311 |
|
| 312 | +_DLL_OVERRIDES = { |
| 313 | + "beclient": "b,n", |
| 314 | + "beclient_x64": "b,n", |
| 315 | + |
| 316 | + # DXVK |
| 317 | + "dxgi": "n", |
| 318 | + "d3d9": "n", |
| 319 | + "d3d10core": "n", |
| 320 | + "d3d11": "n", |
| 321 | + |
| 322 | + # vkd3d-proton |
| 323 | + "d3d12": "n", |
| 324 | + "d3d12core": "n", |
| 325 | + |
| 326 | + # nvapi |
| 327 | + "nvapi": "n", |
| 328 | + "nvapi64": "n", |
| 329 | + "nvofapi64": "n", |
| 330 | + "nvcuda": "b" |
| 331 | +} |
| 332 | + |
| 333 | +_WINE_DEFAULT_ENV_VARS = { |
| 334 | + "WINE_LARGE_ADDRESS_AWARE": "1", |
| 335 | + "DXVK_ENABLE_NVAPI": "1", |
| 336 | +} |
| 337 | + |
| 338 | +def _get_proton_env(proton_app, steam_app, orig_env): |
| 339 | + """ |
| 340 | + Return a dict of various Proton related environment variables. |
| 341 | + These are mainly required to configure DXVK, vkd3d-proton and GStreamer |
| 342 | + properly. |
| 343 | +
|
| 344 | + When using Proton proper, these are usually set by the `proton` launcher |
| 345 | + script. The script is not designed for programmatic usage, so we'll have to |
| 346 | + set them manually instead. |
| 347 | +
|
| 348 | + Some environment variables are not supported depending on the Python |
| 349 | + version. We will err on the side of caution and check if preconditions are |
| 350 | + met before attempting to set any environment variables; for example, Proton |
| 351 | + installation must contain GStreamer directory in order to set GStreamer env |
| 352 | + vars. |
| 353 | + """ |
| 354 | + new_env = {} |
| 355 | + |
| 356 | + dist_path = proton_app.proton_dist_path |
| 357 | + |
| 358 | + # 1.Configure WINEDLLOVERRIDES |
| 359 | + available_dlls = set([ |
| 360 | + file_.stem for file_ |
| 361 | + in itertools.chain( |
| 362 | + (dist_path / "lib64").glob("**/*.dll"), |
| 363 | + (dist_path / "lib").glob("**/*.dll") |
| 364 | + ) |
| 365 | + ]) |
| 366 | + |
| 367 | + dll_overrides = { |
| 368 | + value.split("=")[0]: value.split("=")[1] |
| 369 | + for value in orig_env.get("WINEDLLOVERRIDES", "").split(";") |
| 370 | + if "=" in value |
| 371 | + } |
| 372 | + |
| 373 | + logger.debug( |
| 374 | + "Following Wine DLL overrides already set: %s", |
| 375 | + dll_overrides |
| 376 | + ) |
| 377 | + |
| 378 | + # Set DLL overrides if the corresponding DLL file exists *and* if the user |
| 379 | + # hasn't declared something else |
| 380 | + for name, setting in _DLL_OVERRIDES.items(): |
| 381 | + is_available = name in available_dlls |
| 382 | + is_set = name in dll_overrides |
| 383 | + |
| 384 | + if is_available and not is_set: |
| 385 | + logger.debug("Setting Wine DLL override: %s=%s", name, setting) |
| 386 | + dll_overrides[name] = setting |
| 387 | + |
| 388 | + new_env["WINEDLLOVERRIDES"] = ";".join( |
| 389 | + f"{name}={setting}" for name, setting in dll_overrides.items() |
| 390 | + ) |
| 391 | + |
| 392 | + # 2. Configure GStreamer |
| 393 | + is_gstreamer_available = (dist_path / "lib/gstreamer-1.0").is_dir() |
| 394 | + |
| 395 | + if is_gstreamer_available: |
| 396 | + logger.debug("Setting GStreamer environment variables") |
| 397 | + |
| 398 | + new_env["GST_PLUGIN_SYSTEM_PATH_1_0"] = ( |
| 399 | + f"{dist_path / 'lib64/gstreamer-1.0'}" |
| 400 | + f":{dist_path / 'lib/gstreamer-1.0'}" |
| 401 | + ) |
| 402 | + new_env["WINE_GST_REGISTRY_DIR"] = str( |
| 403 | + steam_app.prefix_path.parent / "gstreamer-1.0" |
| 404 | + ) |
| 405 | + |
| 406 | + # 3. Enable various env vars unless already set by user |
| 407 | + for name, value in _WINE_DEFAULT_ENV_VARS.items(): |
| 408 | + if name not in orig_env: |
| 409 | + logger.debug("Setting default env var: %s=%s", name, value) |
| 410 | + new_env[name] = value |
| 411 | + |
| 412 | + return new_env |
| 413 | + |
| 414 | + |
311 | 415 | def _start_process(args, wait=False, **kwargs):
|
312 | 416 | """Start a new process and return a Popen instance
|
313 | 417 | """
|
@@ -396,6 +500,14 @@ def run_command(
|
396 | 500 | # Fix the locale for Steam Deck, if necessary
|
397 | 501 | wine_environ.update(_get_fixed_locale_env())
|
398 | 502 |
|
| 503 | + # Set various Proton related environment variables |
| 504 | + wine_environ.update( |
| 505 | + _get_proton_env( |
| 506 | + proton_app=proton_app, steam_app=steam_app, |
| 507 | + orig_env=wine_environ |
| 508 | + ) |
| 509 | + ) |
| 510 | + |
399 | 511 | wine_bin_dir = None
|
400 | 512 | wine_environ["PROTONTRICKS_STEAM_RUNTIME"] = "off"
|
401 | 513 | if use_steam_runtime:
|
|
0 commit comments