Skip to content

Commit dc71855

Browse files
LaunchSettings: add an option to use fake EGL exe
1 parent c349177 commit dc71855

9 files changed

Lines changed: 94 additions & 46 deletions

File tree

rare/commands/launcher/lgd_helper.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,19 +109,18 @@ def get_game_params(rgame: RareGameSlim, init: InitParams, launch: LaunchParams)
109109
full_params = []
110110
full_params.extend(params.launch_command)
111111
if 'LEGENDARY_WRAPPER_EXE' in params.environment:
112-
lgd_wrapper = params.environment.pop('LEGENDARY_WRAPPER_EXE').strip()
113-
if os.path.isfile(lgd_wrapper):
112+
lgd_wrapper = params.environment.pop('LEGENDARY_WRAPPER_EXE', '').strip()
113+
if lgd_wrapper and os.path.isfile(lgd_wrapper):
114114
full_params.append(lgd_wrapper)
115115
full_params.append(os.path.join(params.game_directory, params.game_executable))
116116
full_params.extend(params.game_parameters)
117117
full_params.extend(params.egl_parameters)
118118
full_params.extend(params.user_parameters)
119119

120-
exe, init, env = prepare_process(full_params, params.environment)
121-
122-
launch.executable = exe
123-
launch.arguments = init
124-
launch.environment = env
120+
_exe, _init, _env = prepare_process(full_params, params.environment)
121+
launch.executable = _exe
122+
launch.arguments = _init
123+
launch.environment = _env
125124
launch.working_directory = params.working_directory
126125

127126
return launch

rare/components/tabs/library/details/game.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from rare.models.settings import RareAppSettings
1414
from rare.shared import RareCore
1515
from rare.utils import config_helper as config
16+
from rare.utils.wrapper_exe import wrapper_path
1617
from rare.widgets.indicator_edit import IndicatorReasonsCommon, PathEdit
1718

1819
logger = getLogger('LocalGameSettings')
@@ -34,13 +35,13 @@ def __init__(self, rcore: RareCore, parent=None):
3435
self.skip_update_combo.addItem(self.tr('Default'), None)
3536
self.skip_update_combo.addItem(self.tr('No'), 'false')
3637
self.skip_update_combo.addItem(self.tr('Yes'), 'true')
37-
self.skip_update_combo.currentIndexChanged.connect(self.__skip_update_changed)
38+
self.skip_update_combo.currentIndexChanged.connect(self._skip_update_changed)
3839

3940
self.offline_combo = QComboBox(self)
4041
self.offline_combo.addItem(self.tr('Default'), None)
4142
self.offline_combo.addItem(self.tr('No'), 'false')
4243
self.offline_combo.addItem(self.tr('Yes'), 'true')
43-
self.offline_combo.currentIndexChanged.connect(self.__offline_changed)
44+
self.offline_combo.currentIndexChanged.connect(self._offline_changed)
4445

4546
self.override_exe_name_filters: tuple[str, ...] = (
4647
'*.exe',
@@ -54,14 +55,14 @@ def __init__(self, rcore: RareCore, parent=None):
5455
file_mode=QFileDialog.FileMode.ExistingFile,
5556
name_filters=self.override_exe_name_filters,
5657
placeholder=self.tr('Relative path to the replacement executable'),
57-
edit_func=self.__override_exe_edit_callback,
58-
save_func=self.__override_exe_save_callback,
58+
edit_func=self._override_exe_edit_callback,
59+
save_func=self._override_exe_save_callback,
5960
parent=self,
6061
)
6162

6263
self.launch_params_edit = QLineEdit(self)
6364
self.launch_params_edit.setPlaceholderText(self.tr('Game specific command line arguments'))
64-
self.launch_params_edit.textChanged.connect(self.__launch_params_changed)
65+
self.launch_params_edit.textChanged.connect(self._launch_params_changed)
6566

6667
self.main_layout.insertRow(0, self.tr('Skip update check'), self.skip_update_combo)
6768
self.main_layout.insertRow(1, self.tr('Offline mode'), self.offline_combo)
@@ -94,11 +95,11 @@ def showEvent(self, a0: QShowEvent):
9495
return super().showEvent(a0)
9596

9697
@Slot(int)
97-
def __skip_update_changed(self, index):
98+
def _skip_update_changed(self, index):
9899
data = self.skip_update_combo.itemData(index, Qt.ItemDataRole.UserRole)
99100
config.adjust_option(self.app_name, 'skip_update_check', data)
100101

