Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
101a9b5d5e | ||
|
|
7cd79a4e2a | ||
|
|
30c3acfb23 | ||
|
|
31f04db555 |
No files matched your search
@@ -430,6 +430,7 @@ public final class HMCLGameRepository extends DefaultGameRepository {
|
||||
.setNativesDirType(vs.getNativesDirType())
|
||||
.setNativesDir(vs.getNativesDir())
|
||||
.setProcessPriority(vs.getProcessPriority())
|
||||
.setGraphicsBackend(vs.getGraphicsBackend())
|
||||
.setRenderer(vs.getRenderer())
|
||||
.setEnableDebugLogOutput(vs.isEnableDebugLogOutput())
|
||||
.setUseNativeGLFW(vs.isUseNativeGLFW())
|
||||
|
||||
@@ -174,26 +174,27 @@ public final class LauncherHelper {
|
||||
}),
|
||||
Task.composeAsync(() -> {
|
||||
Renderer renderer = setting.getRenderer();
|
||||
if (renderer != Renderer.DEFAULT && OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
Library lib = NativePatcher.getWindowsMesaLoader(java, renderer, OperatingSystem.SYSTEM_VERSION);
|
||||
if (lib == null)
|
||||
return null;
|
||||
Path file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib);
|
||||
if (file.toAbsolutePath().toString().indexOf('=') >= 0) {
|
||||
LOG.warning("Invalid character '=' in the libraries directory path, unable to attach software renderer loader");
|
||||
return null;
|
||||
}
|
||||
if (renderer == null || renderer.getMesaDriverName() == null
|
||||
|| OperatingSystem.CURRENT_OS != OperatingSystem.WINDOWS) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String agent = FileUtils.getAbsolutePath(file) + "=" + renderer.name().toLowerCase(Locale.ROOT);
|
||||
Library lib = NativePatcher.getWindowsMesaLoader(java, renderer, OperatingSystem.SYSTEM_VERSION);
|
||||
if (lib == null)
|
||||
return null;
|
||||
Path file = dependencyManager.getGameRepository().getLibraryFile(version.get(), lib);
|
||||
if (file.toAbsolutePath().toString().indexOf('=') >= 0) {
|
||||
LOG.warning("Invalid character '=' in the libraries directory path, unable to attach software renderer loader");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (GameLibrariesTask.shouldDownloadLibrary(repository, version.get(), lib, integrityCheck)) {
|
||||
return new LibraryDownloadTask(dependencyManager, file, lib)
|
||||
.thenRunAsync(() -> javaAgents.add(agent));
|
||||
} else {
|
||||
javaAgents.add(agent);
|
||||
return null;
|
||||
}
|
||||
String agent = FileUtils.getAbsolutePath(file) + "=" + renderer.getMesaDriverName();
|
||||
|
||||
if (GameLibrariesTask.shouldDownloadLibrary(repository, version.get(), lib, integrityCheck)) {
|
||||
return new LibraryDownloadTask(dependencyManager, file, lib)
|
||||
.thenRunAsync(() -> javaAgents.add(agent));
|
||||
} else {
|
||||
javaAgents.add(agent);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
@@ -232,6 +233,7 @@ public final class LauncherHelper {
|
||||
if (quickPlayOption != null) {
|
||||
launchOptionsBuilder.setQuickPlayOption(quickPlayOption);
|
||||
}
|
||||
|
||||
LaunchOptions launchOptions = launchOptionsBuilder.create();
|
||||
|
||||
LOG.info("Here's the structure of game mod directory:\n" + FileUtils.printFileStructure(repository.getModsDirectory(selectedVersion), 10));
|
||||
|
||||
@@ -603,6 +603,20 @@ public final class VersionSetting implements Cloneable, Observable {
|
||||
processPriorityProperty.set(processPriority);
|
||||
}
|
||||
|
||||
private final ObjectProperty<GraphicsAPI> graphicsBackend = new SimpleObjectProperty<>(this, "graphicsBackend", GraphicsAPI.DEFAULT);
|
||||
|
||||
public ObjectProperty<GraphicsAPI> graphicsBackendProperty() {
|
||||
return graphicsBackend;
|
||||
}
|
||||
|
||||
public GraphicsAPI getGraphicsBackend() {
|
||||
return graphicsBackendProperty().get();
|
||||
}
|
||||
|
||||
public void setGraphicsBackend(GraphicsAPI api) {
|
||||
graphicsBackendProperty().set(api);
|
||||
}
|
||||
|
||||
private final ObjectProperty<Renderer> rendererProperty = new SimpleObjectProperty<>(this, "renderer", Renderer.DEFAULT);
|
||||
|
||||
public Renderer getRenderer() {
|
||||
@@ -820,6 +834,7 @@ public final class VersionSetting implements Cloneable, Observable {
|
||||
}
|
||||
obj.addProperty("java", java);
|
||||
|
||||
obj.addProperty("graphicsBackend", src.getGraphicsBackend().name());
|
||||
obj.addProperty("renderer", src.getRenderer().name());
|
||||
if (src.getRenderer() == Renderer.LLVMPIPE)
|
||||
obj.addProperty("useSoftwareRenderer", true);
|
||||
@@ -905,6 +920,15 @@ public final class VersionSetting implements Cloneable, Observable {
|
||||
return useSoftwareRenderer ? Renderer.LLVMPIPE : Renderer.DEFAULT;
|
||||
}));
|
||||
|
||||
vs.setGraphicsBackend(Optional.ofNullable(obj.get("graphicsBackend")).map(JsonElement::getAsString)
|
||||
.flatMap(name -> {
|
||||
try {
|
||||
return Optional.of(GraphicsAPI.valueOf(name.toUpperCase(Locale.ROOT)));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}).orElseGet(() -> vs.getRenderer().getApi()));
|
||||
|
||||
return vs;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ public final class LogWindow extends Stage {
|
||||
LogWindowImpl() {
|
||||
getStyleClass().add("log-window");
|
||||
|
||||
listView.getStyleClass().add("no-horizontal-scrollbar");
|
||||
listView.getProperties().put("no-smooth-scrolling", true);
|
||||
listView.setItems(FXCollections.observableList(new CircularArrayList<>(logs.size())));
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.StackPane;
|
||||
@@ -49,6 +50,8 @@ public class LineSelectButton<T> extends LineButton {
|
||||
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");
|
||||
|
||||
private JFXPopup popup;
|
||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
||||
private ObservableList<Node> popupItems; // keep a reference
|
||||
|
||||
public LineSelectButton() {
|
||||
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||
@@ -87,7 +90,7 @@ public class LineSelectButton<T> extends LineButton {
|
||||
|
||||
ripplerContainer.addEventFilter(ScrollEvent.ANY, ignored -> popup.hide());
|
||||
|
||||
Bindings.bindContent(popupMenu.getContent(), MappedObservableList.create(itemsProperty(), item -> {
|
||||
Bindings.bindContent(popupMenu.getContent(), popupItems = MappedObservableList.create(itemsProperty(), item -> {
|
||||
VBox vbox = new VBox();
|
||||
|
||||
var itemTitleLabel = new Label();
|
||||
|
||||
@@ -25,6 +25,7 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.layout.*;
|
||||
import org.jackhuang.hmcl.game.GraphicsAPI;
|
||||
import org.jackhuang.hmcl.game.NativesDirectoryType;
|
||||
import org.jackhuang.hmcl.game.Renderer;
|
||||
import org.jackhuang.hmcl.setting.Profile;
|
||||
@@ -36,6 +37,7 @@ import org.jackhuang.hmcl.util.i18n.I18n;
|
||||
import org.jackhuang.hmcl.util.io.FileUtils;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.util.platform.Platform;
|
||||
import org.jackhuang.hmcl.util.versioning.GameVersionNumber;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.FileSystems;
|
||||
@@ -69,6 +71,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
private final ComponentSublist nativesDirSublist;
|
||||
private final MultiFileItem<NativesDirectoryType> nativesDirItem;
|
||||
private final MultiFileItem.FileOption<NativesDirectoryType> nativesDirCustomOption;
|
||||
private final LineSelectButton<GraphicsAPI> graphicsBackendPane;
|
||||
private final LineSelectButton<Renderer> rendererPane;
|
||||
|
||||
public AdvancedVersionSettingPage(Profile profile, @Nullable String versionId, VersionSetting versionSetting) {
|
||||
@@ -79,6 +82,10 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
versionId == null ? i18n("settings.advanced") : i18n("settings.advanced.title", versionId)
|
||||
));
|
||||
|
||||
@Nullable GameVersionNumber gameVersion = versionId != null
|
||||
? GameVersionNumber.asGameVersion(profile.getRepository().getGameVersion(versionId))
|
||||
: null;
|
||||
|
||||
this.getStyleClass().add("gray-background");
|
||||
|
||||
ScrollPane scrollPane = new ScrollPane();
|
||||
@@ -185,6 +192,25 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
nativesDirHint.setText(i18n("settings.advanced.natives_directory.hint"));
|
||||
nativesDirItem.getChildren().add(nativesDirHint);
|
||||
|
||||
graphicsBackendPane = new LineSelectButton<>();
|
||||
graphicsBackendPane.setTitle(i18n("settings.advanced.graphics_backend"));
|
||||
graphicsBackendPane.setConverter(backend -> i18n("settings.advanced.graphics_backend." + backend.name().toLowerCase(Locale.ROOT)));
|
||||
graphicsBackendPane.setDescriptionConverter(backend -> switch (backend) {
|
||||
case DEFAULT -> i18n("settings.advanced.graphics_backend.default.desc");
|
||||
case OPENGL -> i18n("settings.advanced.graphics_backend.opengl.desc");
|
||||
case VULKAN -> {
|
||||
if (gameVersion == null)
|
||||
yield i18n("settings.advanced.graphics_backend.vulkan.desc.global");
|
||||
else if (gameVersion.compareTo("26.2-snapshot-2") < 0)
|
||||
yield i18n("settings.advanced.graphics_backend.vulkan.desc.unsupported");
|
||||
else
|
||||
yield i18n("settings.advanced.graphics_backend.vulkan.desc");
|
||||
}
|
||||
default -> null;
|
||||
});
|
||||
graphicsBackendPane.setValue(GraphicsAPI.DEFAULT);
|
||||
graphicsBackendPane.setItems(GraphicsAPI.values());
|
||||
|
||||
rendererPane = new LineSelectButton<>();
|
||||
rendererPane.setTitle(i18n("settings.advanced.renderer"));
|
||||
rendererPane.setConverter(e -> i18n("settings.advanced.renderer." + e.name().toLowerCase(Locale.ROOT)));
|
||||
@@ -192,7 +218,25 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
String bundleKey = "settings.advanced.renderer." + e.name().toLowerCase(Locale.ROOT) + ".desc";
|
||||
return I18n.hasKey(bundleKey) ? i18n(bundleKey) : null;
|
||||
});
|
||||
rendererPane.setItems(Renderer.values());
|
||||
rendererPane.setValue(Renderer.DEFAULT);
|
||||
rendererPane.setItems(Renderer.DEFAULT);
|
||||
|
||||
FXUtils.onChangeAndOperate(graphicsBackendPane.valueProperty(), backend -> {
|
||||
if (backend == null) { // unbind
|
||||
return;
|
||||
}
|
||||
|
||||
rendererPane.setItems(Renderer.SUPPORTED.get(backend));
|
||||
if (backend == GraphicsAPI.DEFAULT) {
|
||||
rendererPane.setDisable(true);
|
||||
rendererPane.setValue(Renderer.DEFAULT);
|
||||
} else {
|
||||
rendererPane.setDisable(false);
|
||||
if (rendererPane.getValue() == null || !rendererPane.getValue().isSupported(backend)) {
|
||||
rendererPane.setValue(Renderer.DEFAULT);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
noJVMArgsPane = new LineToggleButton();
|
||||
noJVMArgsPane.setTitle(i18n("settings.advanced.no_jvm_args"));
|
||||
@@ -219,7 +263,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
useNativeOpenALPane.setSubtitle(i18n("settings.advanced.linux_freebsd_only"));
|
||||
|
||||
workaroundPane.getContent().setAll(
|
||||
nativesDirSublist, rendererPane, noJVMArgsPane, noOptimizingJVMArgsPane, noGameCheckPane,
|
||||
nativesDirSublist, graphicsBackendPane, rendererPane, noJVMArgsPane, noOptimizingJVMArgsPane, noGameCheckPane,
|
||||
noJVMCheckPane, noNativesPatchPane
|
||||
);
|
||||
|
||||
@@ -252,6 +296,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
FXUtils.bindString(txtPreLaunchCommand, versionSetting.preLaunchCommandProperty());
|
||||
FXUtils.bindString(txtPostExitCommand, versionSetting.postExitCommandProperty());
|
||||
rendererPane.valueProperty().bindBidirectional(versionSetting.rendererProperty());
|
||||
graphicsBackendPane.valueProperty().bindBidirectional(versionSetting.graphicsBackendProperty());
|
||||
noGameCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().bindBidirectional(versionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().bindBidirectional(versionSetting.noJVMArgsProperty());
|
||||
@@ -294,6 +339,7 @@ public final class AdvancedVersionSettingPage extends StackPane implements Decor
|
||||
FXUtils.unbind(txtPreLaunchCommand, versionSetting.preLaunchCommandProperty());
|
||||
FXUtils.unbind(txtPostExitCommand, versionSetting.postExitCommandProperty());
|
||||
rendererPane.valueProperty().unbindBidirectional(versionSetting.rendererProperty());
|
||||
graphicsBackendPane.valueProperty().unbindBidirectional(versionSetting.graphicsBackendProperty());
|
||||
noGameCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckGameProperty());
|
||||
noJVMCheckPane.selectedProperty().unbindBidirectional(versionSetting.notCheckJVMProperty());
|
||||
noJVMArgsPane.selectedProperty().unbindBidirectional(versionSetting.noJVMArgsProperty());
|
||||
|
||||
@@ -189,15 +189,16 @@ public final class NativePatcher {
|
||||
return version.setLibraries(newLibraries);
|
||||
}
|
||||
|
||||
public static @Nullable Library getWindowsMesaLoader(@NotNull JavaRuntime javaVersion, @NotNull Renderer renderer, @NotNull OSVersion windowsVersion) {
|
||||
/// @see <a href="https://github.com/HMCL-dev/mesa-loader-windows">Java Mesa Loader for Windows</a>
|
||||
public static @Nullable Library getWindowsMesaLoader(@NotNull JavaRuntime java, @NotNull Renderer renderer, @NotNull OSVersion windowsVersion) {
|
||||
if (renderer == Renderer.DEFAULT)
|
||||
return null;
|
||||
|
||||
if (windowsVersion.isAtLeast(OSVersion.WINDOWS_10)) {
|
||||
return getNatives(javaVersion.getPlatform()).get("mesa-loader");
|
||||
return getNatives(java.getPlatform()).get("mesa-loader");
|
||||
} else if (windowsVersion.isAtLeast(OSVersion.WINDOWS_7)) {
|
||||
if (renderer == Renderer.LLVMPIPE)
|
||||
return getNatives(javaVersion.getPlatform()).get("software-renderer-loader");
|
||||
return getNatives(java.getPlatform()).get("software-renderer-loader");
|
||||
else
|
||||
return null;
|
||||
} else {
|
||||
|
||||
@@ -96,6 +96,10 @@ public class Translator_lzh extends Translator {
|
||||
case GA -> {
|
||||
// do nothing
|
||||
}
|
||||
case SNAPSHOT -> {
|
||||
builder.append("之快照");
|
||||
appendDigitByDigit(builder, release.getEaVersion().toString());
|
||||
}
|
||||
case PRE_RELEASE -> {
|
||||
builder.append("之預");
|
||||
appendDigitByDigit(builder, release.getEaVersion().toString());
|
||||
|
||||
@@ -1337,6 +1337,15 @@ settings.advanced.dont_patch_natives=Do not attempt to automatically replace nat
|
||||
settings.advanced.environment_variables=Environment Variables
|
||||
settings.advanced.game_dir.default=Default (".minecraft/")
|
||||
settings.advanced.game_dir.independent=Isolated (".minecraft/versions/<instance name>/", except for assets and libraries)
|
||||
settings.advanced.graphics_backend=Graphics API
|
||||
settings.advanced.graphics_backend.default=Default
|
||||
settings.advanced.graphics_backend.default.desc=Follow the game's settings
|
||||
settings.advanced.graphics_backend.opengl=OpenGL
|
||||
settings.advanced.graphics_backend.opengl.desc=Use OpenGL for rendering
|
||||
settings.advanced.graphics_backend.vulkan=Vulkan
|
||||
settings.advanced.graphics_backend.vulkan.desc=Use Vulkan for rendering
|
||||
settings.advanced.graphics_backend.vulkan.desc.global=Use Vulkan for rendering (Since Minecraft 26.2)
|
||||
settings.advanced.graphics_backend.vulkan.desc.unsupported=Use Vulkan for rendering (not supported for the current game version)
|
||||
settings.advanced.java_permanent_generation_space=PermGen Space
|
||||
settings.advanced.java_permanent_generation_space.prompt=in MiB
|
||||
settings.advanced.jvm=JVM Options
|
||||
@@ -1379,13 +1388,17 @@ settings.advanced.post_exit_command=Post-exit Command
|
||||
settings.advanced.post_exit_command.prompt=Commands to execute after the game exits
|
||||
settings.advanced.renderer=Renderer
|
||||
settings.advanced.renderer.default=Default
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.default.desc=Use System Default
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (Poor performance and compatibility)
|
||||
settings.advanced.renderer.d3d12.desc=OpenGL renderer based on DirectX 12
|
||||
settings.advanced.renderer.lavapipe=Mesa Lavapipe
|
||||
settings.advanced.renderer.lavapipe.desc=Software Vulkan Renderer
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=Software (Poor performance, best compatibility)
|
||||
settings.advanced.renderer.llvmpipe.desc=Software OpenGL Renderer
|
||||
settings.advanced.renderer.dozen=Mesa Dozen
|
||||
settings.advanced.renderer.dozen.desc=Vulkan renderer based on DirectX 12 (Experimental)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (Best performance, poor compatibility)
|
||||
settings.advanced.renderer.zink.desc=OpenGL renderer based on Vulkan
|
||||
settings.advanced.server_ip=Server Address
|
||||
settings.advanced.server_ip.prompt=Automatically join after launching the game
|
||||
settings.advanced.unsupported_system_options=Settings not applicable to the current system
|
||||
|
||||
@@ -1364,13 +1364,9 @@ settings.advanced.post_exit_command=أمر ما بعد الإغلاق
|
||||
settings.advanced.post_exit_command.prompt=أوامر تُنفَّذ بعد إغلاق اللعبة
|
||||
settings.advanced.renderer=المُصيِّر
|
||||
settings.advanced.renderer.default=افتراضي
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (أداء وتوافق ضعيفان)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=برمجي (أداء ضعيف، توافق أفضل)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (أفضل أداء، توافق ضعيف)
|
||||
settings.advanced.server_ip=عنوان الخادم
|
||||
settings.advanced.server_ip.prompt=الانضمام تلقائياً بعد تشغيل اللعبة
|
||||
settings.advanced.unsupported_system_options=إعدادات غير مطبّقة على النظام الحالي
|
||||
|
||||
@@ -1268,13 +1268,9 @@ settings.advanced.post_exit_command=Comando post-salida
|
||||
settings.advanced.post_exit_command.prompt=El comando se ejecuta después de que el juego se detenga
|
||||
settings.advanced.renderer=Renderizador
|
||||
settings.advanced.renderer.default=Por defecto
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (Rendimiento y compatibilidad deficientes)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=Software (Bajo rendimiento, máxima compatibilidad)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (Máximo rendimiento, baja compatibilidad)
|
||||
settings.advanced.server_ip=Dirección del servidor
|
||||
settings.advanced.server_ip.prompt=Entrar automáticamente después de ejecutar el juego
|
||||
settings.advanced.unsupported_system_options=Configuración no aplicable al sistema actual
|
||||
|
||||
@@ -792,13 +792,9 @@ settings.advanced.post_exit_command=終了後のコマンド
|
||||
settings.advanced.post_exit_command.prompt=ゲーム終了後に実行されます
|
||||
settings.advanced.renderer=レンダラー
|
||||
settings.advanced.renderer.default=デフォルト
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (低パフォーマンス、低互換性)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=ソフトウェア (低速だが、互換性は最高)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (最高パフォーマンス、低互換性)
|
||||
settings.advanced.server_ip=サーバーアドレス
|
||||
settings.advanced.server_ip.prompt=ゲームの起動時にサーバーに参加する
|
||||
settings.advanced.unsupported_system_options=サポートされていないシステムオプション
|
||||
|
||||
@@ -1085,13 +1085,9 @@ settings.advanced.post_exit_command=令於戲訖
|
||||
settings.advanced.post_exit_command.prompt=將後戲訖而行
|
||||
settings.advanced.renderer=繪器
|
||||
settings.advanced.renderer.default=本
|
||||
settings.advanced.renderer.default.desc=開圖庫
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (效與所適皆差,勘誤之用)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=軟繪器 (效差,所適至)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (效至,所適差)
|
||||
settings.advanced.server_ip=伺服器之址
|
||||
settings.advanced.server_ip.prompt=本之址,啟訖徑入是伺服器
|
||||
settings.advanced.unsupported_system_options=不逮今之械網所選
|
||||
|
||||
@@ -1259,13 +1259,9 @@ settings.advanced.post_exit_command=Команда после выхода
|
||||
settings.advanced.post_exit_command.prompt=Команды, которые необходимо выполнить после выхода из игры
|
||||
settings.advanced.renderer=Рендерер
|
||||
settings.advanced.renderer.default=По умолчанию
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (Низкая производительность и совместимость)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=ПО (Низкая производительность, лучшая совместимость)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (Лучшая производительность, низкая совместимость)
|
||||
settings.advanced.server_ip=Адрес сервера
|
||||
settings.advanced.server_ip.prompt=Присоединяться к серверу при запуске игры
|
||||
settings.advanced.unsupported_system_options=Настройки, не применимые к текущей системе
|
||||
|
||||
@@ -1206,13 +1206,9 @@ settings.advanced.post_exit_command=Команда після виходу
|
||||
settings.advanced.post_exit_command.prompt=Команди для виконання після виходу з гри
|
||||
settings.advanced.renderer=Рендерер
|
||||
settings.advanced.renderer.default=По умолчанию
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (Погана продуктивність та сумісність)
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=Програмний (Погана продуктивність, найкраща сумісність)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (Найкраща продуктивність, погана сумісність)
|
||||
settings.advanced.server_ip=Адреса сервера
|
||||
settings.advanced.server_ip.prompt=Автоматично приєднатися після запуску гри
|
||||
settings.advanced.unsupported_system_options=Налаштування, що не застосовуються до поточної системи
|
||||
|
||||
@@ -1127,6 +1127,15 @@ settings.advanced.dont_patch_natives=不嘗試自動取代本機庫
|
||||
settings.advanced.environment_variables=環境變數
|
||||
settings.advanced.game_dir.default=預設 (".minecraft/")
|
||||
settings.advanced.game_dir.independent=各實例獨立 (".minecraft/versions/<實例名>/",除 assets、libraries 外)
|
||||
settings.advanced.graphics_backend=圖形 API
|
||||
settings.advanced.graphics_backend.default=預設
|
||||
settings.advanced.graphics_backend.default.desc=遵循遊戲設定
|
||||
settings.advanced.graphics_backend.opengl=OpenGL
|
||||
settings.advanced.graphics_backend.opengl.desc=使用 OpenGL 渲染
|
||||
settings.advanced.graphics_backend.vulkan=Vulkan
|
||||
settings.advanced.graphics_backend.vulkan.desc=使用 Vulkan 渲染
|
||||
settings.advanced.graphics_backend.vulkan.desc.global=使用 Vulkan 渲染 (適用於 Minecraft 26.2 及更高版本)
|
||||
settings.advanced.graphics_backend.vulkan.desc.unsupported=使用 Vulkan 渲染 (不適用於當前遊戲版本)
|
||||
settings.advanced.java_permanent_generation_space=記憶體永久儲存區域
|
||||
settings.advanced.java_permanent_generation_space.prompt=單位 MiB
|
||||
settings.advanced.jvm=Java 虛擬機設定
|
||||
@@ -1166,13 +1175,17 @@ settings.advanced.post_exit_command=遊戲結束後執行指令
|
||||
settings.advanced.post_exit_command.prompt=將在遊戲結束後呼叫使用
|
||||
settings.advanced.renderer=繪製器
|
||||
settings.advanced.renderer.default=預設
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.default.desc=使用系統預設繪製器
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (效能與相容性較差,用於除錯)
|
||||
settings.advanced.renderer.d3d12.desc=基於 DirectX 12 的 OpenGL 繪製器
|
||||
settings.advanced.renderer.lavapipe=Mesa Lavapipe
|
||||
settings.advanced.renderer.lavapipe.desc=軟體 Vulkan 繪製器
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=軟繪製器 (效能較差,相容性最好)
|
||||
settings.advanced.renderer.llvmpipe.desc=軟體 OpenGL 繪製器
|
||||
settings.advanced.renderer.dozen=Mesa Dozen
|
||||
settings.advanced.renderer.dozen.desc=基於 DirectX 12 的 Vulkan 繪製器 (實驗性)
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (效能最好,相容性較差)
|
||||
settings.advanced.renderer.zink.desc=基於 Vulkan 的 OpenGL 繪製器
|
||||
settings.advanced.server_ip=伺服器位址
|
||||
settings.advanced.server_ip.prompt=預設,啟動遊戲後直接進入對應伺服器
|
||||
settings.advanced.unsupported_system_options=不適用於目前系統的選項
|
||||
|
||||
@@ -1132,6 +1132,15 @@ settings.advanced.dont_patch_natives=不尝试自动替换本地库
|
||||
settings.advanced.environment_variables=环境变量
|
||||
settings.advanced.game_dir.default=默认 (".minecraft/")
|
||||
settings.advanced.game_dir.independent=各实例独立 (存放在 ".minecraft/versions/<实例名>/",除 assets、libraries 外)
|
||||
settings.advanced.graphics_backend=图形 API
|
||||
settings.advanced.graphics_backend.default=默认
|
||||
settings.advanced.graphics_backend.default.desc=遵循游戏设置
|
||||
settings.advanced.graphics_backend.opengl=OpenGL
|
||||
settings.advanced.graphics_backend.opengl.desc=使用 OpenGL 渲染
|
||||
settings.advanced.graphics_backend.vulkan=Vulkan
|
||||
settings.advanced.graphics_backend.vulkan.desc=使用 Vulkan 渲染
|
||||
settings.advanced.graphics_backend.vulkan.desc.global=使用 Vulkan 渲染 (适用于 Minecraft 26.2 及更高版本)
|
||||
settings.advanced.graphics_backend.vulkan.desc.unsupported=使用 Vulkan 渲染 (不适用于当前游戏版本)
|
||||
settings.advanced.java_permanent_generation_space=内存永久保存区域
|
||||
settings.advanced.java_permanent_generation_space.prompt=单位 MiB
|
||||
settings.advanced.jvm=Java 虚拟机设置
|
||||
@@ -1171,13 +1180,17 @@ settings.advanced.post_exit_command=游戏结束后执行命令
|
||||
settings.advanced.post_exit_command.prompt=将在游戏结束后调用
|
||||
settings.advanced.renderer=渲染器
|
||||
settings.advanced.renderer.default=默认
|
||||
settings.advanced.renderer.default.desc=OpenGL
|
||||
settings.advanced.renderer.default.desc=使用系统默认渲染器
|
||||
settings.advanced.renderer.d3d12=Mesa D3D12
|
||||
settings.advanced.renderer.d3d12.desc=DirectX 12 (性能与兼容性较差,用于调试)
|
||||
settings.advanced.renderer.d3d12.desc=基于 DirectX 12 的 OpenGL 渲染器
|
||||
settings.advanced.renderer.dozen=Mesa Dozen
|
||||
settings.advanced.renderer.dozen.desc=基于 DirectX 12 的 Vulkan 渲染器 (实验性)
|
||||
settings.advanced.renderer.lavapipe=Mesa Lavapipe
|
||||
settings.advanced.renderer.lavapipe.desc=软件 Vulkan 渲染器
|
||||
settings.advanced.renderer.llvmpipe=Mesa LLVMpipe
|
||||
settings.advanced.renderer.llvmpipe.desc=软渲染器 (性能较差,兼容性最好)
|
||||
settings.advanced.renderer.llvmpipe.desc=软件 OpenGL 渲染器
|
||||
settings.advanced.renderer.zink=Mesa Zink
|
||||
settings.advanced.renderer.zink.desc=Vulkan (性能最好,兼容性较差)
|
||||
settings.advanced.renderer.zink.desc=基于 Vulkan 的 OpenGL 渲染器
|
||||
settings.advanced.server_ip=服务器地址
|
||||
settings.advanced.server_ip.prompt=默认,启动游戏后可以直接进入对应服务器
|
||||
settings.advanced.unsupported_system_options=不适用于当前系统的选项
|
||||
|
||||
@@ -4403,13 +4403,13 @@
|
||||
},
|
||||
"windows-x86_64": {
|
||||
"mesa-loader": {
|
||||
"name": "org.glavo:mesa-loader-windows:25.0.3:x64",
|
||||
"name": "org.glavo:mesa-loader-windows:26.0.4:x64",
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-x64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-x64.jar",
|
||||
"sha1": "b2552fcc8c98e95b4559c39f2ff87cdb3aaaa513",
|
||||
"size": 27971214
|
||||
"path": "org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-x64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-x64.jar",
|
||||
"sha1": "f8da709c59ef61f531c91434ca0e3b4f39202981",
|
||||
"size": 49873846
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4427,13 +4427,13 @@
|
||||
},
|
||||
"windows-x86": {
|
||||
"mesa-loader": {
|
||||
"name": "org.glavo:mesa-loader-windows:25.0.3:x86",
|
||||
"name": "org.glavo:mesa-loader-windows:26.0.4:x86",
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-x86.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-x86.jar",
|
||||
"sha1": "6fd0fd7da88ca6636f735e1e0f6feb7f62f59715",
|
||||
"size": 23311299
|
||||
"path": "org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-x86.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-x86.jar",
|
||||
"sha1": "ac6afaa8baa7c17468267c09e77e1296ee92d5ed",
|
||||
"size": 41742113
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4816,13 +4816,13 @@
|
||||
"com.mojang:text2speech:1.12.4:natives": null,
|
||||
"com.mojang:text2speech:1.13.9:natives-windows": null,
|
||||
"mesa-loader": {
|
||||
"name": "org.glavo:mesa-loader-windows:25.0.3:arm64",
|
||||
"name": "org.glavo:mesa-loader-windows:26.0.4:arm64",
|
||||
"downloads": {
|
||||
"artifact": {
|
||||
"path": "org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/25.0.3/mesa-loader-windows-25.0.3-arm64.jar",
|
||||
"sha1": "40ca5de3351bf48b7b9efa5d2598d5b6b4d1ab8e",
|
||||
"size": 24905270
|
||||
"path": "org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-arm64.jar",
|
||||
"url": "https://repo1.maven.org/maven2/org/glavo/mesa-loader-windows/26.0.4/mesa-loader-windows-26.0.4-arm64.jar",
|
||||
"sha1": "5c761a344700a07eaded51c5cf0cde36ee614706",
|
||||
"size": 43504189
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Hello Minecraft! Launcher
|
||||
* Copyright (C) 2026 huangyuhui <huanghongxun2008@126.com> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/// The Graphics API.
|
||||
public enum GraphicsAPI {
|
||||
DEFAULT,
|
||||
OPENGL,
|
||||
VULKAN;
|
||||
|
||||
private final String minecraftArg = name().toLowerCase(Locale.ROOT);
|
||||
|
||||
public String getMinecraftArg() {
|
||||
return minecraftArg;
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,7 @@ public class LaunchOptions implements Serializable {
|
||||
private NativesDirectoryType nativesDirType;
|
||||
private String nativesDir;
|
||||
private ProcessPriority processPriority = ProcessPriority.NORMAL;
|
||||
private GraphicsAPI graphicsBackend = GraphicsAPI.DEFAULT;
|
||||
private Renderer renderer = Renderer.DEFAULT;
|
||||
private boolean useNativeGLFW;
|
||||
private boolean useNativeOpenAL;
|
||||
@@ -244,7 +245,11 @@ public class LaunchOptions implements Serializable {
|
||||
return processPriority;
|
||||
}
|
||||
|
||||
public Renderer getRenderer() {
|
||||
public @NotNull GraphicsAPI getGraphicsBackend() {
|
||||
return graphicsBackend;
|
||||
}
|
||||
|
||||
public @NotNull Renderer getRenderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
@@ -435,8 +440,13 @@ public class LaunchOptions implements Serializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRenderer(@NotNull Renderer renderer) {
|
||||
options.renderer = renderer;
|
||||
public Builder setGraphicsBackend(GraphicsAPI backend) {
|
||||
options.graphicsBackend = Objects.requireNonNullElse(backend, GraphicsAPI.DEFAULT);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setRenderer(Renderer renderer) {
|
||||
options.renderer = Objects.requireNonNullElse(renderer, Renderer.DEFAULT);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,73 @@
|
||||
*/
|
||||
package org.jackhuang.hmcl.game;
|
||||
|
||||
import org.jetbrains.annotations.NotNullByDefault;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/// @author Glavo
|
||||
@NotNullByDefault
|
||||
public enum Renderer {
|
||||
DEFAULT,
|
||||
ZINK,
|
||||
LLVMPIPE,
|
||||
D3D12
|
||||
DEFAULT(GraphicsAPI.DEFAULT, null, null),
|
||||
|
||||
LAVAPIPE(GraphicsAPI.VULKAN, "lavapipe", "lvp"),
|
||||
|
||||
// Currently, Dozen does not support the VK_KHR_push_descriptor feature, so it cannot launch Minecraft 26.2
|
||||
// Using Dozen can run Minecraft 1.21.11 + VulkanMod, but it will cause the game to crash after playing for a while
|
||||
DOZEN(GraphicsAPI.VULKAN, "dzn", "dzn"),
|
||||
|
||||
LLVMPIPE(GraphicsAPI.OPENGL, "llvmpipe", null),
|
||||
ZINK(GraphicsAPI.OPENGL, "zink", null),
|
||||
D3D12(GraphicsAPI.OPENGL, "d3d12", null),
|
||||
;
|
||||
|
||||
/// Map the graphics API to supported renderers.
|
||||
public static final Map<GraphicsAPI, List<Renderer>> SUPPORTED;
|
||||
|
||||
static {
|
||||
var map = new EnumMap<GraphicsAPI, List<Renderer>>(GraphicsAPI.class);
|
||||
|
||||
for (var api : GraphicsAPI.values()) {
|
||||
map.put(api, Stream.of(values()).filter(it -> it.isSupported(api)).toList());
|
||||
}
|
||||
|
||||
SUPPORTED = map;
|
||||
}
|
||||
|
||||
private final GraphicsAPI api;
|
||||
|
||||
private final @Nullable String loaderName;
|
||||
private final @Nullable String icdName;
|
||||
|
||||
Renderer(GraphicsAPI api, @Nullable String loaderName, @Nullable String icdName) {
|
||||
this.api = api;
|
||||
this.loaderName = loaderName;
|
||||
this.icdName = icdName;
|
||||
}
|
||||
|
||||
/// Get the Graphics API used by this renderer.
|
||||
public GraphicsAPI getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
public boolean isSupported(GraphicsAPI api) {
|
||||
return this.api == api || this.api == GraphicsAPI.DEFAULT;
|
||||
}
|
||||
|
||||
public @Nullable String getMesaDriverName() {
|
||||
return loaderName;
|
||||
}
|
||||
|
||||
public @Nullable String getIcdName() {
|
||||
return icdName;
|
||||
}
|
||||
|
||||
public @Nullable String getIcdFileName() {
|
||||
return icdName != null ? icdName + "_icd.json" : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -104,7 +104,7 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
// Executable
|
||||
if (StringUtils.isNotBlank(options.getWrapper()))
|
||||
res.addAllWithoutParsing(StringUtils.tokenize(options.getWrapper(), getEnvVars()));
|
||||
res.addAllWithoutParsing(StringUtils.tokenize(options.getWrapper(), getEnvVars(nativeFolder)));
|
||||
|
||||
res.add(options.getJava().getBinary().toString());
|
||||
|
||||
@@ -265,6 +265,12 @@ public class DefaultLauncher extends Launcher {
|
||||
res.addDefault("-Dfml.ignorePatchDiscrepancies=", "true");
|
||||
}
|
||||
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS
|
||||
&& options.getRenderer() != null
|
||||
&& options.getRenderer().getMesaDriverName() != null) {
|
||||
res.addDefault("-Dorg.glavo.mesa.loader.nativeDir=", FileUtils.getAbsolutePath(nativeFolder.resolve("mesa-loader")));
|
||||
}
|
||||
|
||||
Set<String> classpath = repository.getClasspath(version);
|
||||
|
||||
if (analyzer.has(LibraryAnalyzer.LibraryType.CLEANROOM)) {
|
||||
@@ -395,6 +401,12 @@ public class DefaultLauncher extends Launcher {
|
||||
}
|
||||
}
|
||||
|
||||
if (options.getGraphicsBackend() != GraphicsAPI.DEFAULT
|
||||
&& gameVersion.isPresent() && GameVersionNumber.compare(gameVersion.get(), "26.2-snapshot-2") >= 0) {
|
||||
res.add("--graphicsBackend");
|
||||
res.add(options.getGraphicsBackend().getMinecraftArg());
|
||||
}
|
||||
|
||||
res.addAllWithoutParsing(Arguments.parseStringArguments(options.getGameArguments(), configuration));
|
||||
|
||||
res.removeIf(it -> getForbiddens().containsKey(it) && getForbiddens().get(it).get());
|
||||
@@ -564,8 +576,8 @@ public class DefaultLauncher extends Launcher {
|
||||
Path runDirectory = repository.getRunDirectory(version.getId());
|
||||
|
||||
if (StringUtils.isNotBlank(options.getPreLaunchCommand())) {
|
||||
ProcessBuilder builder = new ProcessBuilder(StringUtils.tokenize(options.getPreLaunchCommand(), getEnvVars())).directory(runDirectory.toFile());
|
||||
builder.environment().putAll(getEnvVars());
|
||||
ProcessBuilder builder = new ProcessBuilder(StringUtils.tokenize(options.getPreLaunchCommand(), getEnvVars(nativeFolder))).directory(runDirectory.toFile());
|
||||
builder.environment().putAll(getEnvVars(nativeFolder));
|
||||
SystemUtils.callExternalProcess(builder);
|
||||
}
|
||||
|
||||
@@ -578,7 +590,7 @@ public class DefaultLauncher extends Launcher {
|
||||
Path appdata = options.getGameDir().toAbsolutePath().getParent();
|
||||
if (appdata != null) builder.environment().put("APPDATA", appdata.toString());
|
||||
|
||||
builder.environment().putAll(getEnvVars());
|
||||
builder.environment().putAll(getEnvVars(nativeFolder));
|
||||
process = builder.start();
|
||||
} catch (IOException e) {
|
||||
throw new ProcessCreationException(e);
|
||||
@@ -586,12 +598,35 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
ManagedProcess p = new ManagedProcess(process, rawCommandLine);
|
||||
if (listener != null)
|
||||
startMonitors(p, listener, command.encoding, daemon);
|
||||
startMonitors(p, nativeFolder, listener, command.encoding, daemon);
|
||||
return p;
|
||||
}
|
||||
|
||||
private Map<String, String> getEnvVars() {
|
||||
private @Nullable Path findVulkanDescriptorFile(List<Path> dirs, String driverNameBase) {
|
||||
String archName = switch (options.getJava().getArchitecture()) {
|
||||
case X86 -> "i686";
|
||||
case X86_64 -> "x86_64";
|
||||
default -> options.getJava().getArchitecture().getCheckedName();
|
||||
};
|
||||
|
||||
for (Path dir : dirs) {
|
||||
if (Files.isDirectory(dir)) {
|
||||
Path file = dir.resolve(driverNameBase + "." + archName + ".json");
|
||||
if (Files.isRegularFile(file))
|
||||
return file;
|
||||
|
||||
file = dir.resolve(driverNameBase + ".json");
|
||||
if (Files.isRegularFile(file))
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Map<String, String> getEnvVars(Path nativeFolder) {
|
||||
String versionName = Optional.ofNullable(options.getVersionName()).orElse(version.getId());
|
||||
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("INST_NAME", versionName);
|
||||
env.put("INST_ID", versionName);
|
||||
@@ -602,15 +637,26 @@ public class DefaultLauncher extends Launcher {
|
||||
Renderer renderer = options.getRenderer();
|
||||
if (renderer != Renderer.DEFAULT) {
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
|
||||
if (renderer != Renderer.LLVMPIPE)
|
||||
env.put("GALLIUM_DRIVER", renderer.name().toLowerCase(Locale.ROOT));
|
||||
if (renderer.getMesaDriverName() != null) {
|
||||
if (renderer.getApi() == GraphicsAPI.OPENGL && renderer != Renderer.LLVMPIPE)
|
||||
env.put("GALLIUM_DRIVER", renderer.getMesaDriverName());
|
||||
|
||||
if (renderer.getApi() == GraphicsAPI.VULKAN) {
|
||||
String icdFile = FileUtils.getAbsolutePath(nativeFolder.resolve("mesa-loader/" + renderer.getIcdFileName()));
|
||||
|
||||
env.put("VK_ICD_FILENAMES", icdFile);
|
||||
env.put("VK_DRIVER_FILES", icdFile);
|
||||
}
|
||||
}
|
||||
} else if (OperatingSystem.CURRENT_OS == OperatingSystem.LINUX) {
|
||||
env.put("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||
switch (renderer) {
|
||||
case LLVMPIPE:
|
||||
case LLVMPIPE: {
|
||||
env.put("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||
env.put("LIBGL_ALWAYS_SOFTWARE", "1");
|
||||
break;
|
||||
case ZINK:
|
||||
}
|
||||
case ZINK: {
|
||||
env.put("__GLX_VENDOR_LIBRARY_NAME", "mesa");
|
||||
env.put("MESA_LOADER_DRIVER_OVERRIDE", "zink");
|
||||
/*
|
||||
* The amdgpu DDX is missing support for modifiers, causing Zink to fail.
|
||||
@@ -620,6 +666,19 @@ public class DefaultLauncher extends Launcher {
|
||||
*/
|
||||
env.put("LIBGL_KOPPER_DRI2", "1");
|
||||
break;
|
||||
}
|
||||
case LAVAPIPE: {
|
||||
Path lvp = findVulkanDescriptorFile(
|
||||
List.of(Path.of("/usr/share/vulkan/icd.d"), Path.of("/etc/vulkan/icd.d")),
|
||||
"lvp_icd"
|
||||
);
|
||||
if (lvp != null) {
|
||||
env.put("VK_ICD_FILENAMES", FileUtils.getAbsolutePath(lvp));
|
||||
env.put("VK_DRIVER_FILES", FileUtils.getAbsolutePath(lvp));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -677,7 +736,7 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
final Command commandLine = generateCommandLine(nativeFolder);
|
||||
final String command = usePowerShell ? null : commandLine.commandLine.toString();
|
||||
Map<String, String> envVars = getEnvVars();
|
||||
Map<String, String> envVars = getEnvVars(nativeFolder);
|
||||
|
||||
if (isWindows && !usePowerShell) {
|
||||
// https://stackoverflow.com/a/28452546
|
||||
@@ -820,7 +879,7 @@ public class DefaultLauncher extends Launcher {
|
||||
throw new ExecutionPolicyLimitException();
|
||||
}
|
||||
|
||||
private void startMonitors(ManagedProcess managedProcess, ProcessListener processListener, Charset encoding, boolean isDaemon) {
|
||||
private void startMonitors(ManagedProcess managedProcess, Path nativeFolder, ProcessListener processListener, Charset encoding, boolean isDaemon) {
|
||||
processListener.setProcess(managedProcess);
|
||||
Thread stdout = Lang.thread(new StreamPump(managedProcess.getProcess().getInputStream(), it -> {
|
||||
processListener.onLog(it, false);
|
||||
@@ -837,8 +896,8 @@ public class DefaultLauncher extends Launcher {
|
||||
|
||||
if (StringUtils.isNotBlank(options.getPostExitCommand())) {
|
||||
try {
|
||||
ProcessBuilder builder = new ProcessBuilder(StringUtils.tokenize(options.getPostExitCommand(), getEnvVars())).directory(options.getGameDir().toFile());
|
||||
builder.environment().putAll(getEnvVars());
|
||||
ProcessBuilder builder = new ProcessBuilder(StringUtils.tokenize(options.getPostExitCommand(), getEnvVars(nativeFolder))).directory(options.getGameDir().toFile());
|
||||
builder.environment().putAll(getEnvVars(nativeFolder));
|
||||
SystemUtils.callExternalProcess(builder);
|
||||
} catch (Throwable e) {
|
||||
LOG.warning("An Exception happened while running exit command.", e);
|
||||
|
||||
@@ -914,4 +914,6 @@
|
||||
26.1
|
||||
26.1.1-rc-1
|
||||
26.1.1
|
||||
26.1.2-rc-1
|
||||
26.1.2
|
||||
26w14a
|
||||
Reference in new issue
Block a user