101-
def __override_exe_edit_callback(self, path: str) -> tuple[bool, str, int]:
102+
def _override_exe_edit_callback(self, path: str) -> tuple[bool, str, int]:
102103
if not path or self.igame is None:
103104
return True, path, IndicatorReasonsCommon.VALID
104105
if not os.path.isabs(path):
@@ -116,17 +117,25 @@ def __override_exe_edit_callback(self, path: str) -> tuple[bool, str, int]:
116117
path = os.path.relpath(path, self.igame.install_path)
117118
return True, path, IndicatorReasonsCommon.VALID
118119

119-
def __override_exe_save_callback(self, path: str):
120+
def _override_exe_save_callback(self, path: str):
120121
config.adjust_option(self.app_name, 'override_exe', path)
121122

122123
@Slot(int)
123-
def __offline_changed(self, index):
124+
def _offline_changed(self, index):
124125
data = self.skip_update_combo.itemData(index, Qt.ItemDataRole.UserRole)
125126
config.adjust_option(self.app_name, 'offline', data)
126127

127-
def __launch_params_changed(self, value) -> None:
128+
def _launch_params_changed(self, value) -> None:
128129
config.adjust_option(self.app_name, 'start_params', value)
129130

131+
@Slot(Qt.CheckState)
132+
def _lgd_wrapper_check_changed(self, state: Qt.CheckState):
133+
_wrapper = str(wrapper_path())
134+
config.adjust_envvar_with_global(
135+
self.app_name, 'LEGENDARY_WRAPPER_EXE', _wrapper if state == Qt.CheckState.Checked else ''
136+
)
137+
self.environ_changed.emit('LEGENDARY_WRAPPER_EXE')
138+
130139
def load_settings(self, rgame: RareGame):
131140
self.game = rgame.game
132141
self.igame = rgame.igame

rare/components/tabs/settings/game.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from PySide6.QtCore import Qt
1+
from PySide6.QtCore import Qt, Signal
22
from PySide6.QtGui import QHideEvent
33
from PySide6.QtWidgets import QVBoxLayout, QWidget
44

@@ -12,6 +12,9 @@
1212

1313

1414
class GameSettingsBase(QWidget, SideTabContents):
15+
# str: option key
16+
environ_changed: Signal = Signal(str)
17+
1518
def __init__(
1619
self,
1720
settings: RareAppSettings,
@@ -26,6 +29,7 @@ def __init__(
2629
self.app_name: str = 'default'
2730

2831
self.launch = launch_widget(rcore, self)
32+
self.launch.environ_changed.connect(self.environ_changed)
2933

3034
self.main_layout = QVBoxLayout(self)
3135
self.main_layout.addWidget(self.launch, stretch=0)

rare/components/tabs/settings/widgets/launch.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import shutil
44
from typing import TypeVar
55

6-
from PySide6.QtCore import Qt, Slot
6+
from PySide6.QtCore import Qt, Signal, Slot
77
from PySide6.QtGui import QShowEvent
88
from PySide6.QtWidgets import (
99
QCheckBox,
@@ -16,12 +16,16 @@
1616

1717
import rare.utils.config_helper as config
1818
from rare.shared import RareCore
19+
from rare.utils.wrapper_exe import wrapper_path
1920
from rare.widgets.indicator_edit import IndicatorReasonsCommon, PathEdit
2021

2122
from .wrappers import WrapperSettings
2223

2324

2425
class LaunchSettingsBase(QGroupBox):
26+
# str: option key
27+
environ_changed: Signal = Signal(str)
28+
2529
def __init__(self, rcore: RareCore, wrapper_widget: type[WrapperSettings], parent=None):
2630
super(LaunchSettingsBase, self).__init__(parent=parent)
2731
self.setTitle(self.tr('Launch'))
@@ -33,21 +37,21 @@ def __init__(self, rcore: RareCore, wrapper_widget: type[WrapperSettings], paren
3337
path='',
3438
placeholder=self.tr('Path to a script or program to run before the game'),
3539
file_mode=QFileDialog.FileMode.ExistingFile,
36-
edit_func=self.__prelaunch_cmd_edit_callback,
37-
save_func=self.__prelaunch_cmd_save_callback,
40+
edit_func=self._prelaunch_cmd_edit_callback,
41+
save_func=self._prelaunch_cmd_save_callback,
3842
)
3943

4044
self.prelaunch_args = QLineEdit('')
4145
self.prelaunch_args.setPlaceholderText(self.tr('Arguments to the script or program to run before the game'))
4246
self.prelaunch_args.setToolTip(self.prelaunch_args.placeholderText())
43-
self.prelaunch_args.textChanged.connect(self.__prelaunch_changed)
47+
self.prelaunch_args.textChanged.connect(self._prelaunch_changed)
4448

4549
font = self.font()
4650
font.setItalic(True)
4751

4852
self.prelaunch_check = QCheckBox(self.tr('Wait for the pre-launch command to finish before launching the game'))
4953
self.prelaunch_check.setFont(font)
50-
self.prelaunch_check.checkStateChanged.connect(self.__prelauch_check_changed)
54+
self.prelaunch_check.checkStateChanged.connect(self._prelauch_check_changed)
5155

5256
prelaunch_layout = QVBoxLayout()
5357
prelaunch_layout.addWidget(self.prelaunch_cmd)
@@ -61,6 +65,13 @@ def __init__(self, rcore: RareCore, wrapper_widget: type[WrapperSettings], paren
6165

6266
self.wrappers_widget = wrapper_widget(rcore, self)
6367

68+
self.lgd_wrapper = QCheckBox(
69+
self.tr('Use "EpicGamesLauncher.exe" shim for compatibility with third-party launchers (Rockstar etc.)')
70+
)
71+
self.lgd_wrapper.setFont(font)
72+
self.lgd_wrapper.checkStateChanged.connect(self._lgd_wrapper_check_changed)
73+
74+
self.main_layout.addRow(self.tr('Use fake EGL'), self.lgd_wrapper)
6475
self.main_layout.addRow(self.tr('Wrappers'), self.wrappers_widget)
6576
self.main_layout.addRow(self.tr('Pre-launch'), prelaunch_layout)
6677

@@ -77,31 +88,36 @@ def showEvent(self, a0: QShowEvent):
7788
self.prelaunch_check.setChecked(wait)
7889
self.prelaunch_check.setEnabled(bool(command))
7990

91+
wrapper = config.get_envvar_with_global(self.app_name, 'LEGENDARY_WRAPPER_EXE', fallback=False)
92+
93+
self.lgd_wrapper.setEnabled(wrapper_path().exists())
94+
self.lgd_wrapper.setChecked(wrapper_path().exists() and bool(wrapper) and os.path.exists(wrapper))
95+
8096
return super().showEvent(a0)
8197

8298
@Slot()
8399
def tool_enabled(self):
84100
self.wrappers_widget.update_state()
85101

86102
@staticmethod
87-
def __prelaunch_cmd_edit_callback(text: str) -> tuple[bool, str, int]:
103+
def _prelaunch_cmd_edit_callback(text: str) -> tuple[bool, str, int]:
88104
if not text.strip():
89105
return True, text, IndicatorReasonsCommon.UNDEFINED
90106
if not os.path.isfile(text) and not shutil.which(text):
91107
return False, text, IndicatorReasonsCommon.FILE_NOT_EXISTS
92108
else:
93109
return True, text, IndicatorReasonsCommon.VALID
94110

95-
def __prelaunch_cmd_save_callback(self, text):
111+
def _prelaunch_cmd_save_callback(self, text):
96112
self.prelaunch_check.setEnabled(bool(text))
97-
self.__prelaunch_changed()
113+
self._prelaunch_changed()
98114

99115
@Slot(Qt.CheckState)
100-
def __prelauch_check_changed(self, state: Qt.CheckState):
116+
def _prelauch_check_changed(self, state: Qt.CheckState):
101117
config.set_boolean(self.app_name, 'pre_launch_wait', state != Qt.CheckState.Unchecked)
102118

103119
@Slot()
104-
def __prelaunch_changed(self):
120+
def _prelaunch_changed(self):
105121
command = self.prelaunch_cmd.text().strip()
106122
if not command:
107123
config.adjust_option(self.app_name, 'pre_launch_command', command)
@@ -111,5 +127,11 @@ def __prelaunch_changed(self):
111127
arguments = self.prelaunch_args.text().strip()
112128
config.adjust_option(self.app_name, 'pre_launch_command', ' '.join([command, arguments]))
113129

130+
@Slot(Qt.CheckState)
131+
def _lgd_wrapper_check_changed(self, state: Qt.CheckState):
132+
_wrapper = str(wrapper_path())
133+
config.adjust_envvar(self.app_name, 'LEGENDARY_WRAPPER_EXE', _wrapper if state == Qt.CheckState.Checked else '')
134+
self.environ_changed.emit('LEGENDARY_WRAPPER_EXE')
135+
114136

115137
LaunchSettingsType = TypeVar('LaunchSettingsType', bound=LaunchSettingsBase)

rare/models/settings.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ class Settings(Namespace):
6161

6262
local_shader_cache = Setting(key='local_shader_cache', default=False, dtype=bool)
6363
create_shortcut = Setting(
64-
key='create_shortcut',
65-
default=pf.system() == 'Windows' and 'WINEUSERNAME' not in os.environ,
66-
dtype=bool
64+
key='create_shortcut', default=pf.system() == 'Windows' and 'WINEUSERNAME' not in os.environ, dtype=bool
6765
)
6866

6967

rare/shared/rare_core.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from collections.abc import Callable, Iterable, Iterator
66
from itertools import chain
77
from logging import getLogger
8-
from typing import Optional
98

109
from legendary.lfs.eos import EOSOverlayApp
1110
from legendary.models.game import Game, SaveGameFile

rare/utils/config_helper.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ def set_boolean(app_name: str, option: str, value: bool) -> None:
3535
set_option(app_name, option, str(value).lower())
3636

3737

38-
def set_envvar(app_name: str, envvar: str, value: str) -> None:
39-
set_option(f'{app_name}.env', envvar, value)
40-
41-
4238
def remove_section(app_name: str) -> None:
4339
return
4440
# Disabled due to env variables implementation
@@ -55,10 +51,6 @@ def remove_option(app_name: str, option: str) -> None:
5551
# save_config()
5652

5753

58-
def remove_envvar(app_name: str, option: str) -> None:
59-
remove_option(f'{app_name}.env', option)
60-
61-
6254
def adjust_option(app_name: str, option: str, value: str) -> None:
6355
if value:
6456
set_option(app_name, option, value)
@@ -70,6 +62,14 @@ def get_option(app_name: str, option: str, fallback: Any = None) -> str:
7062
return _config.get(app_name, option, fallback=fallback)
7163

7264

65+
def adjust_option_with_global(app_name: str, option: str, value: str) -> None:
66+
value = value if value else ''
67+
if value == get_option('default', option, ''):
68+
remove_option(app_name, option)
69+
else:
70+
set_option(app_name, option, value)
71+
72+
7373
def get_option_with_global(app_name: str, option: str, fallback: Any = None) -> str:
7474
_option = get_option('default', option, fallback=fallback)
7575
_option = get_option(app_name, option, fallback=_option)
@@ -80,17 +80,30 @@ def get_boolean(app_name: str, option: str, fallback: bool = False) -> bool:
8080
return _config.getboolean(app_name, option, fallback=fallback)
8181

8282

83+
def set_envvar(app_name: str, envvar: str, value: str) -> None:
84+
set_option(f'{app_name}.env', envvar, value)
85+
86+
87+
def remove_envvar(app_name: str, option: str) -> None:
88+
remove_option(f'{app_name}.env', option)
89+
90+
8391
def adjust_envvar(app_name: str, option: str, value: str) -> None:
84-
if value:
85-
set_envvar(app_name, option, value)
86-
else:
87-
remove_envvar(app_name, option)
92+
adjust_option(f'{app_name}.env', option, value)
8893

8994

9095
def get_envvar(app_name: str, option: str, fallback: Any = None) -> str:
9196
return get_option(f'{app_name}.env', option, fallback=fallback)
9297

9398

99+
def adjust_envvar_with_global(app_name: str, option: str, value: str) -> None:
100+
value = value if value else ''
101+
if value == get_envvar('default', option, ''):
102+
remove_envvar(app_name, option)
103+
else:
104+
set_envvar(app_name, option, value)
105+
106+
94107
def get_envvar_with_global(app_name: str, option: str, fallback: Any = None) -> str:
95108
_option = _config.get('default.env', option, fallback=fallback)
96109
_option = _config.get(f'{app_name}.env', option, fallback=_option)

rare/utils/workarounds.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from rare.utils import config_helper as config
99
from rare.utils.paths import data_dir
10+
from rare.utils.wrapper_exe import wrapper_path
1011

1112

1213
class Workarounds:
@@ -70,11 +71,16 @@ def screen_height() -> int:
7071
def screen_width() -> int:
7172
return QApplication.instance().primaryScreen().geometry().width()
7273

74+
@staticmethod
75+
def wrapper_exe() -> str:
76+
return str(wrapper_path())
77+
7378
@staticmethod
7479
def subst(text: str) -> str:
7580
return text.format(
7681
res_width=Workarounds.screen_width(),
7782
res_height=Workarounds.screen_height(),
83+
wrapper_exe=Workarounds.wrapper_exe(),
7884
)
7985

8086

rare/utils/wrapper_exe.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ def wrapper_path() -> Path:
2323

2424

2525
def download_lgd_wrapper() -> bool:
26-
config.remove_envvar('default', 'LEGENDARY_WRAPPER_EXE')
27-
2826
runtime_assets = {
2927
wrapper_path().name: {
3028
'version': 'v0.0',

0 commit comments

Comments
 (0)