diff --git a/common/src/main/java/org/vivecraft/client/VivecraftVRMod.java b/common/src/main/java/org/vivecraft/client/VivecraftVRMod.java index c0c90717b..26ab0a657 100644 --- a/common/src/main/java/org/vivecraft/client/VivecraftVRMod.java +++ b/common/src/main/java/org/vivecraft/client/VivecraftVRMod.java @@ -149,6 +149,6 @@ public boolean isSafeBinding(KeyMapping kb) { } public boolean isModBinding(KeyMapping kb) { - return !this.vanillaBindingSet.contains(kb); + return !this.vanillaBindingSet.contains(kb) && kb != mc.options.keyUse; } } diff --git a/common/src/main/java/org/vivecraft/client/gui/screens/ErrorScreen.java b/common/src/main/java/org/vivecraft/client/gui/screens/ErrorScreen.java index af9e21a4f..7209ab77e 100644 --- a/common/src/main/java/org/vivecraft/client/gui/screens/ErrorScreen.java +++ b/common/src/main/java/org/vivecraft/client/gui/screens/ErrorScreen.java @@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull; import org.vivecraft.client.gui.widgets.TextScrollWidget; - public class ErrorScreen extends Screen { private final Screen lastScreen; diff --git a/common/src/main/java/org/vivecraft/client/gui/settings/GuiHUDSettings.java b/common/src/main/java/org/vivecraft/client/gui/settings/GuiHUDSettings.java index bd6cb7359..6c50eaa49 100644 --- a/common/src/main/java/org/vivecraft/client/gui/settings/GuiHUDSettings.java +++ b/common/src/main/java/org/vivecraft/client/gui/settings/GuiHUDSettings.java @@ -1,13 +1,14 @@ package org.vivecraft.client.gui.settings; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; import net.minecraft.client.gui.screens.Screen; import org.vivecraft.client.gui.framework.GuiVROption; import org.vivecraft.client.gui.framework.GuiVROptionsBase; import org.vivecraft.client.gui.framework.VROptionEntry; +import org.vivecraft.client_vr.VRState; import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; -import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; import org.vivecraft.client_vr.settings.VRSettings; public class GuiHUDSettings extends GuiVROptionsBase { @@ -20,20 +21,20 @@ public class GuiHUDSettings extends GuiVROptionsBase { new VROptionEntry(VRSettings.VrOptions.HUD_OPACITY), new VROptionEntry(VRSettings.VrOptions.RENDER_MENU_BACKGROUND), new VROptionEntry(VRSettings.VrOptions.TOUCH_HOTBAR), - new VROptionEntry(VRSettings.VrOptions.AUTO_OPEN_KEYBOARD), new VROptionEntry(VRSettings.VrOptions.MENU_ALWAYS_FOLLOW_FACE), - new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD, (button, mousePos) -> { - KeyboardHandler.setOverlayShowing(false); - return false; - }), new VROptionEntry(VRSettings.VrOptions.GUI_APPEAR_OVER_BLOCK), - new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD_SCALE), + new VROptionEntry(VRSettings.VrOptions.DOUBLE_GUI_RESOLUTION), + new VROptionEntry(VRSettings.VrOptions.GUI_SCALE), + new VROptionEntry(VRSettings.VrOptions.HUD_MAX_GUI_SCALE), + new VROptionEntry(VRSettings.VrOptions.SHADER_GUI_RENDER), + new VROptionEntry("vivecraft.options.screen.keyboard.button", (button, mousePos) -> { + Minecraft.getInstance().setScreen(new GuiKeyboardSettings(this)); + return true; + }), new VROptionEntry("vivecraft.options.screen.menuworld.button", (button, mousePos) -> { Minecraft.getInstance().setScreen(new GuiMenuWorldSettings(this)); return true; }), - new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD_THEME), - new VROptionEntry(VRSettings.VrOptions.SHADER_GUI_RENDER) }; public GuiHUDSettings(Screen guiScreen) { @@ -53,12 +54,15 @@ protected void loadDefaults() { protected void actionPerformed(AbstractWidget widget) { if (widget instanceof GuiVROption button) { - if (button.getId() == VRSettings.VrOptions.PHYSICAL_KEYBOARD_THEME.ordinal()) { - KeyboardHandler.physicalKeyboard.init(); - } if (button.getId() == VRSettings.VrOptions.MENU_ALWAYS_FOLLOW_FACE.ordinal()) { GuiHandler.onScreenChanged(Minecraft.getInstance().screen, Minecraft.getInstance().screen, false); } + if ((button.getId() == VRSettings.VrOptions.DOUBLE_GUI_RESOLUTION.ordinal() + || button.getId() == VRSettings.VrOptions.GUI_SCALE.ordinal()) + && VRState.vrEnabled) { + this.dataholder.vrRenderer.resizeFrameBuffers("GUI Setting Changed"); + this.reinit = true; + } } } } diff --git a/common/src/main/java/org/vivecraft/client/gui/settings/GuiKeyboardSettings.java b/common/src/main/java/org/vivecraft/client/gui/settings/GuiKeyboardSettings.java new file mode 100644 index 000000000..1310dedf6 --- /dev/null +++ b/common/src/main/java/org/vivecraft/client/gui/settings/GuiKeyboardSettings.java @@ -0,0 +1,46 @@ +package org.vivecraft.client.gui.settings; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.screens.Screen; +import org.vivecraft.client.gui.framework.GuiVROption; +import org.vivecraft.client.gui.framework.GuiVROptionsBase; +import org.vivecraft.client.gui.framework.VROptionEntry; +import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; +import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; +import org.vivecraft.client_vr.settings.VRSettings; + +public class GuiKeyboardSettings extends GuiVROptionsBase { + private final VROptionEntry[] keyboardOptions = new VROptionEntry[]{ + new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD, (button, mousePos) -> { + KeyboardHandler.setOverlayShowing(false); + return false; + }), + new VROptionEntry(VRSettings.VrOptions.AUTO_OPEN_KEYBOARD), + new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD_SCALE), + new VROptionEntry(VRSettings.VrOptions.KEYBOARD_PRESS_BINDS), + new VROptionEntry(VRSettings.VrOptions.PHYSICAL_KEYBOARD_THEME) + }; + + public GuiKeyboardSettings(Screen guiScreen) { + super(guiScreen); + } + + public void init() { + this.vrTitle = "vivecraft.options.screen.keyboard"; + super.init(this.keyboardOptions, true); + super.addDefaultButtons(); + } + + protected void loadDefaults() { + super.loadDefaults(); + } + + protected void actionPerformed(AbstractWidget widget) { + if (widget instanceof GuiVROption button) { + if (button.getId() == VRSettings.VrOptions.PHYSICAL_KEYBOARD_THEME.ordinal()) { + KeyboardHandler.physicalKeyboard.init(); + } + } + } +} diff --git a/common/src/main/java/org/vivecraft/client/gui/widgets/TextScrollWidget.java b/common/src/main/java/org/vivecraft/client/gui/widgets/TextScrollWidget.java index b50e03fa6..fc60d4582 100644 --- a/common/src/main/java/org/vivecraft/client/gui/widgets/TextScrollWidget.java +++ b/common/src/main/java/org/vivecraft/client/gui/widgets/TextScrollWidget.java @@ -3,10 +3,12 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.AbstractWidget; +import net.minecraft.client.gui.components.ComponentRenderUtils; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.FormattedText; import net.minecraft.network.chat.Style; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.util.Mth; import org.lwjgl.glfw.GLFW; import java.util.List; @@ -23,12 +25,12 @@ public class TextScrollWidget extends AbstractWidget { private final int scrollBarWidth = 5; private final int padding = 5; - private final List formattedText; + private final List formattedChars; public TextScrollWidget(int x, int y, int width, int height, String text) { super(x, y, width, height, Component.literal("")); - formattedText = Minecraft.getInstance().font.getSplitter().splitLines(text, width - scrollBarWidth * 2, Style.EMPTY); + formattedChars = ComponentRenderUtils.wrapComponents(Component.literal(text), width - scrollBarWidth * 2, Minecraft.getInstance().font); initScroll(); } @@ -36,7 +38,7 @@ public TextScrollWidget(int x, int y, int width, int height, String text) { public TextScrollWidget(int x, int y, int width, int height, Component text) { super(x, y, width, height, Component.literal("")); - formattedText = Minecraft.getInstance().font.getSplitter().splitLines(text, width - scrollBarWidth * 2, Style.EMPTY); + formattedChars = ComponentRenderUtils.wrapComponents(text, width - scrollBarWidth * 2, Minecraft.getInstance().font); initScroll(); } @@ -44,14 +46,14 @@ private void initScroll() { maxLines = (height - 2 - padding + 3) / 12; currentLine = 0; - scrollSteps = formattedText.size() - maxLines; + scrollSteps = formattedChars.size() - maxLines; scrollSteps = Math.max(scrollSteps, 0); - scrollBarSize = scrollSteps == 0 ? height - 2 : (int) (Math.max(formattedText.size(), maxLines) / (float) (scrollSteps) * 12); + scrollBarSize = scrollSteps == 0 ? height - 2 : (int) (Math.max(formattedChars.size(), maxLines) / (float) (scrollSteps) * 12); scrollBarOffset = height - scrollBarSize - 2; } @Override - public void renderWidget(GuiGraphics guiGraphics, int i, int j, float f) { + public void renderWidget(GuiGraphics guiGraphics, int x, int y, float f) { // draw box outline guiGraphics.fill( getX(), @@ -68,8 +70,8 @@ public void renderWidget(GuiGraphics guiGraphics, int i, int j, float f) { -16777216); // draw text - for (int line = 0; line + currentLine < formattedText.size() && line < maxLines; line++) { - guiGraphics.drawString(Minecraft.getInstance().font, formattedText.get(line + currentLine).getString(), getX() + padding, getY() + padding + line * 12, 16777215); + for (int line = 0; line + currentLine < formattedChars.size() && line < maxLines; line++) { + guiGraphics.drawString(Minecraft.getInstance().font, formattedChars.get(line + currentLine), getX() + padding, getY() + padding + line * 12, 16777215); } float scrollbarStart = scrollSteps == 0 ? 0 : currentLine / (float) scrollSteps * scrollBarOffset; @@ -91,6 +93,8 @@ public void renderWidget(GuiGraphics guiGraphics, int i, int j, float f) { getX() + width - (isFocused() || isHovered ? 2 : 1), (int) (getY() + (isFocused() || isHovered ? 0 : 1) + scrollbarStart + scrollBarSize), -6250336); + + renderMouseover(guiGraphics, x, y); } @Override @@ -102,10 +106,15 @@ protected void updateWidgetNarration(NarrationElementOutput narrationElementOutp public void onClick(double x, double y) { if (x >= getX() + width - scrollBarWidth && x <= getX() + width && y >= getY() && y <= getY() + height) { scrollDragActive = true; - if (maxLines < formattedText.size()) { + if (maxLines < formattedChars.size()) { // update scroll position setCurrentLineFromYPos(y); } + } else if (this.clicked(x, y)) { + Style style = getMouseoverStyle(x, y); + if (style != null && style.getClickEvent() != null) { + Minecraft.getInstance().screen.handleComponentClicked(style); + } } } @@ -154,4 +163,28 @@ public boolean keyPressed(int key, int scancode, int mods) { } return super.keyPressed(key, scancode, mods); } + + public Style getMouseoverStyle(double x, double y) { + int lineIndex = this.getLineIndex(x, y); + if (lineIndex >= 0 && lineIndex < this.formattedChars.size()) { + FormattedCharSequence line = this.formattedChars.get(lineIndex); + return Minecraft.getInstance().font.getSplitter().componentStyleAtWidth(line, Mth.floor(x - this.getX())); + } + return null; + } + + private int getLineIndex(double x, double y) { + if (!this.clicked(x, y)) { + return -1; + } else { + return (int) ((y - this.getY() - padding * 0.5) / 12.0); + } + } + + public void renderMouseover(GuiGraphics guiGraphics, int x, int y) { + Style style = this.getMouseoverStyle(x, y); + if (style != null && style.getHoverEvent() != null) { + guiGraphics.renderComponentHoverEffect(Minecraft.getInstance().font, style, x, y); + } + } } diff --git a/common/src/main/java/org/vivecraft/client_vr/VRState.java b/common/src/main/java/org/vivecraft/client_vr/VRState.java index d66bf07ba..f1e95c035 100644 --- a/common/src/main/java/org/vivecraft/client_vr/VRState.java +++ b/common/src/main/java/org/vivecraft/client_vr/VRState.java @@ -36,7 +36,7 @@ public static void initializeVR() { dh.vr = new NullVR(Minecraft.getInstance(), dh); } if (!dh.vr.init()) { - throw new RenderConfigException("VR init Error", Component.translatable("vivecraft.messages.rendersetupfailed", dh.vr.initStatus + "\nVR provider: " + dh.vr.getName())); + throw new RenderConfigException("VR init Error", Component.translatable("vivecraft.messages.rendersetupfailed", dh.vr.initStatus, dh.vr.getName())); } dh.vrRenderer = dh.vr.createVRRenderer(); @@ -45,7 +45,7 @@ public static void initializeVR() { dh.vrRenderer.setupRenderConfiguration(); RenderPassManager.setVanillaRenderPass(); } catch (RenderConfigException renderConfigException) { - throw new RenderConfigException("VR Render Error", Component.translatable("vivecraft.messages.rendersetupfailed", renderConfigException.error.getString() + "\nVR provider: " + dh.vr.getName())); + throw new RenderConfigException("VR Render Error", Component.translatable("vivecraft.messages.rendersetupfailed", renderConfigException.error, dh.vr.getName())); } catch (Exception e) { e.printStackTrace(); } diff --git a/common/src/main/java/org/vivecraft/client_vr/extensions/WindowExtension.java b/common/src/main/java/org/vivecraft/client_vr/extensions/WindowExtension.java new file mode 100644 index 000000000..db19af986 --- /dev/null +++ b/common/src/main/java/org/vivecraft/client_vr/extensions/WindowExtension.java @@ -0,0 +1,7 @@ +package org.vivecraft.client_vr.extensions; + +public interface WindowExtension { + int vivecraft$getActualScreenHeight(); + + int vivecraft$getActualScreenWidth(); +} diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java index e1dd20112..4bce7ac77 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/VRPlayer.java @@ -302,88 +302,95 @@ public void tick(LocalPlayer player, Minecraft mc, RandomSource rand) { } public void doPlayerMoveInRoom(LocalPlayer player) { + ClientDataHolderVR dataholder = ClientDataHolderVR.getInstance(); + if (this.roomScaleMovementDelay > 0) { --this.roomScaleMovementDelay; - } else { + } else if (player != null + && !player.isShiftKeyDown() //jrbudda : prevent falling off things or walking up blocks while moving in room scale. + && !player.isSleeping() + && !dataholder.jumpTracker.isjumping() + && !dataholder.climbTracker.isGrabbingLadder() + && player.isAlive()) { + Minecraft minecraft = Minecraft.getInstance(); - ClientDataHolderVR dataholder = ClientDataHolderVR.getInstance(); - - if (player != null) { - if (!player.isShiftKeyDown()) { - if (!player.isSleeping()) { - if (!dataholder.jumpTracker.isjumping()) { - if (!dataholder.climbTracker.isGrabbingLadder()) { - if (player.isAlive()) { - VRData vrdata = new VRData(this.roomOrigin, dataholder.vrSettings.walkMultiplier, this.worldScale, this.vrdata_world_pre.rotation_radians); - - if (dataholder.vehicleTracker.canRoomscaleDismount(minecraft.player)) { - Vec3 vec35 = minecraft.player.getVehicle().position(); - Vec3 vec36 = vrdata.getHeadPivot(); - double d6 = Math.sqrt((vec36.x - vec35.x) * (vec36.x - vec35.x) + (vec36.z - vec35.z) * (vec36.z - vec35.z)); - - if (d6 > 1.0D) { - dataholder.sneakTracker.sneakCounter = 5; - } - } else { - float f = player.getBbWidth() / 2.0F; - float f1 = player.getBbHeight(); - Vec3 vec3 = vrdata.getHeadPivot(); - double d0 = vec3.x; - double d1 = player.getY(); - double d2 = vec3.z; - AABB aabb = new AABB(d0 - (double) f, d1, d2 - (double) f, d0 + (double) f, d1 + (double) f1, d2 + (double) f); - Vec3 vec31 = null; - float f2 = 0.0625F; - boolean flag = minecraft.level.noCollision(player, aabb); - - if (flag) { - player.setPosRaw(d0, !dataholder.vrSettings.simulateFalling ? d1 : player.getY(), d2); - player.setBoundingBox(new AABB(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.minY + (double) f1, aabb.maxZ)); - player.fallDistance = 0.0F; - this.getEstimatedTorsoPosition(d0, d1, d2); - } else if ((dataholder.vrSettings.walkUpBlocks && ((PlayerExtension) player).vivecraft$getMuhJumpFactor() == 1.0F || dataholder.climbTracker.isGrabbingLadder() && dataholder.vrSettings.realisticClimbEnabled) && player.fallDistance == 0.0F) { - if (vec31 == null) { - vec31 = this.getEstimatedTorsoPosition(d0, d1, d2); - } - - float f3 = player.getDimensions(player.getPose()).width * 0.45F; - double d3 = f - f3; - AABB aabb1 = new AABB(vec31.x - d3, aabb.minY, vec31.z - d3, vec31.x + d3, aabb.maxY, vec31.z + d3); - boolean flag1 = !minecraft.level.noCollision(player, aabb1); - - if (flag1) { - double d4 = vec31.x - d0; - double d5 = vec31.z - d2; - aabb = aabb.move(d4, 0.0D, d5); - int i = 0; - - if (player.onClimbable() && dataholder.vrSettings.realisticClimbEnabled) { - i = 6; - } - - for (int j = 0; j <= 10 + i; ++j) { - aabb = aabb.move(0.0D, 0.1D, 0.0D); - flag = minecraft.level.noCollision(player, aabb); - - if (flag) { - d0 = d0 + d4; - d2 = d2 + d5; - d1 = d1 + (double) (0.1F * (float) j); - player.setPosRaw(d0, d1, d2); - player.setBoundingBox(new AABB(aabb.minX, aabb.minY, aabb.minZ, aabb.maxX, aabb.maxY, aabb.maxZ)); - Vec3 vec32 = this.roomOrigin.add(d4, 0.1F * (float) j, d5); - this.setRoomOrigin(vec32.x, vec32.y, vec32.z, false); - Vec3 vec33 = player.getLookAngle(); - Vec3 vec34 = (new Vec3(vec33.x, 0.0D, vec33.z)).normalize(); - player.fallDistance = 0.0F; - ((PlayerExtension) minecraft.player).vivecraft$stepSound(BlockPos.containing(player.position()), player.position()); - break; - } - } - } - } - } - } + + VRData tempVrdata = new VRData(this.roomOrigin, dataholder.vrSettings.walkMultiplier, this.worldScale, this.vrdata_world_pre.rotation_radians); + + if (dataholder.vehicleTracker.canRoomscaleDismount(minecraft.player)) { + Vec3 mountpos = minecraft.player.getVehicle().position(); + Vec3 head = tempVrdata.getHeadPivot(); + double distance = Math.sqrt((head.x - mountpos.x) * (head.x - mountpos.x) + (head.z - mountpos.z) * (head.z - mountpos.z)); + + if (distance > 1.0D) { + dataholder.sneakTracker.sneakCounter = 5; + } + } else { + // move player's X/Z coords as the HMD moves around the room + float playerHalfWidth = player.getBbWidth() / 2.0F; + float playerHeight = player.getBbHeight(); + Vec3 eyePos = tempVrdata.getHeadPivot(); + + double x = eyePos.x; + double y = player.getY(); + double z = eyePos.z; + + // create bounding box at dest position + AABB bb = new AABB( + x - playerHalfWidth, + y, + z - playerHalfWidth, + x + playerHalfWidth, + y + playerHeight, + z + playerHalfWidth); + + Vec3 torso = new Vec3(x, y, z); + + if (minecraft.level.noCollision(player, bb)) { + // no collision + // don't call setPosition style functions to avoid shifting room origin + player.setPosRaw(x, !dataholder.vrSettings.simulateFalling ? y : player.getY(), z); + player.setBoundingBox(bb); + player.fallDistance = 0.0F; + } else if (( + //collision, test for climbing up a block + (dataholder.vrSettings.walkUpBlocks && ((PlayerExtension) player).vivecraft$getMuhJumpFactor() == 1.0F) + || (dataholder.climbTracker.isGrabbingLadder() && dataholder.vrSettings.realisticClimbEnabled)) && player.fallDistance == 0.0F) { + + // is the player significantly inside a block? + float climbShrink = player.getDimensions(player.getPose()).width * 0.45F; + double shrunkClimbHalfWidth = playerHalfWidth - climbShrink; + + AABB bbClimb = new AABB( + torso.x - shrunkClimbHalfWidth, + bb.minY, + torso.z - shrunkClimbHalfWidth, + torso.x + shrunkClimbHalfWidth, + bb.maxY, + torso.z + shrunkClimbHalfWidth); + + // colliding with a block + if (!minecraft.level.noCollision(player, bbClimb)) { + int extra = 0; + + if (player.onClimbable() && dataholder.vrSettings.realisticClimbEnabled) { + extra = 6; + } + + for (int i = 0; i <= 10 + extra; ++i) { + bb = bb.move(0.0D, 0.1D, 0.0D); + + if (minecraft.level.noCollision(player, bb)) { + // free spot, move player there + player.setPosRaw(x, bb.minY, z); + player.setBoundingBox(bb); + + Vec3 dest = this.roomOrigin.add(0.0, 0.1F * (i + 1), 0.0); + this.setRoomOrigin(dest.x, dest.y, dest.z, false); + + player.fallDistance = 0.0F; + ((PlayerExtension) minecraft.player).vivecraft$stepSound(BlockPos.containing(player.position()), player.position()); + break; } } } @@ -418,7 +425,8 @@ public void updateFreeMove() { this.isFreeMoveCurrent = false; } - if (this.mc.player.input.forwardImpulse != 0.0F || this.mc.player.input.leftImpulse != 0.0F) { + // during login input can be null, and can cause a weird async crash, if not checked + if (this.mc.player.input != null && (this.mc.player.input.forwardImpulse != 0.0F || this.mc.player.input.leftImpulse != 0.0F)) { this.isFreeMoveCurrent = true; } diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/GuiHandler.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/GuiHandler.java index 850ad125d..7cf0cea4b 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/GuiHandler.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/GuiHandler.java @@ -10,6 +10,8 @@ import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractSignEditScreen; import net.minecraft.client.gui.screens.inventory.BookEditScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; import net.minecraft.world.entity.vehicle.ContainerEntity; import net.minecraft.world.phys.*; import org.joml.Vector2f; @@ -18,6 +20,7 @@ import org.vivecraft.client_vr.VRData; import org.vivecraft.client_vr.VRState; import org.vivecraft.client_vr.extensions.GameRendererExtension; +import org.vivecraft.client_vr.extensions.WindowExtension; import org.vivecraft.client_vr.gameplay.VRPlayer; import org.vivecraft.client_vr.provider.ControllerType; import org.vivecraft.client_vr.provider.HandedKeyBinding; @@ -83,36 +86,73 @@ public boolean isPriorityOnController(ControllerType type) { public static RenderTarget guiFramebuffer = null; public static int guiWidth = 1280; public static int guiHeight = 720; + public static int guiScaleFactorMax; public static int guiScaleFactor = calculateScale(0, false, guiWidth, guiHeight); public static int scaledWidth; public static int scaledHeight; + public static int scaledWidthMax; + public static int scaledHeightMax; public static int calculateScale(int scaleIn, boolean forceUnicode, int framebufferWidth, int framebufferHeight) { - int j = 1; - - while (j != scaleIn && - j < framebufferWidth && - j < framebufferHeight && - framebufferWidth / (j + 1) >= 320 && - framebufferHeight / (j + 1) >= 240) { - ++j; + int scale = 1; + int maxScale = 1; + + while (maxScale < framebufferWidth && + maxScale < framebufferHeight && + framebufferWidth / (maxScale + 1) >= 320 && + framebufferHeight / (maxScale + 1) >= 240) { + if (scale < scaleIn || scaleIn == 0) { + scale++; + } + maxScale++; } - if (forceUnicode && j % 2 != 0) { - ++j; + if (forceUnicode) { + if (scale % 2 != 0) { + scale++; + } + if (maxScale % 2 != 0) { + maxScale++; + } } - int widthFloor = framebufferWidth / j; - scaledWidth = framebufferWidth / j > widthFloor ? widthFloor + 1 : widthFloor; + guiScaleFactorMax = maxScale; + + scaledWidth = Mth.ceil(framebufferWidth / (float) scale); + scaledWidthMax = Mth.ceil(framebufferWidth / (float) maxScale); - int heightFloor = framebufferHeight / j; - scaledHeight = framebufferHeight / j > heightFloor ? heightFloor + 1 : heightFloor; + scaledHeight = Mth.ceil(framebufferHeight / (float) scale); + scaledHeightMax = Mth.ceil(framebufferHeight / (float) maxScale); - return j; + return scale; + } + + public static boolean updateResolution() { + int oldWidth = guiWidth; + int oldHeight = guiHeight; + int oldGuiScale = guiScaleFactor; + guiWidth = dh.vrSettings.doubleGUIResolution ? 2560 : 1280; + guiHeight = dh.vrSettings.doubleGUIResolution ? 1440 : 720; + guiScaleFactor = calculateScale( + dh.vrSettings.doubleGUIResolution ? dh.vrSettings.guiScale : (int) Math.ceil(dh.vrSettings.guiScale * 0.5f), + false, guiWidth, guiHeight); + if (oldWidth != guiWidth) { + // move cursor to right position + InputSimulator.setMousePos( + mc.mouseHandler.xpos() * ((WindowExtension) (Object) mc.getWindow()).vivecraft$getActualScreenWidth() / oldWidth, + mc.mouseHandler.ypos() * ((WindowExtension) (Object) mc.getWindow()).vivecraft$getActualScreenHeight() / oldHeight); + controllerMouseX *= (double) guiWidth / oldWidth; + controllerMouseY *= (double) guiHeight / oldHeight; + return true; + } else if (oldGuiScale != guiScaleFactor) { + return true; + } else { + return false; + } } public static void processGui() { - if (mc.screen != null) { + if (mc.screen != null || !mc.mouseHandler.isMouseGrabbed()) { if (!dh.vrSettings.seated) { if (guiRotation_room != null) { if (MCVR.get().isControllerTracking(0)) { @@ -142,7 +182,9 @@ public static void processGui() { int j = 0; if (MCVR.get().isControllerTracking(ControllerType.RIGHT)) { - InputSimulator.setMousePos(d1, d0); + InputSimulator.setMousePos( + d1 * (((WindowExtension) (Object) mc.getWindow()).vivecraft$getActualScreenWidth() / (double) mc.getWindow().getScreenWidth()), + d0 * (((WindowExtension) (Object) mc.getWindow()).vivecraft$getActualScreenHeight() / (double) mc.getWindow().getScreenHeight())); controllerMouseValid = true; } } else { @@ -272,6 +314,10 @@ public static void processBindingsGui() { } public static void onScreenChanged(Screen previousGuiScreen, Screen newScreen, boolean unpressKeys) { + onScreenChanged(previousGuiScreen, newScreen, unpressKeys, false); + } + + public static void onScreenChanged(Screen previousGuiScreen, Screen newScreen, boolean unpressKeys, boolean infrontOfHand) { if (!VRState.vrRunning) { return; } @@ -330,6 +376,8 @@ public static void onScreenChanged(Screen previousGuiScreen, Screen newScreen, b && mc.hitResult instanceof EntityHitResult && ((EntityHitResult) mc.hitResult).getEntity() instanceof ContainerEntity; + VRData.VRDevicePose facingDevice = infrontOfHand ? dh.vrPlayer.vrdata_room_pre.getController(0) : dh.vrPlayer.vrdata_room_pre.hmd; + if (guiAppearOverBlockActive && (isBlockScreen || isEntityScreen) && dh.vrSettings.guiAppearOverBlock) { Vec3 sourcePos; if (isEntityScreen) { @@ -355,8 +403,8 @@ public static void onScreenChanged(Screen previousGuiScreen, Screen newScreen, b vec3 = new Vec3(0.0D, 0.25D, -2.0D); } - Vec3 hmdPos = dh.vrPlayer.vrdata_room_pre.hmd.getPosition(); - Vec3 vec32 = dh.vrPlayer.vrdata_room_pre.hmd.getCustomVector(vec3); + Vec3 hmdPos = facingDevice.getPosition(); + Vec3 vec32 = facingDevice.getCustomVector(vec3); guiPos_room = new Vec3(vec32.x / 2.0D + hmdPos.x, vec32.y / 2.0D + hmdPos.y, vec32.z / 2.0D + hmdPos.z); if (dh.vrSettings.physicalKeyboard && KeyboardHandler.Showing && guiPos_room.y < hmdPos.y + 0.2D) { @@ -365,7 +413,7 @@ public static void onScreenChanged(Screen previousGuiScreen, Screen newScreen, b } // orient screen - Vec3 hmdPos = dh.vrPlayer.vrdata_room_pre.hmd.getPosition(); + Vec3 hmdPos = facingDevice.getPosition(); Vector3 look = new Vector3(); look.setX((float) (guiPos_room.x - hmdPos.x)); look.setY((float) (guiPos_room.y - hmdPos.y)); @@ -388,6 +436,12 @@ public static Vec3 applyGUIModelView(RenderPass currentPass, PoseStack pMatrixSt if (mc.screen != null && guiPos_room == null) { //naughty mods! onScreenChanged(null, mc.screen, false); + } else if (mc.screen == null && !mc.mouseHandler.isMouseGrabbed()) { + // some mod want's to do a mouse selection overlay + if (guiPos_room == null) { + onScreenChanged(null, new Screen(Component.empty()) { + }, false, true); + } } else if (mc.screen == null && guiPos_room != null) { //even naughtier mods! // someone canceled the setScreen, so guiPos didn't get reset diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/KeyboardHandler.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/KeyboardHandler.java index 4e7ef72a7..5e711c149 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/KeyboardHandler.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/screenhandlers/KeyboardHandler.java @@ -56,6 +56,9 @@ public static boolean setOverlayShowing(boolean showingState) { } } else { Showing = false; + if (dh.vrSettings.physicalKeyboard) { + physicalKeyboard.unpressAllKeys(); + } } return Showing; diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java index 54ab77573..9a57ee724 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/TelescopeTracker.java @@ -87,7 +87,7 @@ public static float viewPercent(int controller) { } private static float viewPercent(int controller, int e) { - if (e == -1) { + if (e == -1 || ClientDataHolderVR.getInstance().vrPlayer == null) { return 0.0F; } else { VRData.VRDevicePose eye = ClientDataHolderVR.getInstance().vrPlayer.vrdata_room_pre.getEye(RenderPass.values()[e]); diff --git a/common/src/main/java/org/vivecraft/client_vr/gui/GuiKeyboard.java b/common/src/main/java/org/vivecraft/client_vr/gui/GuiKeyboard.java index 197a2a2a4..dd5a0d69b 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gui/GuiKeyboard.java +++ b/common/src/main/java/org/vivecraft/client_vr/gui/GuiKeyboard.java @@ -5,10 +5,12 @@ import net.minecraft.network.chat.Component; import org.lwjgl.glfw.GLFW; import org.vivecraft.client.gui.framework.TwoHandedScreen; +import org.vivecraft.client.utils.Utils; import org.vivecraft.client_vr.provider.InputSimulator; public class GuiKeyboard extends TwoHandedScreen { private boolean isShift = false; + private long airTypingWarningTime; public void init() { String s = this.dataholder.vrSettings.keyboardKeys; @@ -42,8 +44,11 @@ public void init() { } String s2 = String.valueOf(c0); + final int code = l1 < this.dataholder.vrSettings.keyboardCodes.length ? this.dataholder.vrSettings.keyboardCodes[l1] : GLFW.GLFW_KEY_UNKNOWN; Button button = new Button.Builder(Component.literal(s2), (p) -> { + InputSimulator.pressKeyForBind(code); + InputSimulator.releaseKeyForBind(code); InputSimulator.typeChars(s2); }) .size(i1, 20) @@ -62,6 +67,8 @@ public void init() { .build()); this.addRenderableWidget(new Button.Builder(Component.literal(" "), (p) -> { + InputSimulator.pressKeyForBind(GLFW.GLFW_KEY_SPACE); + InputSimulator.releaseKeyForBind(GLFW.GLFW_KEY_SPACE); InputSimulator.typeChars(" "); }) .size(5 * (i1 + l), 20) diff --git a/common/src/main/java/org/vivecraft/client_vr/gui/PhysicalKeyboard.java b/common/src/main/java/org/vivecraft/client_vr/gui/PhysicalKeyboard.java index f9deb9e4d..6821b2026 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gui/PhysicalKeyboard.java +++ b/common/src/main/java/org/vivecraft/client_vr/gui/PhysicalKeyboard.java @@ -12,6 +12,7 @@ import net.minecraft.client.renderer.GameRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; @@ -90,6 +91,7 @@ public PhysicalKeyboard() { } public void init() { + this.unpressAllKeys(); this.keys.clear(); this.rows = ROWS; this.columns = COLUMNS; @@ -118,9 +120,11 @@ public void init() { } final char c1 = c0; + final int code = k < this.dh.vrSettings.keyboardCodes.length ? this.dh.vrSettings.keyboardCodes[k] : GLFW.GLFW_KEY_UNKNOWN; this.addKey(new KeyButton(k, String.valueOf(c0), this.keyWidthSpecial + this.spacing + (float) j * (this.keyWidth + this.spacing), (float) i * (this.keyHeight + this.spacing), this.keyWidth, this.keyHeight) { @Override public void onPressed() { + InputSimulator.pressKeyForBind(code); InputSimulator.typeChar(c1); if (!PhysicalKeyboard.this.shiftSticky) { @@ -132,6 +136,11 @@ public void onPressed() { InputSimulator.releaseKey(GLFW.GLFW_KEY_SLASH); } } + + @Override + public void onReleased() { + InputSimulator.releaseKeyForBind(code); + } }); } } @@ -169,13 +178,23 @@ public RGBAColor getRenderColor() { this.addKey(new KeyButton(1002, " ", this.keyWidthSpecial + this.spacing + (float) (this.columns - 5) / 2.0F * (this.keyWidth + this.spacing), (float) this.rows * (this.keyHeight + this.spacing), 5.0F * (this.keyWidth + this.spacing) - this.spacing, this.keyHeight) { @Override public void onPressed() { + InputSimulator.pressKeyForBind(GLFW.GLFW_KEY_SPACE); InputSimulator.typeChar(' '); } + + @Override + public void onReleased() { + InputSimulator.releaseKeyForBind(GLFW.GLFW_KEY_SPACE); + } }); this.addKey(new KeyButton(1003, "Tab", 0.0F, this.keyHeight + this.spacing, this.keyWidthSpecial, this.keyHeight) { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_TAB); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_TAB); } }); @@ -183,6 +202,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_ESCAPE); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_ESCAPE); } }); @@ -190,6 +213,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_BACKSPACE); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_BACKSPACE); } }); @@ -197,6 +224,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_ENTER); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_ENTER); } }); @@ -204,6 +235,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_UP); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_UP); } }); @@ -211,6 +246,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_DOWN); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_DOWN); } }); @@ -218,6 +257,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_LEFT); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_LEFT); } }); @@ -225,6 +268,10 @@ public void onPressed() { @Override public void onPressed() { InputSimulator.pressKey(GLFW.GLFW_KEY_RIGHT); + } + + @Override + public void onReleased() { InputSimulator.releaseKey(GLFW.GLFW_KEY_RIGHT); } }); @@ -332,7 +379,7 @@ public void process() { if (physicalkeyboard$keybutton != null) { if (physicalkeyboard$keybutton != this.pressedKey[i] && Utils.milliTime() - this.pressTime[i] >= 150L) { if (this.pressedKey[i] != null) { - this.pressedKey[i].unpress(controllertype); + this.pressedKey[i].unpress(); this.pressedKey[i] = null; } @@ -345,7 +392,7 @@ public void process() { this.pressRepeatTime[i] = Utils.milliTime(); } } else if (this.pressedKey[i] != null) { - this.pressedKey[i].unpress(controllertype); + this.pressedKey[i].unpress(); this.pressedKey[i] = null; this.pressTime[i] = Utils.milliTime(); } @@ -535,6 +582,12 @@ public void show() { this.reinit = true; } + public void unpressAllKeys() { + for (KeyButton key : this.keys) { + if(key.pressed) key.unpress(); + } + } + private KeyButton addKey(KeyButton key) { this.keys.add(key); return key; @@ -609,11 +662,13 @@ public final void press(ControllerType controller, boolean isRepeat) { PhysicalKeyboard.this.updateEasterEgg(this.label); } - public final void unpress(ControllerType controller) { + public final void unpress() { this.pressed = false; + this.onReleased(); } public abstract void onPressed(); + public void onReleased() {} } public enum KeyboardTheme implements OptionEnum { diff --git a/common/src/main/java/org/vivecraft/client_vr/provider/InputSimulator.java b/common/src/main/java/org/vivecraft/client_vr/provider/InputSimulator.java index 0266326fb..6417714eb 100644 --- a/common/src/main/java/org/vivecraft/client_vr/provider/InputSimulator.java +++ b/common/src/main/java/org/vivecraft/client_vr/provider/InputSimulator.java @@ -1,10 +1,15 @@ package org.vivecraft.client_vr.provider; import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import org.lwjgl.glfw.GLFW; import java.util.HashSet; import java.util.Set; +import org.vivecraft.client.utils.Utils; +import org.vivecraft.client_vr.ClientDataHolderVR; + public class InputSimulator { private static final Set pressedKeys = new HashSet<>(); @@ -70,4 +75,28 @@ public static void typeChars(CharSequence characters) { typeChar(c0); } } + + private static long airTypingWarningTime; + public static void pressKeyForBind(int code) { + Minecraft minecraft = Minecraft.getInstance(); + ClientDataHolderVR dataHolder = ClientDataHolderVR.getInstance(); + + if (dataHolder.vrSettings.keyboardPressBinds) { + if (code != GLFW.GLFW_KEY_UNKNOWN) { + pressKey(code); + } + } else if (minecraft.screen == null && Utils.milliTime() - airTypingWarningTime >= 30000) { + minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.airtypingwarning")); + airTypingWarningTime = Utils.milliTime(); + } + } + + + public static void releaseKeyForBind(int code) { + ClientDataHolderVR dataHolder = ClientDataHolderVR.getInstance(); + + if (dataHolder.vrSettings.keyboardPressBinds && code != GLFW.GLFW_KEY_UNKNOWN) { + releaseKey(code); + } + } } diff --git a/common/src/main/java/org/vivecraft/client_vr/provider/MCVR.java b/common/src/main/java/org/vivecraft/client_vr/provider/MCVR.java index fd60ff11a..39eb530dd 100644 --- a/common/src/main/java/org/vivecraft/client_vr/provider/MCVR.java +++ b/common/src/main/java/org/vivecraft/client_vr/provider/MCVR.java @@ -21,6 +21,7 @@ import org.vivecraft.client_vr.VRData; import org.vivecraft.client_vr.Vec3History; import org.vivecraft.client_vr.extensions.GuiExtension; +import org.vivecraft.client_vr.extensions.WindowExtension; import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; import org.vivecraft.client_vr.gameplay.screenhandlers.RadialHandler; @@ -358,7 +359,7 @@ protected void processHotbar() { Vec3 main = this.getAimSource(0); Vec3 off = this.getAimSource(1); - Vec3 barStartos = null, barEndos = null; + Vec3 barStartPos = null, barEndPos = null; int i = 1; if (this.dh.vrSettings.reverseHands) { @@ -366,18 +367,28 @@ protected void processHotbar() { } if (this.dh.vrSettings.vrHudLockMode == VRSettings.HUDLock.WRIST) { - barStartos = this.getAimRotation(1).transform(new Vector3((float) i * 0.02F, 0.05F, 0.26F)).toVector3d(); - barEndos = this.getAimRotation(1).transform(new Vector3((float) i * 0.02F, 0.05F, 0.01F)).toVector3d(); + barStartPos = this.getAimRotation(1).transform(new Vector3((float) i * 0.02F, 0.05F, 0.26F)).toVector3d(); + barEndPos = this.getAimRotation(1).transform(new Vector3((float) i * 0.02F, 0.05F, 0.01F)).toVector3d(); } else if (this.dh.vrSettings.vrHudLockMode == VRSettings.HUDLock.HAND) { - barStartos = this.getAimRotation(1).transform(new Vector3((float) i * -0.18F, 0.08F, -0.01F)).toVector3d(); - barEndos = this.getAimRotation(1).transform(new Vector3((float) i * 0.19F, 0.04F, -0.08F)).toVector3d(); + barStartPos = this.getAimRotation(1).transform(new Vector3((float) i * -0.18F, 0.08F, -0.01F)).toVector3d(); + barEndPos = this.getAimRotation(1).transform(new Vector3((float) i * 0.19F, 0.04F, -0.08F)).toVector3d(); } else { return; //how did u get here } + float guiScaleFactor = (float) this.mc.getWindow().getGuiScale() / GuiHandler.guiScaleFactorMax; + + Vec3 barMidPos = barStartPos.add(barEndPos).scale(0.5); + + Vec3 barStart = off.add( + Mth.lerp(guiScaleFactor, barMidPos.x, barStartPos.x), + Mth.lerp(guiScaleFactor, barMidPos.y, barStartPos.y), + Mth.lerp(guiScaleFactor, barMidPos.z, barStartPos.z)); + Vec3 barEnd = off.add( + Mth.lerp(guiScaleFactor, barMidPos.x, barEndPos.x), + Mth.lerp(guiScaleFactor, barMidPos.y, barEndPos.y), + Mth.lerp(guiScaleFactor, barMidPos.z, barEndPos.z)); - Vec3 barStart = off.add(barStartos.x, barStartos.y, barStartos.z); - Vec3 barEnd = off.add(barEndos.x, barEndos.y, barEndos.z); Vec3 u = barStart.subtract(barEnd); Vec3 pq = barStart.subtract(main); @@ -566,7 +577,7 @@ protected void updateAim() { this.controllerRotation[0].M[3][3] = 1.0F; Vec3 vec31 = this.getHmdVector(); - if (this.dh.vrSettings.seated && this.mc.screen == null) { + if (this.dh.vrSettings.seated && this.mc.screen == null && this.mc.mouseHandler.isMouseGrabbed()) { Matrix4f matrix4f = new Matrix4f(); float f = 110.0F; float f1 = 180.0F; @@ -605,8 +616,10 @@ protected void updateAim() { double d4 = 0.5D * (double) this.dh.vrSettings.ySensitivity; d2 = (double) this.aimPitch + d1 * d4; d2 = Mth.clamp(d2, -89.9D, 89.9D); - InputSimulator.setMousePos(d3, i / 2); - GLFW.glfwSetCursorPos(this.mc.getWindow().getWindow(), d3, i / 2); + double screenX = d3 * (((WindowExtension) (Object) this.mc.getWindow()).vivecraft$getActualScreenWidth() / (double) this.mc.getWindow().getScreenWidth()); + double screenY = (i * 0.5F) * (((WindowExtension) (Object) this.mc.getWindow()).vivecraft$getActualScreenHeight() / (double) this.mc.getWindow().getScreenHeight()); + InputSimulator.setMousePos(screenX, screenY); + GLFW.glfwSetCursorPos(this.mc.getWindow().getWindow(), screenX, screenY); matrix4f.rotate((float) Math.toRadians(-d2), new Vector3f(1.0F, 0.0F, 0.0F)); matrix4f.rotate((float) Math.toRadians(-180.0D + d0 - (double) this.hmdForwardYaw), new Vector3f(0.0F, 1.0F, 0.0F)); } diff --git a/common/src/main/java/org/vivecraft/client_vr/provider/VRRenderer.java b/common/src/main/java/org/vivecraft/client_vr/provider/VRRenderer.java index f407b2f17..14d8aa248 100644 --- a/common/src/main/java/org/vivecraft/client_vr/provider/VRRenderer.java +++ b/common/src/main/java/org/vivecraft/client_vr/provider/VRRenderer.java @@ -6,10 +6,15 @@ import com.mojang.blaze3d.shaders.ProgramManager; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; +import net.minecraft.ChatFormatting; +import net.minecraft.Util; import net.minecraft.client.GraphicsStatus; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Tuple; @@ -23,6 +28,7 @@ import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.VRTextureTarget; import org.vivecraft.client_vr.extensions.GameRendererExtension; +import org.vivecraft.client_vr.extensions.WindowExtension; import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; import org.vivecraft.client_vr.gameplay.screenhandlers.RadialHandler; @@ -35,6 +41,8 @@ import org.vivecraft.client_xr.render_pass.WorldRenderPass; import org.vivecraft.mod_compat_vr.ShadersHelper; import org.vivecraft.mod_compat_vr.resolutioncontrol.ResolutionControlHelper; +import oshi.SystemInfo; +import oshi.hardware.GraphicsCard; import java.nio.FloatBuffer; import java.util.ArrayList; @@ -319,7 +327,8 @@ public List getRenderPasses() { list.add(RenderPass.RIGHT); // only do these, if the window is not minimized - if (minecraft.getWindow().getScreenWidth() > 0 && minecraft.getWindow().getScreenHeight() > 0) { + if (((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth() > 0 + && ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight() > 0) { if (dataholder.vrSettings.displayMirrorMode == VRSettings.MirrorMode.FIRST_PERSON) { list.add(RenderPass.CENTER); } else if (dataholder.vrSettings.displayMirrorMode == VRSettings.MirrorMode.MIXED_REALITY) { @@ -353,8 +362,8 @@ public List getRenderPasses() { public abstract Tuple getRenderTextureSizes(); public Tuple getMirrorTextureSize(int eyeFBWidth, int eyeFBHeight, float resolutionScale) { - mirrorFBWidth = (int) Math.ceil(Minecraft.getInstance().getWindow().getScreenWidth() * resolutionScale); - mirrorFBHeight = (int) Math.ceil(Minecraft.getInstance().getWindow().getScreenHeight() * resolutionScale); + mirrorFBWidth = (int) Math.ceil(((WindowExtension) (Object) Minecraft.getInstance().getWindow()).vivecraft$getActualScreenWidth() * resolutionScale); + mirrorFBHeight = (int) Math.ceil(((WindowExtension) (Object) Minecraft.getInstance().getWindow()).vivecraft$getActualScreenHeight() * resolutionScale); if (ClientDataHolderVR.getInstance().vrSettings.displayMirrorMode == VRSettings.MirrorMode.MIXED_REALITY) { mirrorFBWidth = mirrorFBWidth / 2; @@ -489,11 +498,13 @@ public void setupRenderConfiguration() throws Exception { } // mirror - if (WorldRenderPass.center != null) { - WorldRenderPass.center.resize(mirrorSize.getA(), mirrorSize.getB()); - } - if (WorldRenderPass.mixedReality != null) { - WorldRenderPass.mixedReality.resize(mirrorSize.getA(), mirrorSize.getB()); + if (mirrorSize.getA() > 0 && mirrorSize.getB() > 0) { + if (WorldRenderPass.center != null) { + WorldRenderPass.center.resize(mirrorSize.getA(), mirrorSize.getB()); + } + if (WorldRenderPass.mixedReality != null) { + WorldRenderPass.mixedReality.resize(mirrorSize.getA(), mirrorSize.getB()); + } } // telescopes @@ -507,15 +518,45 @@ public void setupRenderConfiguration() throws Exception { } else { WorldRenderPass.camera.resize(cameraSize.getA(), cameraSize.getB()); } + + // resize gui, if changed + if (GuiHandler.updateResolution()) { + GuiHandler.guiFramebuffer.resize(GuiHandler.guiWidth, GuiHandler.guiHeight, Minecraft.ON_OSX); + if (minecraft.screen != null) { + int l2 = minecraft.getWindow().getGuiScaledWidth(); + int j3 = minecraft.getWindow().getGuiScaledHeight(); + minecraft.screen.init(minecraft, l2, j3); + } + } } if (this.reinitFramebuffers) { this.reinitShadersFlag = true; this.checkGLError("Start Init"); - if (GlUtil.getRenderer().toLowerCase().contains("intel")) //Optifine - { - throw new RenderConfigException("Incompatible", Component.translatable("vivecraft.messages.intelgraphics", GlUtil.getRenderer())); + if (Util.getPlatform() == Util.OS.WINDOWS && GlUtil.getRenderer().toLowerCase().contains("intel")) { + StringBuilder gpus = new StringBuilder(); + boolean onlyIntel = true; + for (GraphicsCard gpu : (new SystemInfo()).getHardware().getGraphicsCards()) { + gpus.append("\n"); + if (gpu.getVendor().toLowerCase().contains("intel") || gpu.getName().toLowerCase().contains("intel")) { + gpus.append("§c❌§r "); + } else { + onlyIntel = false; + gpus.append("§a✔§r "); + } + gpus.append(gpu.getVendor()).append(": ").append(gpu.getName()); + } + throw new RenderConfigException("Incompatible", Component.translatable( + "vivecraft.messages.intelgraphics1", + Component.literal(GlUtil.getRenderer()).withStyle(ChatFormatting.GOLD), + gpus.toString(), + onlyIntel ? Component.empty() + : Component.translatable("vivecraft.messages.intelgraphics2", Component.literal("https://www.vivecraft.org/faq/#gpu") + .withStyle(style -> style.withUnderlined(true) + .withColor(ChatFormatting.GREEN) + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, CommonComponents.GUI_OPEN_IN_BROWSER)) + .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://www.vivecraft.org/faq/#gpu")))))); } if (!this.isInitialized()) { @@ -589,6 +630,7 @@ public void setupRenderConfiguration() throws Exception { } } + GuiHandler.updateResolution(); GuiHandler.guiFramebuffer = new VRTextureTarget("GUI", GuiHandler.guiWidth, GuiHandler.guiHeight, true, false, -1, false, true, false); dataholder.print(GuiHandler.guiFramebuffer.toString()); this.checkGLError("GUI framebuffer setup"); @@ -677,7 +719,7 @@ public void setupRenderConfiguration() throws Exception { minecraft.screen.init(minecraft, l2, j3); } - long windowPixels = (long) minecraft.getWindow().getScreenWidth() * minecraft.getWindow().getScreenHeight(); + long windowPixels = (long) ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth() * ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight(); long vrPixels = eyeFBWidth * eyeFBHeight * 2L; if (list.contains(RenderPass.CENTER)) { @@ -691,7 +733,7 @@ public void setupRenderConfiguration() throws Exception { System.out.println("[Minecrift] New render config:" + "\nOpenVR target width: " + eyew + ", height: " + eyeh + " [" + String.format("%.1f", (float) (eyew * eyeh) / 1000000.0F) + " MP]" + "\nRender target width: " + eyeFBWidth + ", height: " + eyeFBHeight + " [Render scale: " + Math.round(dataholder.vrSettings.renderScaleFactor * 100.0F) + "%, " + String.format("%.1f", (float) (eyeFBWidth * eyeFBHeight) / 1000000.0F) + " MP]" + - "\nMain window width: " + minecraft.getWindow().getScreenWidth() + ", height: " + minecraft.getWindow().getScreenHeight() + " [" + String.format("%.1f", (float) windowPixels / 1000000.0F) + " MP]" + + "\nMain window width: " + ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth() + ", height: " + ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight() + " [" + String.format("%.1f", (float) windowPixels / 1000000.0F) + " MP]" + "\nTotal shaded pixels per frame: " + String.format("%.1f", (float) vrPixels / 1000000.0F) + " MP (eye stencil not accounted for)"); this.lastDisplayFBWidth = eyeFBWidth; this.lastDisplayFBHeight = eyeFBHeight; @@ -705,8 +747,8 @@ public void setupRenderConfiguration() throws Exception { public boolean wasDisplayResized() { Minecraft minecraft = Minecraft.getInstance(); - int i = minecraft.getWindow().getScreenHeight(); - int j = minecraft.getWindow().getScreenWidth(); + int i = ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight(); + int j = ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth(); boolean flag = this.dispLastHeight != i || this.dispLastWidth != j; this.dispLastHeight = i; this.dispLastWidth = j; diff --git a/common/src/main/java/org/vivecraft/client_vr/provider/openvr_lwjgl/MCOpenVR.java b/common/src/main/java/org/vivecraft/client_vr/provider/openvr_lwjgl/MCOpenVR.java index d179335e6..404254ec4 100644 --- a/common/src/main/java/org/vivecraft/client_vr/provider/openvr_lwjgl/MCOpenVR.java +++ b/common/src/main/java/org/vivecraft/client_vr/provider/openvr_lwjgl/MCOpenVR.java @@ -8,6 +8,8 @@ import com.sun.jna.NativeLibrary; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.language.ClientLanguage; +import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.phys.Vec3; @@ -427,59 +429,82 @@ protected ControllerType findActiveBindingControllerType(KeyMapping binding) { private void generateActionManifest() { Map map = new HashMap<>(); - List> list = new ArrayList<>(); + List> actionSets = new ArrayList<>(); - for (VRInputActionSet vrinputactionset : VRInputActionSet.values()) { - String s = vrinputactionset.usage; + for (VRInputActionSet actionSet : VRInputActionSet.values()) { + String usage = actionSet.usage; - if (vrinputactionset.advanced && !this.dh.vrSettings.allowAdvancedBindings) { - s = "hidden"; + if (actionSet.advanced && !this.dh.vrSettings.allowAdvancedBindings) { + usage = "hidden"; } - list.add(ImmutableMap.builder().put("name", vrinputactionset.name).put("usage", s).build()); + actionSets.add(ImmutableMap.builder().put("name", actionSet.name).put("usage", usage).build()); } - map.put("action_sets", list); - List list1 = new ArrayList<>(this.inputActions.values()); - list1.sort(Comparator.comparing((action) -> + map.put("action_sets", actionSets); + List sortedActions = new ArrayList<>(this.inputActions.values()); + sortedActions.sort(Comparator.comparing((action) -> { return action.keyBinding; })); - List> list2 = new ArrayList<>(); + List> actions = new ArrayList<>(); - for (VRInputAction vrinputaction : list1) { - list2.add(ImmutableMap.builder().put("name", vrinputaction.name).put("requirement", vrinputaction.requirement).put("type", vrinputaction.type).build()); + for (VRInputAction action : sortedActions) { + actions.add(ImmutableMap.builder().put("name", action.name).put("requirement", action.requirement).put("type", action.type).build()); } - list2.add(ImmutableMap.builder().put("name", ACTION_LEFT_HAND).put("requirement", "suggested").put("type", "pose").build()); - list2.add(ImmutableMap.builder().put("name", ACTION_RIGHT_HAND).put("requirement", "suggested").put("type", "pose").build()); - list2.add(ImmutableMap.builder().put("name", ACTION_EXTERNAL_CAMERA).put("requirement", "optional").put("type", "pose").build()); - list2.add(ImmutableMap.builder().put("name", ACTION_LEFT_HAPTIC).put("requirement", "suggested").put("type", "vibration").build()); - list2.add(ImmutableMap.builder().put("name", ACTION_RIGHT_HAPTIC).put("requirement", "suggested").put("type", "vibration").build()); - map.put("actions", list2); - Map map1 = new HashMap<>(); - - for (VRInputAction vrinputaction1 : list1) { - MutableComponent component = Component.translatable(vrinputaction1.keyBinding.getCategory()).append(" - ").append(Component.translatable(vrinputaction1.keyBinding.getName())); - map1.put(vrinputaction1.name, component.getString()); - } + actions.add(ImmutableMap.builder().put("name", ACTION_LEFT_HAND).put("requirement", "suggested").put("type", "pose").build()); + actions.add(ImmutableMap.builder().put("name", ACTION_RIGHT_HAND).put("requirement", "suggested").put("type", "pose").build()); + actions.add(ImmutableMap.builder().put("name", ACTION_EXTERNAL_CAMERA).put("requirement", "optional").put("type", "pose").build()); + actions.add(ImmutableMap.builder().put("name", ACTION_LEFT_HAPTIC).put("requirement", "suggested").put("type", "vibration").build()); + actions.add(ImmutableMap.builder().put("name", ACTION_RIGHT_HAPTIC).put("requirement", "suggested").put("type", "vibration").build()); + map.put("actions", actions); + + // Last updated 10/29/2023 + // Hard-coded list of languages Steam supports + String[] steamLanguages = {"en_US", "bg_BG", "zh_CN", "zh_TW", "cs_CZ", "da_DK", "nl_NL", "fi_FI", "fr_FR", "de_DE", "el_GR", "hu_HU", "id_ID", "it_IT", "ja_JP", "ko_KR", "no_NO", "pl_PL", "pt_PT", "pt_BR", "ro_RO", "ru_RU", "es_ES", "es_MX", "sv_SE", "th_TH", "tr_TR", "uk_UA", "vi_VN"}; + // Steam uses some incorrect language codes, this remaps to those + // SteamVR itself is also not translated into all languages Steam supports yet, so in those cases English may be used regardless + Map wrongCodeMappings = Map.ofEntries(Map.entry("cs_CZ", "cs_CS"), Map.entry("da_DK", "da_DA"), Map.entry("el_GR", "el_EL"), Map.entry("sv_SE", "sv_SV")); + + List> localeList = new ArrayList<>(); + for (String langCode : steamLanguages) { + Map localeMap = new HashMap<>(); + + // Load the language + List langs = new ArrayList<>(); + langs.add("en_us"); + if (!langCode.equals("en_US")) langs.add(langCode.toLowerCase()); + Language lang = ClientLanguage.loadFrom(mc.getResourceManager(), langs, false); + + for (VRInputAction action : sortedActions) { + localeMap.put(action.name, lang.getOrDefault(action.keyBinding.getCategory()) + " - " + lang.getOrDefault(action.keyBinding.getName())); + } + + for (VRInputActionSet actionSet : VRInputActionSet.values()) { + localeMap.put(actionSet.name, lang.getOrDefault(actionSet.localizedName)); + } + + // We don't really care about localizing these + localeMap.put(ACTION_LEFT_HAND, "Left Hand Pose"); + localeMap.put(ACTION_RIGHT_HAND, "Right Hand Pose"); + localeMap.put(ACTION_EXTERNAL_CAMERA, "External Camera"); + localeMap.put(ACTION_LEFT_HAPTIC, "Left Hand Haptic"); + localeMap.put(ACTION_RIGHT_HAPTIC, "Right Hand Haptic"); - for (VRInputActionSet vrinputactionset1 : VRInputActionSet.values()) { - MutableComponent component = Component.translatable(vrinputactionset1.localizedName); - map1.put(vrinputactionset1.name, component.getString()); + localeMap.put("language_tag", wrongCodeMappings.getOrDefault(langCode, langCode)); + localeList.add(localeMap); } + map.put("localization", localeList); - map1.put(ACTION_LEFT_HAND, "Left Hand Pose"); - map1.put(ACTION_RIGHT_HAND, "Right Hand Pose"); - map1.put(ACTION_EXTERNAL_CAMERA, "External Camera"); - map1.put(ACTION_LEFT_HAPTIC, "Left Hand Haptic"); - map1.put(ACTION_RIGHT_HAPTIC, "Right Hand Haptic"); - map1.put("language_tag", "en_US"); - map.put("localization", ImmutableList.>builder().add(map1).build()); - List> list3 = new ArrayList<>(); - list3.add(ImmutableMap.builder().put("controller_type", "vive_controller").put("binding_url", "vive_defaults.json").build()); - list3.add(ImmutableMap.builder().put("controller_type", "oculus_touch").put("binding_url", "oculus_defaults.json").build()); - map.put("default_bindings", list3); + List> defaults = new ArrayList<>(); + defaults.add(ImmutableMap.builder().put("controller_type", "vive_controller").put("binding_url", "vive_defaults.json").build()); + defaults.add(ImmutableMap.builder().put("controller_type", "oculus_touch").put("binding_url", "oculus_defaults.json").build()); + defaults.add(ImmutableMap.builder().put("controller_type", "holographic_controller").put("binding_url", "wmr_defaults.json").build()); + defaults.add(ImmutableMap.builder().put("controller_type", "knuckles").put("binding_url", "knuckles_defaults.json").build()); + defaults.add(ImmutableMap.builder().put("controller_type", "vive_cosmos_controller").put("binding_url", "cosmos_defaults.json").build()); + defaults.add(ImmutableMap.builder().put("controller_type", "vive_tracker_camera").put("binding_url", "tracker_defaults.json").build()); + map.put("default_bindings", defaults); try { (new File("openvr/input")).mkdirs(); @@ -491,9 +516,13 @@ private void generateActionManifest() { throw new RuntimeException("Failed to write action manifest", exception); } - String s1 = this.dh.vrSettings.reverseHands ? "_reversed" : ""; - Utils.loadAssetToFile("input/vive_defaults" + s1 + ".json", new File("openvr/input/vive_defaults.json"), false); - Utils.loadAssetToFile("input/oculus_defaults" + s1 + ".json", new File("openvr/input/oculus_defaults.json"), false); + String rev = this.dh.vrSettings.reverseHands ? "_reversed" : ""; + Utils.loadAssetToFile("input/vive_defaults" + rev + ".json", new File("openvr/input/vive_defaults.json"), false); + Utils.loadAssetToFile("input/oculus_defaults" + rev + ".json", new File("openvr/input/oculus_defaults.json"), false); + Utils.loadAssetToFile("input/wmr_defaults" + rev + ".json", new File("openvr/input/wmr_defaults.json"), false); + Utils.loadAssetToFile("input/knuckles_defaults" + rev + ".json", new File("openvr/input/knuckles_defaults.json"), false); + Utils.loadAssetToFile("input/cosmos_defaults" + rev + ".json", new File("openvr/input/cosmos_defaults.json"), false); + Utils.loadAssetToFile("input/tracker_defaults.json", new File("openvr/input/tracker_defaults.json"), false); } private long getActionHandle(String name) { diff --git a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java index 97208c756..6af70e8b7 100644 --- a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java +++ b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VREffectsHelper.java @@ -806,6 +806,9 @@ private static boolean shouldRenderCrosshair() { return false; } else if (RadialHandler.isUsingController(ControllerType.RIGHT)) { return false; + } else if (GuiHandler.guiPos_room != null) { + // don't show it, when a screen is open, or a popup + return false; } else if (dataHolder.bowTracker.isNotched()) { return false; } else if (dataHolder.vr.getInputAction(VivecraftVRMod.INSTANCE.keyVRInteract).isEnabledRaw(ControllerType.RIGHT) @@ -824,7 +827,6 @@ private static boolean shouldRenderCrosshair() { } public static void renderCrosshairAtDepth(boolean depthAlways, PoseStack poseStack) { - // TODO broken if (shouldRenderCrosshair()) { mc.getProfiler().push("crosshair"); diff --git a/common/src/main/java/org/vivecraft/client_vr/settings/SettingField.java b/common/src/main/java/org/vivecraft/client_vr/settings/SettingField.java index af6e2685f..7114be7ba 100644 --- a/common/src/main/java/org/vivecraft/client_vr/settings/SettingField.java +++ b/common/src/main/java/org/vivecraft/client_vr/settings/SettingField.java @@ -31,4 +31,13 @@ * @return whether to separate keys */ boolean separate() default false; + + /** + * If true, arrays will always be kept the same size when loading. If false, + * the size of the array can vary. If {@link #separate} is true, setting this + * to false will have no effect and the array will always be the same size. + * + * @return whether to separate keys + */ + boolean fixedSize() default true; } diff --git a/common/src/main/java/org/vivecraft/client_vr/settings/VRHotkeys.java b/common/src/main/java/org/vivecraft/client_vr/settings/VRHotkeys.java index 422d74e4d..f2f535933 100644 --- a/common/src/main/java/org/vivecraft/client_vr/settings/VRHotkeys.java +++ b/common/src/main/java/org/vivecraft/client_vr/settings/VRHotkeys.java @@ -5,11 +5,13 @@ import net.minecraft.client.gui.screens.WinScreen; import net.minecraft.network.chat.Component; import net.minecraft.world.phys.Vec3; +import org.lwjgl.glfw.GLFW; import org.vivecraft.client.utils.LangHelper; import org.vivecraft.client.utils.Utils; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.MethodHolder; import org.vivecraft.client_vr.VRData; +import org.vivecraft.client_vr.VRState; import org.vivecraft.client_vr.extensions.MinecraftExtension; import org.vivecraft.common.utils.math.*; @@ -37,28 +39,28 @@ public static boolean handleKeyboardInputs(int key, int scanCode, int action, in } else { Minecraft minecraft = Minecraft.getInstance(); ClientDataHolderVR dataholder = ClientDataHolderVR.getInstance(); - boolean flag = false; + boolean gotKey = false; - if (action == 1 && key == 344 && MethodHolder.isKeyDown(345)) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_RIGHT_SHIFT && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { dataholder.vrSettings.storeDebugAim = true; minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.showaim")); - flag = true; + gotKey = true; } - if (action == 1 && key == 66 && MethodHolder.isKeyDown(345)) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_B && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { dataholder.vrSettings.walkUpBlocks = !dataholder.vrSettings.walkUpBlocks; minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.walkupblocks", dataholder.vrSettings.walkUpBlocks ? LangHelper.getYes() : LangHelper.getNo())); - flag = true; + gotKey = true; } - if (action == 1 && key == 73 && MethodHolder.isKeyDown(345)) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_I && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { dataholder.vrSettings.inertiaFactor = dataholder.vrSettings.inertiaFactor.getNext(); minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.playerinertia", Component.translatable(dataholder.vrSettings.inertiaFactor.getLangKey()))); - flag = true; + gotKey = true; } - if (action == 1 && key == 82 && MethodHolder.isKeyDown(345)) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_R && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { if (dataholder.vrPlayer.isTeleportOverridden()) { dataholder.vrPlayer.setTeleportOverride(false); minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.teleportdisabled")); @@ -67,29 +69,36 @@ public static boolean handleKeyboardInputs(int key, int scanCode, int action, in minecraft.gui.getChat().addMessage(Component.translatable("vivecraft.messages.teleportenabled")); } - flag = true; + gotKey = true; } - if (action == 1 && key == 268 && MethodHolder.isKeyDown(345)) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_HOME && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { snapMRCam(0); - flag = true; + gotKey = true; } - if (action == 1 && key == 301 && debug) { + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_F12 && debug) { minecraft.setScreen(new WinScreen(false, Runnables.doNothing())); - flag = true; + gotKey = true; } - if ((minecraft.level == null || minecraft.screen != null) && action == 1 && key == 294) { + if ((minecraft.level == null || minecraft.screen != null) && action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_F5) { dataholder.vrSettings.setOptionValue(VRSettings.VrOptions.MIRROR_DISPLAY); ((MinecraftExtension) minecraft).vivecraft$notifyMirror(dataholder.vrSettings.getButtonDisplayString(VRSettings.VrOptions.MIRROR_DISPLAY), false, 3000); } - if (flag) { + // toggle VR with a keyboard shortcut + if (action == GLFW.GLFW_PRESS && key == GLFW.GLFW_KEY_F7 && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL)) { + VRState.vrEnabled = !VRState.vrEnabled; + ClientDataHolderVR.getInstance().vrSettings.vrEnabled = VRState.vrEnabled; + gotKey = true; + } + + if (gotKey) { dataholder.vrSettings.saveOptions(); } - return flag; + return gotKey; } } @@ -98,82 +107,82 @@ public static void handleMRKeys() { ClientDataHolderVR dataholder = ClientDataHolderVR.getInstance(); boolean flag = false; - if (MethodHolder.isKeyDown(263) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_LEFT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(-0.01F, 0.0F, 0.0F)); flag = true; } - if (MethodHolder.isKeyDown(262) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(0.01F, 0.0F, 0.0F)); flag = true; } - if (MethodHolder.isKeyDown(265) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_UP) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(0.0F, 0.0F, -0.01F)); flag = true; } - if (MethodHolder.isKeyDown(264) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_DOWN) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(0.0F, 0.0F, 0.01F)); flag = true; } - if (MethodHolder.isKeyDown(266) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_PAGE_UP) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(0.0F, 0.01F, 0.0F)); flag = true; } - if (MethodHolder.isKeyDown(267) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_PAGE_DOWN) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamPos(new Vector3(0.0F, -0.01F, 0.0F)); flag = true; } - if (MethodHolder.isKeyDown(265) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_UP) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.PITCH, 0.5F); flag = true; } - if (MethodHolder.isKeyDown(264) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_DOWN) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.PITCH, -0.5F); flag = true; } - if (MethodHolder.isKeyDown(263) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_LEFT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.YAW, 0.5F); flag = true; } - if (MethodHolder.isKeyDown(262) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.YAW, -0.5F); flag = true; } - if (MethodHolder.isKeyDown(266) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_PAGE_UP) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.ROLL, 0.5F); flag = true; } - if (MethodHolder.isKeyDown(267) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_PAGE_DOWN) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { adjustCamRot(Axis.ROLL, -0.5F); flag = true; } - if (MethodHolder.isKeyDown(260) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_INSERT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { minecraft.options.fov().set(minecraft.options.fov().get() + 1); flag = true; } - if (MethodHolder.isKeyDown(261) && MethodHolder.isKeyDown(345) && !MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_DELETE) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && !MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { minecraft.options.fov().set(minecraft.options.fov().get() - 1); flag = true; } - if (MethodHolder.isKeyDown(260) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_INSERT) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { ++dataholder.vrSettings.mixedRealityFov; flag = true; } - if (MethodHolder.isKeyDown(261) && MethodHolder.isKeyDown(345) && MethodHolder.isKeyDown(344)) { + if (MethodHolder.isKeyDown(GLFW.GLFW_KEY_DELETE) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_CONTROL) && MethodHolder.isKeyDown(GLFW.GLFW_KEY_RIGHT_SHIFT)) { --dataholder.vrSettings.mixedRealityFov; flag = true; } diff --git a/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java b/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java index 12548ac5a..b0b29fa05 100644 --- a/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java +++ b/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java @@ -13,9 +13,9 @@ import net.minecraft.sounds.SoundEvent; import net.minecraft.util.Mth; import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.lwjgl.glfw.GLFW; import org.vivecraft.client.utils.LangHelper; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.VRState; @@ -171,6 +171,8 @@ public enum UpdateType implements OptionEnum { public String[] vrRadialItems = getRadialItemsDefault(); @SettingField(config = "RADIALALT", separate = true) public String[] vrRadialItemsAlt = getRadialItemsAltDefault(); + @SettingField(fixedSize = false) + public int[] keyboardCodes = getKeyboardCodesDefault(); //Control @SettingField(VrOptions.REVERSE_HANDS) @@ -402,6 +404,8 @@ public enum UpdateType implements OptionEnum { public float physicalKeyboardScale = 1.0f; @SettingField(VrOptions.PHYSICAL_KEYBOARD_THEME) public PhysicalKeyboard.KeyboardTheme physicalKeyboardTheme = PhysicalKeyboard.KeyboardTheme.DEFAULT; + @SettingField(VrOptions.KEYBOARD_PRESS_BINDS) + public boolean keyboardPressBinds = false; @SettingField(VrOptions.ALLOW_ADVANCED_BINDINGS) public boolean allowAdvancedBindings = false; @SettingField(VrOptions.CHAT_NOTIFICATIONS) @@ -412,6 +416,12 @@ public enum UpdateType implements OptionEnum { public boolean guiAppearOverBlock = true; @SettingField(VrOptions.SHADER_GUI_RENDER) public ShaderGUIRender shaderGUIRender = ShaderGUIRender.AFTER_SHADER; + @SettingField(VrOptions.DOUBLE_GUI_RESOLUTION) + public boolean doubleGUIResolution = false; + @SettingField(VrOptions.GUI_SCALE) + public int guiScale = 0; + @SettingField(VrOptions.HUD_MAX_GUI_SCALE) + public boolean hudMaxScale = false; @SettingField(VrOptions.SHOW_UPDATES) public boolean alwaysShowUpdates = true; @SettingField @@ -449,8 +459,8 @@ public enum UpdateType implements OptionEnum { public ServerOverrides overrides = new ServerOverrides(); - private final Map> fieldEnumMap = new EnumMap<>(VrOptions.class); - private final Map> fieldConfigMap = new HashMap<>(); + private final Map fieldEnumMap = new EnumMap<>(VrOptions.class); + private final Map fieldConfigMap = new HashMap<>(); // This map is only here to preserve old settings, not intended for general use private Map preservedSettingMap; @@ -487,14 +497,14 @@ private void initializeFieldInfo() { } String config = ann.config().isEmpty() ? field.getName() : ann.config(); + ConfigEntry configEntry = new ConfigEntry(field, ann.value(), config, ann.separate(), ann.fixedSize()); if (ann.value() != VrOptions.DUMMY) { if (fieldEnumMap.containsKey(ann.value())) { throw new RuntimeException("duplicate enum in setting field: " + field.getName()); } - fieldEnumMap.put(ann.value(), Triple.of(field, config, ann.separate())); + fieldEnumMap.put(ann.value(), configEntry); } - Triple configEntry = Triple.of(field, ann.value(), ann.separate()); if (ann.separate() && field.getType().isArray()) { int len = Array.getLength(field.get(this)); IntStream.range(0, len).forEach(i -> fieldConfigMap.put(config + "_" + i, configEntry)); @@ -709,16 +719,16 @@ public void loadDefault(VrOptions option) { if (mapping == null) { return; } - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); - String name = mapping.getMiddle(); + String name = mapping.configName; Map profileSet = ProfileManager.getProfileSet(this.defaults, ProfileManager.PROFILE_SET_VR); if (type.isArray()) { Object arr = field.get(this); int len = Array.getLength(arr); - if (mapping.getRight()) { + if (mapping.separate) { for (int i = 0; i < len; i++) { Object obj = Objects.requireNonNull(loadDefault(name + "_" + i, null, option, type.getComponentType(), false, profileSet)); Array.set(arr, i, obj); @@ -732,7 +742,7 @@ public void loadDefault(VrOptions option) { } } } else { - Object obj = Objects.requireNonNull(loadDefault(name, null, option, type, mapping.getRight(), profileSet)); + Object obj = Objects.requireNonNull(loadDefault(name, null, option, type, mapping.separate, profileSet)); field.set(this, obj); } } catch (Exception ex) { @@ -767,24 +777,31 @@ public void loadOptions(JsonObject theProfiles) { continue; } - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); Object currentValue = field.get(this); if (type.isArray()) { - if (mapping.getRight()) { + if (mapping.separate) { int index = Integer.parseInt(name.substring(name.lastIndexOf('_') + 1)); - Object obj = Objects.requireNonNull(loadOption(name.substring(0, name.lastIndexOf('_')), value, Array.get(currentValue, index), mapping.getMiddle(), type.getComponentType(), false)); + Object obj = Objects.requireNonNull(loadOption(name.substring(0, name.lastIndexOf('_')), value, Array.get(currentValue, index), mapping.vrOptions, type.getComponentType(), false)); Array.set(currentValue, index, obj); } else { int len = Array.getLength(currentValue); String[] split = value.split(";", -1); // Avoid conflicting with other comma-delimited types + if (split.length != len && !mapping.fixedSize) { + Object newValue = Array.newInstance(type.getComponentType(), split.length); + System.arraycopy(currentValue, 0, newValue, 0, Math.min(len, split.length)); + field.set(this, newValue); + currentValue = newValue; + len = split.length; + } for (int i = 0; i < len; i++) { - Object obj = Objects.requireNonNull(loadOption(name, split[i], Array.get(currentValue, i), mapping.getMiddle(), type.getComponentType(), false)); + Object obj = Objects.requireNonNull(loadOption(name, split[i], Array.get(currentValue, i), mapping.vrOptions, type.getComponentType(), false)); Array.set(currentValue, i, obj); } } } else { - Object obj = Objects.requireNonNull(loadOption(name, value, currentValue, mapping.getMiddle(), type, mapping.getRight())); + Object obj = Objects.requireNonNull(loadOption(name, value, currentValue, mapping.vrOptions, type, mapping.separate)); field.set(this, obj); } } catch (Exception var7) { @@ -820,27 +837,27 @@ private void saveOptions(JsonObject theProfiles) { for (var entry : fieldConfigMap.entrySet()) { String name = entry.getKey(); var mapping = entry.getValue(); - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); Object obj = field.get(this); try { if (type.isArray()) { - if (mapping.getRight()) { + if (mapping.separate) { int index = Integer.parseInt(name.substring(name.lastIndexOf('_') + 1)); - String value = Objects.requireNonNull(saveOption(name.substring(0, name.lastIndexOf('_')), Array.get(obj, index), mapping.getMiddle(), type.getComponentType(), mapping.getRight())); + String value = Objects.requireNonNull(saveOption(name.substring(0, name.lastIndexOf('_')), Array.get(obj, index), mapping.vrOptions, type.getComponentType(), mapping.separate)); var5.println(name + ":" + value); } else { StringJoiner joiner = new StringJoiner(";"); int len = Array.getLength(obj); for (int i = 0; i < len; i++) { - String value = Objects.requireNonNull(saveOption(name, Array.get(obj, i), mapping.getMiddle(), type.getComponentType(), mapping.getRight())); + String value = Objects.requireNonNull(saveOption(name, Array.get(obj, i), mapping.vrOptions, type.getComponentType(), mapping.separate)); joiner.add(value); } var5.println(name + ":" + joiner); } } else { - String value = Objects.requireNonNull(saveOption(name, obj, mapping.getMiddle(), type, mapping.getRight())); + String value = Objects.requireNonNull(saveOption(name, obj, mapping.vrOptions, type, mapping.separate)); var5.println(name + ":" + value); } } catch (Exception ex) { @@ -873,7 +890,7 @@ public String getButtonDisplayString(VrOptions par1EnumOptions) { if (mapping == null) { return var2; } - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); Object obj = field.get(this); @@ -912,7 +929,7 @@ public float getOptionFloatValue(VrOptions par1EnumOptions) { if (mapping == null) { return 0; } - Field field = mapping.getLeft(); + Field field = mapping.field; float value = ((Number) field.get(this)).floatValue(); if (overrides.hasSetting(par1EnumOptions)) { @@ -937,7 +954,7 @@ public void setOptionValue(VrOptions par1EnumOptions) { if (mapping == null) { return; } - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); Object obj = par1EnumOptions.setOptionValue(field.get(this)); @@ -948,7 +965,7 @@ public void setOptionValue(VrOptions par1EnumOptions) { } else if (OptionEnum.class.isAssignableFrom(type)) { field.set(this, ((OptionEnum) field.get(this)).getNext()); } else { - logger.warn("Don't know how to set VR option " + mapping.getMiddle() + " with type " + type.getSimpleName()); + logger.warn("Don't know how to set VR option " + mapping.configName + " with type " + type.getSimpleName()); return; } @@ -966,7 +983,7 @@ public void setOptionFloatValue(VrOptions par1EnumOptions, float par2) { if (mapping == null) { return; } - Field field = mapping.getLeft(); + Field field = mapping.field; Class type = field.getType(); float f = Objects.requireNonNullElse(par1EnumOptions.setOptionFloatValue(par2), par2); @@ -1004,6 +1021,8 @@ public float getHeadTrackSensitivity() { //return this.headTrackSensitivity; // TODO: If head track sensitivity is working again... if } + record ConfigEntry(Field field, VrOptions vrOptions, String configName, boolean separate, boolean fixedSize) { + } public enum VrOptions { DUMMY(false, true), // Dummy @@ -1146,8 +1165,32 @@ void onOptionChange() { } }, PHYSICAL_KEYBOARD_THEME(false, false), // Keyboard Theme + KEYBOARD_PRESS_BINDS(false, true), // Keyboard Presses Bindings GUI_APPEAR_OVER_BLOCK(false, true), // Appear Over Block - SHADER_GUI_RENDER(false, true), + SHADER_GUI_RENDER(false, false), // Shaders GUI + DOUBLE_GUI_RESOLUTION(false, true), // 1440p GUI + GUI_SCALE(true, true, 0, 6, 1, 0) { // GUI Scale + + @Override + String getDisplayString(String prefix, Object value) { + if ((int) value == 0) { + return prefix + I18n.get("options.guiScale.auto"); + } else { + if (ClientDataHolderVR.getInstance().vrSettings.doubleGUIResolution) { + return prefix + value; + } else { + return prefix + (int) Math.ceil((int) value * 0.5f); + } + } + } + @Override + void onOptionChange() { + if (VRState.vrEnabled) { + ClientDataHolderVR.getInstance().vrRenderer.resizeFrameBuffers(""); + } + } + }, + HUD_MAX_GUI_SCALE(false, true), // force HUD to render with max GUI scale //HMD/render FSAA(false, true), // Lanczos Scaler LOW_HEALTH_INDICATOR(false, true), // red low health pulse @@ -1980,6 +2023,66 @@ public String[] getRadialItemsAltDefault() { return out; } + public int[] getKeyboardCodesDefault() { + // Some keys in the in-game keyboard don't have assignable key codes + int[] out = new int[]{ + GLFW.GLFW_KEY_GRAVE_ACCENT, + GLFW.GLFW_KEY_1, + GLFW.GLFW_KEY_2, + GLFW.GLFW_KEY_3, + GLFW.GLFW_KEY_4, + GLFW.GLFW_KEY_5, + GLFW.GLFW_KEY_6, + GLFW.GLFW_KEY_7, + GLFW.GLFW_KEY_8, + GLFW.GLFW_KEY_9, + GLFW.GLFW_KEY_0, + GLFW.GLFW_KEY_MINUS, + GLFW.GLFW_KEY_EQUAL, + GLFW.GLFW_KEY_Q, + GLFW.GLFW_KEY_W, + GLFW.GLFW_KEY_E, + GLFW.GLFW_KEY_R, + GLFW.GLFW_KEY_T, + GLFW.GLFW_KEY_Y, + GLFW.GLFW_KEY_U, + GLFW.GLFW_KEY_I, + GLFW.GLFW_KEY_O, + GLFW.GLFW_KEY_P, + GLFW.GLFW_KEY_LEFT_BRACKET, + GLFW.GLFW_KEY_RIGHT_BRACKET, + GLFW.GLFW_KEY_BACKSLASH, + GLFW.GLFW_KEY_A, + GLFW.GLFW_KEY_S, + GLFW.GLFW_KEY_D, + GLFW.GLFW_KEY_F, + GLFW.GLFW_KEY_G, + GLFW.GLFW_KEY_H, + GLFW.GLFW_KEY_J, + GLFW.GLFW_KEY_K, + GLFW.GLFW_KEY_L, + GLFW.GLFW_KEY_SEMICOLON, + GLFW.GLFW_KEY_APOSTROPHE, + GLFW.GLFW_KEY_UNKNOWN, // colon + GLFW.GLFW_KEY_UNKNOWN, // quote + GLFW.GLFW_KEY_Z, + GLFW.GLFW_KEY_X, + GLFW.GLFW_KEY_C, + GLFW.GLFW_KEY_V, + GLFW.GLFW_KEY_B, + GLFW.GLFW_KEY_N, + GLFW.GLFW_KEY_M, + GLFW.GLFW_KEY_COMMA, + GLFW.GLFW_KEY_PERIOD, + GLFW.GLFW_KEY_SLASH, + GLFW.GLFW_KEY_UNKNOWN, // question mark + GLFW.GLFW_KEY_UNKNOWN, // less than + GLFW.GLFW_KEY_UNKNOWN // greater than + }; + + return out; + } + public double normalizeValue(float optionFloatValue) { // TODO Auto-generated method stub return 0; diff --git a/common/src/main/java/org/vivecraft/mixin/client/gui/screens/TitleScreenMixin.java b/common/src/main/java/org/vivecraft/mixin/client/gui/screens/TitleScreenMixin.java index 6834cf32f..5abcdfb65 100644 --- a/common/src/main/java/org/vivecraft/mixin/client/gui/screens/TitleScreenMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client/gui/screens/TitleScreenMixin.java @@ -4,14 +4,13 @@ import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.TitleScreen; -import net.minecraft.client.renderer.PanoramaRenderer; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.vivecraft.client.gui.screens.UpdateScreen; import org.vivecraft.client.utils.UpdateChecker; @@ -32,11 +31,8 @@ protected TitleScreenMixin(Component component) { private Button updateButton; - @Redirect(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PanoramaRenderer;render(FF)V"), method = "render") - public void vivecraft$maybeNoPanorama(PanoramaRenderer instance, float f, float g) { - if (VRState.vrRunning && ClientDataHolderVR.getInstance().menuWorldRenderer.isReady()) { - return; - } - instance.render(f, g); + @ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PanoramaRenderer;render(FF)V"), method = "render", index = 1) + public float vivecraft$maybeNoPanorama(float alpha) { + return VRState.vrRunning && ClientDataHolderVR.getInstance().menuWorldRenderer.isReady() ? 0.0F : alpha; } } diff --git a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/PlayerRendererMixin.java b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/PlayerRendererMixin.java index f991369f9..b9b019772 100644 --- a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/PlayerRendererMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/PlayerRendererMixin.java @@ -74,20 +74,20 @@ public boolean addLayer(RenderLayer renderLayer) { if (constructor == null) { // do a hacky clone, and replace parent if (((PlayerModel) model).slim) { - addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); - addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); } else { - addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); - addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); } } else { // make a new instance with the vr model as parent if (((PlayerModel) model).slim) { - addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); - addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); } else { - addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); - addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); } } } @@ -98,7 +98,7 @@ public boolean addLayer(RenderLayer renderLayer) { * does a basic Object.clone() copy */ @Unique - private void addLayerClone(RenderLayer renderLayer, LivingEntityRenderer target) { + private void vivecraft$addLayerClone(RenderLayer renderLayer, LivingEntityRenderer target) { try { VRSettings.logger.warn("Copying layer: {} with Object.copy, this could cause issues", renderLayer.getClass()); RenderLayer newLayer = (RenderLayer) ((RenderLayerExtension) renderLayer).clone(); @@ -113,7 +113,7 @@ private void addLayerClone(RenderLayer renderLayer, LivingEntityRenderer constructor, RenderLayerTypes.LayerType type, LivingEntityRenderer target) { + private void vivecraft$addLayerConstructor(Constructor constructor, RenderLayerTypes.LayerType type, LivingEntityRenderer target) { try { switch (type) { case PARENT_ONLY -> target.addLayer((RenderLayer) constructor.newInstance(target)); diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java index acc12b65a..724a98f84 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java @@ -390,7 +390,7 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { RenderSystem.depthMask(true); // draw cursor on Gui Layer - if (this.screen != null) { + if (this.screen != null || !mouseHandler.isMouseGrabbed()) { PoseStack poseStack = RenderSystem.getModelViewStack(); poseStack.pushPose(); poseStack.setIdentity(); @@ -832,16 +832,20 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { @Unique private void vivecraft$drawNotifyMirror() { if (System.currentTimeMillis() < this.vivecraft$mirroNotifyStart + this.vivecraft$mirroNotifyLen) { - RenderSystem.viewport(0, 0, this.window.getScreenWidth(), this.window.getScreenHeight()); - Matrix4f matrix4f = new Matrix4f().setOrtho(0.0F, (float) this.window.getScreenWidth(), - (float) this.window.getScreenHeight(), 0.0F, 1000.0F, 3000.0F); + int screenX = ((WindowExtension) (Object) this.window).vivecraft$getActualScreenWidth(); + int screenY = ((WindowExtension) (Object) this.window).vivecraft$getActualScreenHeight(); + RenderSystem.viewport(0, 0, screenX, screenY); + Matrix4f matrix4f = new Matrix4f().setOrtho(0.0F, (float) screenX, + screenY, 0.0F, 1000.0F, 3000.0F); RenderSystem.setProjectionMatrix(matrix4f, VertexSorting.ORTHOGRAPHIC_Z); RenderSystem.getModelViewStack().pushPose(); RenderSystem.getModelViewStack().setIdentity(); RenderSystem.getModelViewStack().translate(0, 0, -2000); RenderSystem.applyModelViewMatrix(); - PoseStack p = new PoseStack(); - p.scale(3, 3, 3); + RenderSystem.setShaderFogStart(Float.MAX_VALUE); + + GuiGraphics guiGraphics = new GuiGraphics((Minecraft) (Object) this, renderBuffers.bufferSource()); + guiGraphics.pose().scale(3, 3, 3); RenderSystem.clear(256, ON_OSX); if (this.vivecraft$mirrorNotifyClear) { @@ -859,7 +863,6 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { int j = 1; int k = 12; - GuiGraphics guiGraphics = new GuiGraphics((Minecraft) (Object) this, renderBuffers.bufferSource()); for (String s : arraylist) { guiGraphics.drawString(this.font, s, 1, j, 16777215); j += 12; @@ -878,7 +881,6 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { } // release mouse when switching to standing if (!ClientDataHolderVR.getInstance().vrSettings.seated) { - mouseHandler.releaseMouse(); InputConstants.grabOrReleaseMouse(window.getWindow(), GLFW.GLFW_CURSOR_NORMAL, mouseHandler.xpos(), mouseHandler.ypos()); } } else { @@ -946,14 +948,16 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { RenderTarget rendertarget = ClientDataHolderVR.getInstance().vrRenderer.framebufferEye0; RenderTarget rendertarget1 = ClientDataHolderVR.getInstance().vrRenderer.framebufferEye1; + int screenWidth = ((WindowExtension) (Object) this.window).vivecraft$getActualScreenWidth() / 2; + int screenHeight = ((WindowExtension) (Object) this.window).vivecraft$getActualScreenHeight(); if (rendertarget != null) { - ((RenderTargetExtension) rendertarget).vivecraft$blitToScreen(0, this.window.getScreenWidth() / 2, - this.window.getScreenHeight(), 0, true, 0.0F, 0.0F, false); + ((RenderTargetExtension) rendertarget).vivecraft$blitToScreen(0, screenWidth, + screenHeight, 0, true, 0.0F, 0.0F, false); } if (rendertarget1 != null) { - ((RenderTargetExtension) rendertarget1).vivecraft$blitToScreen(this.window.getScreenWidth() / 2, - this.window.getScreenWidth() / 2, this.window.getScreenHeight(), 0, true, 0.0F, 0.0F, false); + ((RenderTargetExtension) rendertarget1).vivecraft$blitToScreen(screenWidth, + screenWidth, screenHeight, 0, true, 0.0F, 0.0F, false); } } else { float xcrop = 0.0F; @@ -986,8 +990,8 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { // source = DataHolder.getInstance().vrRenderer.telescopeFramebufferR; // if (source != null) { - ((RenderTargetExtension) source).vivecraft$blitToScreen(0, this.window.getScreenWidth(), - this.window.getScreenHeight(), 0, true, xcrop, ycrop, ar); + ((RenderTargetExtension) source).vivecraft$blitToScreen(0, ((WindowExtension) (Object) this.window).vivecraft$getActualScreenWidth(), + ((WindowExtension) (Object) this.window).vivecraft$getActualScreenHeight(), 0, true, xcrop, ycrop, ar); } } } @@ -995,7 +999,9 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { @Unique private void vivecraft$doMixedRealityMirror() { // set viewport to fullscreen, since it would be still on the one from the last pass - RenderSystem.viewport(0, 0, window.getScreenWidth(), window.getScreenHeight()); + RenderSystem.viewport(0, 0, + ((WindowExtension) (Object) this.window).vivecraft$getActualScreenWidth(), + ((WindowExtension) (Object) this.window).vivecraft$getActualScreenHeight()); Vec3 camPlayer = ClientDataHolderVR.getInstance().vrPlayer.vrdata_room_pre.getHeadPivot() .subtract(ClientDataHolderVR.getInstance().vrPlayer.vrdata_room_pre.getEye(RenderPass.THIRD).getPosition()); diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/MouseHandlerVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/MouseHandlerVRMixin.java index a18d108af..e58525994 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/MouseHandlerVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/MouseHandlerVRMixin.java @@ -6,12 +6,12 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.*; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.VRState; +import org.vivecraft.client_vr.extensions.WindowExtension; +import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; import org.vivecraft.client_vr.provider.MCVR; @Mixin(MouseHandler.class) @@ -23,14 +23,6 @@ public class MouseHandlerVRMixin { @Shadow private Minecraft minecraft; - // TODO, this seems unnecessary, and wrong - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/Screen;mouseScrolled(DDD)Z", shift = At.Shift.BEFORE), method = "onScroll", cancellable = true) - public void vivecraft$cancelScroll(long g, double h, double f, CallbackInfo ci) { - if (this.minecraft.screen.mouseScrolled(g, h, f)) { - ci.cancel(); - } - } - @Redirect(method = "onPress", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z")) private boolean vivecraft$checkNull(LocalPlayer instance) { return instance != null && instance.isSpectator(); @@ -76,6 +68,21 @@ public class MouseHandlerVRMixin { } } + // we change the screen size different from window size, so need to modify the mouse position on grab/release + @ModifyArg(at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/InputConstants;grabOrReleaseMouse(JIDD)V"), index = 2, method = {"grabMouse", "releaseMouse"}) + public double vivecraft$modifyXCenter(double x) { + return VRState.vrRunning + ? (double) ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth() / 2 + : x; + } + + @ModifyArg(at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/platform/InputConstants;grabOrReleaseMouse(JIDD)V"), index = 3, method = {"grabMouse", "releaseMouse"}) + public double vivecraft$modifyYCenter(double y) { + return VRState.vrRunning + ? (double) ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight() / 2 + : y; + } + @Inject(at = @At(value = "HEAD"), method = "releaseMouse", cancellable = true) public void vivecraft$grabMouse(CallbackInfo ci) { if (!VRState.vrRunning) { @@ -87,4 +94,21 @@ public class MouseHandlerVRMixin { ci.cancel(); } } + + // we change the screen size different from window size, so adapt move events to the emulated size + @ModifyVariable(at = @At(value = "HEAD"), ordinal = 0, method = "onMove", argsOnly = true) + public double vivecraft$modifyX(double x) { + if (VRState.vrRunning) { + x *= GuiHandler.guiWidth / (double) ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenWidth(); + } + return x; + } + + @ModifyVariable(at = @At(value = "HEAD"), ordinal = 1, method = "onMove", argsOnly = true) + public double vivecraft$modifyY(double y) { + if (VRState.vrRunning) { + y *= (double) GuiHandler.guiHeight / (double) ((WindowExtension) (Object) minecraft.getWindow()).vivecraft$getActualScreenHeight(); + } + return y; + } } diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/blaze3d/platform/WindowVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/blaze3d/platform/WindowVRMixin.java index d44823722..eada80e87 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/blaze3d/platform/WindowVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/blaze3d/platform/WindowVRMixin.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.platform.Window; import net.minecraft.client.Minecraft; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -11,10 +12,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.VRState; +import org.vivecraft.client_vr.extensions.WindowExtension; import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; @Mixin(Window.class) -public abstract class WindowVRMixin { +public abstract class WindowVRMixin implements WindowExtension { + + @Shadow + private int width; + + @Shadow + private int height; // TODO: check if that actually works like that with sodium extras adaptive sync @ModifyVariable(method = "updateVsync", ordinal = 0, at = @At("HEAD"), argsOnly = true) @@ -25,7 +33,7 @@ public abstract class WindowVRMixin { return v; } - @Inject(method = {/*"getScreenWidth", */"getWidth"}, at = @At("HEAD"), cancellable = true) + @Inject(method = "getWidth", at = @At("HEAD"), cancellable = true) void vivecraft$getVivecraftWidth(CallbackInfoReturnable cir) { if (vivecraft$shouldOverrideSide()) { // if (mcxrGameRenderer.reloadingDepth > 0) { @@ -38,7 +46,7 @@ public abstract class WindowVRMixin { } } - @Inject(method = {/*"getScreenHeight",*/ "getHeight"}, at = @At("HEAD"), cancellable = true) + @Inject(method = "getHeight", at = @At("HEAD"), cancellable = true) void vivecraft$getVivecraftHeight(CallbackInfoReturnable cir) { if (vivecraft$shouldOverrideSide()) { // if (mcxrGameRenderer.reloadingDepth > 0) { @@ -51,24 +59,48 @@ public abstract class WindowVRMixin { } } + @Inject(method = "getScreenWidth", at = @At("HEAD"), cancellable = true) + void vivecraft$getVivecraftScreenWidth(CallbackInfoReturnable cir) { + if (vivecraft$shouldOverrideSide()) { + cir.setReturnValue(GuiHandler.guiWidth); + } + } + + @Inject(method = "getScreenHeight", at = @At("HEAD"), cancellable = true) + void vivecraft$getVivecraftScreenHeight(CallbackInfoReturnable cir) { + if (vivecraft$shouldOverrideSide()) { + cir.setReturnValue(GuiHandler.guiHeight); + } + } + + @Inject(method = "getGuiScaledHeight", at = @At("HEAD"), cancellable = true) void vivecraft$getScaledHeight(CallbackInfoReturnable cir) { if (vivecraft$shouldOverrideSide()) { - cir.setReturnValue(GuiHandler.scaledHeight); + cir.setReturnValue( + Minecraft.getInstance().screen == null && ClientDataHolderVR.getInstance().vrSettings.hudMaxScale + ? GuiHandler.scaledHeightMax + : GuiHandler.scaledHeight); } } @Inject(method = "getGuiScaledWidth", at = @At("HEAD"), cancellable = true) void vivecraft$getScaledWidth(CallbackInfoReturnable cir) { if (vivecraft$shouldOverrideSide()) { - cir.setReturnValue(GuiHandler.scaledWidth); + cir.setReturnValue( + Minecraft.getInstance().screen == null && ClientDataHolderVR.getInstance().vrSettings.hudMaxScale + ? GuiHandler.scaledWidthMax + : GuiHandler.scaledWidth); } } @Inject(method = "getGuiScale", at = @At("HEAD"), cancellable = true) void vivecraft$getScaleFactor(CallbackInfoReturnable cir) { if (vivecraft$shouldOverrideSide()) { - cir.setReturnValue((double) GuiHandler.guiScaleFactor); + cir.setReturnValue( + Minecraft.getInstance().screen == null && ClientDataHolderVR.getInstance().vrSettings.hudMaxScale + ? (double) GuiHandler.guiScaleFactorMax + : (double) GuiHandler.guiScaleFactor); } } @@ -84,4 +116,16 @@ public abstract class WindowVRMixin { //MCXR: return mcxrGameRenderer.overrideWindowSize || (mcxrGameRenderer.isXrMode() && mcxrGameRenderer.reloadingDepth > 0); return VRState.vrRunning; } + + @Override + @Unique + public int vivecraft$getActualScreenHeight() { + return height; + } + + @Override + @Unique + public int vivecraft$getActualScreenWidth() { + return width; + } } diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java index c82048ff7..3bedb873d 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/player/LocalPlayerVRMixin.java @@ -7,7 +7,6 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.player.Input; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.Packet; @@ -73,8 +72,6 @@ public abstract class LocalPlayerVRMixin extends AbstractClientPlayer implements private final ClientDataHolderVR vivecraft$dataholder = ClientDataHolderVR.getInstance(); @Shadow private InteractionHand usingItemHand; - @Shadow - public Input input; public LocalPlayerVRMixin(ClientLevel clientLevel, GameProfile gameProfile) { super(clientLevel, gameProfile); @@ -88,28 +85,28 @@ public LocalPlayerVRMixin(ClientLevel clientLevel, GameProfile gameProfile) { @Inject(at = @At("TAIL"), method = "startRiding") public void vivecraft$startRidingTracker(Entity entity, boolean bl, CallbackInfoReturnable cir) { - if (VRState.vrInitialized) { + if (VRState.vrInitialized && vivecraft$isLocalPlayer(this)) { ClientDataHolderVR.getInstance().vehicleTracker.onStartRiding(entity, (LocalPlayer) (Object) this); } } @Inject(at = @At("TAIL"), method = "removeVehicle") public void vivecraft$stopRidingTracker(CallbackInfo ci) { - if (VRState.vrInitialized) { + if (VRState.vrInitialized && vivecraft$isLocalPlayer(this)) { ClientDataHolderVR.getInstance().vehicleTracker.onStopRiding((LocalPlayer) (Object) this); } } @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;tick()V", shift = At.Shift.BEFORE), method = "tick") public void vivecraft$overrideLookPre(CallbackInfo ci) { - if (VRState.vrRunning) { + if (VRState.vrRunning && vivecraft$isLocalPlayer(this)) { ClientDataHolderVR.getInstance().vrPlayer.doPermanantLookOverride((LocalPlayer) (Object) this, ClientDataHolderVR.getInstance().vrPlayer.vrdata_world_pre); } } @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;tick()V", shift = At.Shift.AFTER), method = "tick") public void vivecraft$overridePose(CallbackInfo ci) { - if (VRState.vrRunning) { + if (VRState.vrRunning && vivecraft$isLocalPlayer(this)) { ClientNetworking.overridePose((LocalPlayer) (Object) this); ClientDataHolderVR.getInstance().vrPlayer.doPermanantLookOverride((LocalPlayer) (Object) this, ClientDataHolderVR.getInstance().vrPlayer.vrdata_world_pre); } @@ -157,14 +154,14 @@ public LocalPlayerVRMixin(ClientLevel clientLevel, GameProfile gameProfile) { @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/AbstractClientPlayer;aiStep()V"), method = "aiStep") public void vivecraft$ai(CallbackInfo ci) { - if (VRState.vrRunning) { + if (VRState.vrRunning && vivecraft$isLocalPlayer(this)) { this.vivecraft$dataholder.vrPlayer.tick((LocalPlayer) (Object) this, this.minecraft, this.random); } } @Inject(at = @At("HEAD"), method = "move(Lnet/minecraft/world/entity/MoverType;Lnet/minecraft/world/phys/Vec3;)V", cancellable = true) public void vivecraft$overwriteMove(MoverType pType, Vec3 pPos, CallbackInfo info) { - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { return; } @@ -249,7 +246,7 @@ public ItemStack eat(Level level, ItemStack itemStack) { @Override public void moveTo(double pX, double p_20109_, double pY, float p_20111_, float pZ) { super.moveTo(pX, p_20109_, pY, p_20111_, pZ); - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { return; } if (this.vivecraft$initFromServer) { @@ -260,7 +257,7 @@ public void moveTo(double pX, double p_20109_, double pY, float p_20111_, float @Override public void absMoveTo(double pX, double p_19892_, double pY, float p_19894_, float pZ) { super.absMoveTo(pX, p_19892_, pY, p_19894_, pZ); - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { return; } ClientDataHolderVR.getInstance().vrPlayer.snapRoomOriginToPlayerEntity((LocalPlayer) (Object) this, false, false); @@ -269,7 +266,7 @@ public void absMoveTo(double pX, double p_19892_, double pY, float p_19894_, flo @Override public void setPos(double pX, double p_20211_, double pY) { this.vivecraft$initFromServer = true; - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { super.setPos(pX, p_20211_, pY); return; } @@ -330,7 +327,7 @@ public void setPos(double pX, double p_20211_, double pY) { @Override public void moveRelative(float pAmount, Vec3 pRelative) { - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { super.moveRelative(pAmount, pRelative); return; } @@ -457,7 +454,7 @@ public void moveRelative(float pAmount, Vec3 pRelative) { @Override public void die(DamageSource pCause) { super.die(pCause); - if (!VRState.vrRunning) { + if (!VRState.vrRunning || !vivecraft$isLocalPlayer(this)) { return; } ClientDataHolderVR.getInstance().vr.triggerHapticPulse(0, 2000); @@ -534,7 +531,9 @@ public void die(DamageSource pCause) { @Override public void releaseUsingItem() { - ClientNetworking.sendActiveHand((byte) this.getUsedItemHand().ordinal()); + if (vivecraft$isLocalPlayer(this)) { + ClientNetworking.sendActiveHand((byte) this.getUsedItemHand().ordinal()); + } super.releaseUsingItem(); } @@ -563,4 +562,9 @@ public void releaseUsingItem() { public void vivecraft$setItemInUseCountClient(int count) { this.useItemRemaining = count; } + + @Unique + private boolean vivecraft$isLocalPlayer(Object player) { + return player.getClass().equals(LocalPlayer.class) || Minecraft.getInstance().player == player; + } } diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/GameRendererVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/GameRendererVRMixin.java index e29c50595..3fe4e515b 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/GameRendererVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/GameRendererVRMixin.java @@ -265,14 +265,14 @@ public abstract class GameRendererVRMixin this.vivecraft$minClipDistance, this.vivecraft$clipDistance)); } else if (vivecraft$DATA_HOLDER.currentPass == RenderPass.SCOPEL || vivecraft$DATA_HOLDER.currentPass == RenderPass.SCOPER) { - posestack.mulPoseMatrix(new Matrix4f().setPerspective(70f / 8f * 0.01745329238474369F, 1.0F, 0.05F, this.vivecraft$clipDistance)); + posestack.mulPoseMatrix(new Matrix4f().setPerspective(70f / 8f * 0.01745329238474369F, 1.0F, this.vivecraft$minClipDistance, this.vivecraft$clipDistance)); } else { if (this.zoom != 1.0F) { posestack.translate(this.zoomX, -this.zoomY, 0.0D); posestack.scale(this.zoom, this.zoom, 1.0F); } posestack.mulPoseMatrix(new Matrix4f().setPerspective((float) d * 0.01745329238474369F, (float) this.minecraft.getWindow().getScreenWidth() - / (float) this.minecraft.getWindow().getScreenHeight(), 0.05F, this.vivecraft$clipDistance)); + / (float) this.minecraft.getWindow().getScreenHeight(), this.vivecraft$minClipDistance, this.vivecraft$clipDistance)); } info.setReturnValue(posestack.last().pose()); } diff --git a/common/src/main/java/org/vivecraft/mod_compat_vr/modmenu/mixin/PauseScreenVRModMenuMixin.java b/common/src/main/java/org/vivecraft/mod_compat_vr/modmenu/mixin/PauseScreenVRModMenuMixin.java new file mode 100644 index 000000000..90620b56e --- /dev/null +++ b/common/src/main/java/org/vivecraft/mod_compat_vr/modmenu/mixin/PauseScreenVRModMenuMixin.java @@ -0,0 +1,52 @@ +package org.vivecraft.mod_compat_vr.modmenu.mixin; + +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.screens.PauseScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.contents.TranslatableContents; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.vivecraft.client_vr.VRState; + +@Mixin(PauseScreen.class) +public abstract class PauseScreenVRModMenuMixin extends Screen { + protected PauseScreenVRModMenuMixin(Component component) { + super(component); + } + + @Inject(at = @At("TAIL"), method = "init") + private void vivecraft$reduceModmenuButtonSize(CallbackInfo ci) { + if (VRState.vrInitialized) { + Button modmenuButton = null; + Button commandsButton = null; + Button reportBugsButton = null; + for (GuiEventListener guiEventListener : children()) { + if (guiEventListener instanceof Button button) { + if (button.getMessage().getContents() instanceof TranslatableContents contents + && "modmenu.title".equals(contents.getKey())) { + modmenuButton = button; + } else if (button.getMessage().getContents() instanceof TranslatableContents contents + && "vivecraft.gui.commands".equals(contents.getKey())) { + commandsButton = button; + } else if (button.getMessage().getContents() instanceof TranslatableContents contents + && "menu.reportBugs".equals(contents.getKey())) { + reportBugsButton = button; + } + } + } + + // make sure we found the buttons, and they are actually overlapping + if (reportBugsButton == null && modmenuButton != null && commandsButton != null + && modmenuButton.getX() == commandsButton.getX() + && modmenuButton.getY() == commandsButton.getY()) { + modmenuButton.setWidth(modmenuButton.getWidth() / 2 - 1); + commandsButton.setWidth(commandsButton.getWidth() / 2); + modmenuButton.setX(commandsButton.getX() + commandsButton.getWidth() + 1); + } + } + } +} diff --git a/common/src/main/resources/assets/vivecraft/lang/de_de.json b/common/src/main/resources/assets/vivecraft/lang/de_de.json index cd366e73a..474416349 100644 --- a/common/src/main/resources/assets/vivecraft/lang/de_de.json +++ b/common/src/main/resources/assets/vivecraft/lang/de_de.json @@ -12,7 +12,7 @@ "vivecraft.key.rotateFree": "Freies Drehen", "vivecraft.key.walkabout": "Rundgang", "vivecraft.key.teleport": "Teleportation", - "vivecraft.key.teleportFallback": "Forwärts gehen, wenn die Teleportation deaktiviert ist", + "vivecraft.key.teleportFallback": "Vorwärts, wenn Teleportation deaktiviert", "vivecraft.key.freeMoveRotate": "Bewegen/Drehen", "vivecraft.key.freeMoveStrafe": "Nur Bewegen", "vivecraft.key.toggleMovement": "Bewegungsart umschalten", @@ -68,6 +68,7 @@ "vivecraft.options.screen.standing": "Stehende Fortbewegungseinstellungen", "vivecraft.options.screen.teleport": "Teleportationseinstellungen", "vivecraft.options.screen.controls": "Controller-Einstellungen", + "vivecraft.options.screen.keyboard": "Tastatur-Einstellungen", "_comment5": "Buttons that lead to the screen", "vivecraft.options.screen.main.button": "VR Einstellungen...", "vivecraft.options.screen.gui.button": "Benutzeroberflächen Einst...", @@ -82,6 +83,7 @@ "vivecraft.options.screen.menuworld.button": "Menü-Welt Einstellungen...", "vivecraft.options.screen.teleport.button": "Teleporteinstellungen...", "vivecraft.options.screen.freemove.button": "Freie Bewegungseinst...", + "vivecraft.options.screen.keyboard.button": "Tastatur-Einstellungen...", "_comment6": "Option names", "vivecraft.options.HUD_SCALE": "Kopf-HUD Größe", "vivecraft.options.HUD_DISTANCE": "Kopf-HUD Entfernung", @@ -171,6 +173,7 @@ "vivecraft.options.HANDHELD_CAMERA_RENDER_SCALE": "Kamera Auflösung", "vivecraft.options.MIXED_REALITY_RENDER_CAMERA_MODEL": "Zeige Kameramodell", "vivecraft.options.PHYSICAL_KEYBOARD_THEME": "Tastatur Aussehen", + "vivecraft.options.KEYBOARD_PRESS_BINDS": "Tastatur aktiviert Bindungen", "_comment8": "Option tooltips", "vivecraft.options.HUD_SCALE.tooltip": "Die Relative Größe vom HUD im Sichtfeld.\nDie Einheiten sind relativ, nicht in Grad oder einem Bruchteil von FOV.", "vivecraft.options.HUD_DISTANCE.tooltip": "Abstand, den das schwebende HUD vom Körper weg angezeigt wird.\nDie relative Größe des HUDs bleibt dadurch unverändert.\nDer Abstand wird in Metern angegeben (wird aber nicht durch Blöcke versperrt).", @@ -258,6 +261,7 @@ "vivecraft.options.HANDHELD_CAMERA_RENDER_SCALE.tooltip": "Auflösung der Handheld-Screenshot-Kamera, für die Aufnahme von Screenshots, die viel größer als die normale Render-Auflösung sind.\nKann nicht verwendet werden, wenn Shader aktiviert sind.\n§cWARNUNG: Wenn Sie diesen Wert sehr hoch einstellen, kann der Computer schmelzen!", "vivecraft.options.MIXED_REALITY_RENDER_CAMERA_MODEL.tooltip": "Zeige das Modell einer Kamera (nur in HMD Ansicht) um anzuzeigen wo sich die Mixed Reality oder 3. Person Kamera derzeit befindet. Die Kamera kann auch durch das halten der Interaktionstaste bewegt werden.", "vivecraft.options.PHYSICAL_KEYBOARD_THEME.tooltip": "Voreinstellung des Farbschemas für die physische Tastatur. Das Aussehen kann durch das Bearbeiten der keyboardtheme.txt im Spielverzeichnis angepasst werden. Beim öffnen der Tastatur wird diese Datei neu geladen, um Echtzeitänderungen anzuzeigen.", + "vivecraft.options.KEYBOARD_PRESS_BINDS.tooltip": "Ob the Tastatur Tasten Bindungen aktivieren soll, wenn in die Luft getippt wird.\nSei Vorsichtig! Du könntest Sachen aktivieren, die du nicht wolltest.", "_comment10": "Option values", "vivecraft.options.gamma.cantseeshitcaptain": "Ich kann nichts sehen", "vivecraft.options.yes": "Ja", @@ -365,8 +369,9 @@ "vivecraft.messages.serverplugin": "Vivecraft Server Mod erkannt: %s", "vivecraft.messages.noserverplugin": "Vivecraft Server Mod nicht erkannt. Dieser Server unterstützt möglicherweise kein Teleportieren. Der eingeschränkte Bewegungsmodus (Fallback auf freie Bewegung) wurde aktiviert.", "vivecraft.messages.calibrateheight": "Bitte kalibrieren Sie Ihre Körpergröße im Pause Menü.", - "vivecraft.messages.rendersetupfailed": "Render Setup fehlgeschlagen: %s", - "vivecraft.messages.intelgraphics": "Intel Integrated Graphics werden nicht unterstützt. Wenn es sich um einen Laptop handelt, erzwingen Sie bitte die Hochleistungs-GPU. Erkannte GPU: %s", + "vivecraft.messages.rendersetupfailed": "Render Setup fehlgeschlagen: %s\nVR provider: %s", + "vivecraft.messages.intelgraphics1": "Intel Grafikkarten werden unter Windows nicht unterstützt, wegen fehlerhaften Treibern.\n\nMomentan verwendete Grafikkarte: %s\n\nVerfügbare Grafikkarten: %s\n\n%s", + "vivecraft.messages.intelgraphics2": "Siehe hier wie die verwendete Grafikkarte geändert werden kann: %s", "vivecraft.messages.nosteamvr": "OpenVR runtime nicht erkannt. Ist SteamVR installiert?", "vivecraft.messages.menuworldexportcomplete.1": "Weltexport abgeschlossen... Flächengröße: %d", "vivecraft.messages.menuworldexportcomplete.2": "Gespeichert unter %s", @@ -380,6 +385,7 @@ "vivecraft.messages.coords": "X: %.2f Y: %.2f Z: %.2f", "vivecraft.messages.angles": "Längsachse: %.1f Querachse: %.1f Vertikalachse: %.1f", "vivecraft.messages.heightset": "Körpergröße gesetzt auf %d%%", + "vivecraft.messages.airtypingwarning": "Du tipps ohne einen Bildschirm offen zu haben. Wenn du eine Tastenbindung aktivieren wolltest, aktiviere \"Tastatur aktiviert Bindungen\" in den VR Einstellungen.", "_comment_m": "mixin version exclusive strings", "_comment_m0": "Option values", @@ -398,6 +404,9 @@ "_comment_m5": "Option names", "vivecraft.options.LOW_HEALTH_INDICATOR": "Gesundheit Indikator", "vivecraft.options.SHADER_GUI_RENDER": "Shader GUI", + "vivecraft.options.DOUBLE_GUI_RESOLUTION": "1440p GUI", + "vivecraft.options.GUI_SCALE": "VR GUI Skalierung", + "vivecraft.options.HUD_MAX_GUI_SCALE": "HUD Maximale Skalierung", "vivecraft.options.FREEMOVE_FLY_MODE": "Frei Bewegen Fliegen", "vivecraft.options.SHOW_UPDATES": "Update Nachricht", "vivecraft.options.UPDATE_TYPE": "Updates", @@ -408,10 +417,13 @@ "vivecraft.options.VR_TOGGLE_BUTTON_VISIBLE": "VR Aktivierungsknopf Sichtbar", "vivecraft.options.VR_SETTINGS_BUTTON_VISIBLE": "VR Einstellungsknopf Sichtbar", "vivecraft.options.VR_SETTINGS_BUTTON_POSITION": "VR Einstellungsknopf Position", - "vivecraft.options.INGAME_BINDINGS_IN_GUI": "Im-Spiel Tatest im GUI", + "vivecraft.options.INGAME_BINDINGS_IN_GUI": "Im-Spiel Tasten im GUI", "_comment_m6": "Option tooltips", "vivecraft.options.LOW_HEALTH_INDICATOR.tooltip": "Pulsiert den Bildschirm Rot bei niedriger Gesundheit, um den derzeitigen Gesundheitszustand anzuzeigen.", "vivecraft.options.SHADER_GUI_RENDER.tooltip": "Bestimmt wie die Benutzeroberfläche mit Shadern dargestellt wird.\n Nach Shader: zeigt die Benutzeroberfläche ohne Shader, beste Kompatibilität. (Probleme mit PTGI HRR)\n Transparent: zeigt die Benutzeroberfläche mit Shadern und transparent. (Probleme mit Sildurs Vibrant)\n Undurchsichtig: zeigt die Benutzeroberfläche mit Shadern, aber Undurchsichtig", + "vivecraft.options.DOUBLE_GUI_RESOLUTION.tooltip": "Wenn dies eingeschalten ist, wird das GUI in 1440p dargestellt anstatt von 720p, welches die Schärfe enorm erhöht.\nKann mehr Leistung benötigen, bei Grafikkarten mit begrenzter Speicherbandbreite.", + "vivecraft.options.GUI_SCALE.tooltip": "Die anzuwendende GUI Skalierung, wenn VR aktiv ist.", + "vivecraft.options.HUD_MAX_GUI_SCALE.tooltip": "Wenn dies eingeschalten ist, wird das HUD immer die maximale GUI Skalierung verwenden, egal auf was 'VR GUI Skalierung' gestellt ist.", "vivecraft.options.VR_MODE.tooltip": "wechsle zwischen VR/NONVR", "vivecraft.options.FREEMOVE_FLY_MODE.tooltip": "Die Quelle für die Frei Bewegen-Richtung im Flugmodus.\n\n Auto: Verwendet die gleiche richtung wie das normale Frei Bewegen.\n Controller: Richtung des nicht dominanten Controllers.\n HMD: Blickrichtung des Headsets.", "vivecraft.options.SHOW_UPDATES.tooltip": "Wie oft eine Update Nachricht im Chat gezeigt werden soll.\n Immer: zeigt die Nachricht immer, wenn eine Welt geladen wird.\n Einmal: Zeigt die Nachricht einmal, wenn ein neues Update verfügbar ist.", diff --git a/common/src/main/resources/assets/vivecraft/lang/en_ca.json b/common/src/main/resources/assets/vivecraft/lang/en_ca.json index e763f23d5..5d32709a8 100644 --- a/common/src/main/resources/assets/vivecraft/lang/en_ca.json +++ b/common/src/main/resources/assets/vivecraft/lang/en_ca.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Vivecraft server mod detected: %s", "vivecraft.messages.noserverplugin": "Vivecraft server mod not detected. This server may not support teleporting. Restricted movement mode (fallback to free move) has been enabled.", "vivecraft.messages.calibrateheight": "Please calibrate your height in the pause menu.", - "vivecraft.messages.rendersetupfailed": "Render setup failed: %s", + "vivecraft.messages.rendersetupfailed": "Render setup failed: %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "Intel Integrated Graphics are not supported. If this is a laptop, please force the high-performance GPU. Detected GPU: %s", "vivecraft.messages.nosteamvr": "OpenVR runtime not detected. Did you install SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "World export complete... area size: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/en_gb.json b/common/src/main/resources/assets/vivecraft/lang/en_gb.json index 074d32562..5873b0d09 100644 --- a/common/src/main/resources/assets/vivecraft/lang/en_gb.json +++ b/common/src/main/resources/assets/vivecraft/lang/en_gb.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Vivecraft server mod detected: %s", "vivecraft.messages.noserverplugin": "Vivecraft server mod not detected. This server may not support teleporting. Restricted movement mode (fallback to free move) has been enabled.", "vivecraft.messages.calibrateheight": "Please calibrate your height in the pause menu.", - "vivecraft.messages.rendersetupfailed": "Render setup failed: %s", + "vivecraft.messages.rendersetupfailed": "Render setup failed: %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "Intel Integrated Graphics are not supported. If this is a laptop, please force the high-performance GPU. Detected GPU: %s", "vivecraft.messages.nosteamvr": "OpenVR runtime not detected. Did you install SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "World export complete... area size: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/en_us.json b/common/src/main/resources/assets/vivecraft/lang/en_us.json index 8530533b3..e7272ae59 100644 --- a/common/src/main/resources/assets/vivecraft/lang/en_us.json +++ b/common/src/main/resources/assets/vivecraft/lang/en_us.json @@ -67,6 +67,7 @@ "vivecraft.options.screen.standing": "Standing Locomotion Settings", "vivecraft.options.screen.teleport": "Teleport Settings", "vivecraft.options.screen.controls": "Controller Settings", + "vivecraft.options.screen.keyboard": "Keyboard Settings", "_comment4": "Buttons that lead to the screen", "vivecraft.options.screen.main.button": "VR Settings...", "vivecraft.options.screen.gui.button": "HUD and GUI Settings...", @@ -81,6 +82,7 @@ "vivecraft.options.screen.menuworld.button": "Menu World Settings...", "vivecraft.options.screen.teleport.button": "Teleport Settings...", "vivecraft.options.screen.freemove.button": "Free Move Settings...", + "vivecraft.options.screen.keyboard.button": "Keyboard Settings...", "_comment5": "Option names", "vivecraft.options.HUD_SCALE": "Head HUD Size", "vivecraft.options.HUD_DISTANCE": "Head HUD Distance", @@ -170,6 +172,7 @@ "vivecraft.options.HANDHELD_CAMERA_RENDER_SCALE": "Camera Resolution", "vivecraft.options.MIXED_REALITY_RENDER_CAMERA_MODEL": "Show Camera Model", "vivecraft.options.PHYSICAL_KEYBOARD_THEME": "Keyboard Theme", + "vivecraft.options.KEYBOARD_PRESS_BINDS": "Keyboard Presses Bindings", "_comment6": "Option tooltips", "vivecraft.options.HUD_SCALE.tooltip": "Relative size HUD takes up in field-of-view.\nThe units are just relative, not in degrees or a fraction of FOV or anything.", "vivecraft.options.HUD_DISTANCE.tooltip": "Distance the floating HUD is drawn in front of your body.\nThe relative size of the HUD is unchanged by this.\nDistance is in meters (though isn't obstructed by blocks).", @@ -257,6 +260,7 @@ "vivecraft.options.HANDHELD_CAMERA_RENDER_SCALE.tooltip": "Resolution of the handheld screenshot camera, for taking screenshots much larger than normal render resolution.\nCannot be used when shaders are enabled.\n§cWARNING: Setting this very high may melt your computer!", "vivecraft.options.MIXED_REALITY_RENDER_CAMERA_MODEL.tooltip": "Show model of a video camera (only in HMD view) to represent where the mixed reality or third person camera is currently located. It can also be grabbed to move it around using the interact binding.", "vivecraft.options.PHYSICAL_KEYBOARD_THEME.tooltip": "Color scheme preset for the physical keyboard. Custom theme can be edited via keyboardtheme.txt in the game directory. It will be reloaded every time the keyboard is opened, to allow real-time tweaking.", + "vivecraft.options.KEYBOARD_PRESS_BINDS.tooltip": "Whether the keyboard should activate key bindings when typing into thin air.\nBe careful! You might activate things you don't intend to.", "_comment7": "Option values", "vivecraft.options.gamma.cantseeshitcaptain": "I Can't See", "vivecraft.options.yes": "YES", @@ -364,8 +368,9 @@ "vivecraft.messages.serverplugin": "Vivecraft server mod detected: %s", "vivecraft.messages.noserverplugin": "Vivecraft server mod not detected. This server may not support teleporting. Restricted movement mode (fallback to free move) has been enabled.", "vivecraft.messages.calibrateheight": "Please calibrate your height in the pause menu.", - "vivecraft.messages.rendersetupfailed": "Render setup failed: %s", - "vivecraft.messages.intelgraphics": "Intel Integrated Graphics are not supported. If this is a laptop, please force the high-performance GPU. Detected GPU: %s", + "vivecraft.messages.rendersetupfailed": "Render setup failed: %s\nVR provider: %s", + "vivecraft.messages.intelgraphics1": "Intel Graphics are not supported on Windows because of bad drivers.\n\nCurrently used GPU: %s\n\nAvailable GPUs: %s\n\n%s", + "vivecraft.messages.intelgraphics2": "See here how to change the used gpu: %s", "vivecraft.messages.nosteamvr": "OpenVR runtime not detected. Did you install SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "World export complete... area size: %d", "vivecraft.messages.menuworldexportcomplete.2": "Saved to %s", @@ -379,6 +384,7 @@ "vivecraft.messages.coords": "X: %.2f Y: %.2f Z: %.2f", "vivecraft.messages.angles": "Pitch: %.1f Yaw: %.1f Roll: %.1f", "vivecraft.messages.heightset": "User height set to %d%%", + "vivecraft.messages.airtypingwarning": "You are typing without a screen open. If you're trying to use key bindings, enable \"Keyboard Presses Bindings\" in the VR settings.", "_comment_m": "mixin version exclusive strings", "vivecraft.options.screen.settings": "Vivecraft Settings", @@ -401,6 +407,9 @@ "_comment_m5": "Option names", "vivecraft.options.LOW_HEALTH_INDICATOR": "Health Indicator", "vivecraft.options.SHADER_GUI_RENDER": "Shaders GUI", + "vivecraft.options.DOUBLE_GUI_RESOLUTION": "1440p GUI", + "vivecraft.options.GUI_SCALE": "VR GUI Scale", + "vivecraft.options.HUD_MAX_GUI_SCALE": "HUD Max Scale", "vivecraft.options.FREEMOVE_FLY_MODE": "Free Move Flying", "vivecraft.options.SHOW_UPDATES": "Update Message", "vivecraft.options.UPDATE_TYPE": "Updates", @@ -415,6 +424,9 @@ "_comment_m6": "Option tooltips", "vivecraft.options.LOW_HEALTH_INDICATOR.tooltip": "Pulses the screen red, when at low health, to indicate your current health status", "vivecraft.options.SHADER_GUI_RENDER.tooltip": "Determines how the GUI is rendered with shaders.\n After Shader: renders the GUI without using the shader, best compatibility. (issues with PTGI HRR)\n Translucent: renders the GUI with shader and transparency. (issues with Sildurs Vibrant)\n Opaque: renders the GUI with shader and opaque", + "vivecraft.options.DOUBLE_GUI_RESOLUTION.tooltip": "If enabled, GUIs will be rendered at 1440p instead of 720p, greatly increasing sharpness.\nMay be more resource intensive on GPUs with limited memory bandwidth.", + "vivecraft.options.GUI_SCALE.tooltip": "The GUI scale to apply when VR is active.", + "vivecraft.options.HUD_MAX_GUI_SCALE.tooltip": "If enabled, the HUD will use max GUI Scale, regardless of what is set as 'VR GUI Scale'.", "vivecraft.options.VR_MODE.tooltip": "change between VR/NONVR", "vivecraft.options.FREEMOVE_FLY_MODE.tooltip": "The source for freemove direction when flying.\n\n Auto: uses the same direction as regular Freemove.\n Controller: Offhand controller pointing direction.\n HMD: Headset look direction.", "vivecraft.options.SHOW_UPDATES.tooltip": "How often an update message should show up in chat.\n Always: Shows the update message each time a world is loaded.\n Once: Shows the update message only on the first world load after a new update is out.", diff --git a/common/src/main/resources/assets/vivecraft/lang/es_es.json b/common/src/main/resources/assets/vivecraft/lang/es_es.json index c6df045e7..b6b54ea08 100644 --- a/common/src/main/resources/assets/vivecraft/lang/es_es.json +++ b/common/src/main/resources/assets/vivecraft/lang/es_es.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Detectado mod de servidor Vivecraft: %s", "vivecraft.messages.noserverplugin": "Mod de servidor Vivecraft no detectado. Este servidor podría no soportar teletransporte. Se ha activado el Movimiento Restringido (alternativa a movimiento libre).", "vivecraft.messages.calibrateheight": "Por favor calibra tu altura en el menú de pausa.", - "vivecraft.messages.rendersetupfailed": "Inicialización de Renderizado fallida: %s", + "vivecraft.messages.rendersetupfailed": "Inicialización de Renderizado fallida: %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "No se soporta las Gráficas Integradas de Intel. Si estás usando un portátil, por favor use la GPU de gran-rendimiento. GPU Detectada: %s", "vivecraft.messages.nosteamvr": "Componente OpenVR no detectado. ¿Ha instalado SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "Exportación de Mundo completada... tamaño de área: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/fr_fr.json b/common/src/main/resources/assets/vivecraft/lang/fr_fr.json index 8d0469e15..c66c562c4 100644 --- a/common/src/main/resources/assets/vivecraft/lang/fr_fr.json +++ b/common/src/main/resources/assets/vivecraft/lang/fr_fr.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Mod/Plugin Vivecraft détecté sur le serveur: %s", "vivecraft.messages.noserverplugin": "Vivecraft pour serveurs non détecté. Ce serveur pourrait ne pas supporter la téléportation. Dans le doute, on va restreindre vos déplacements. Ne le prenez pas mal hein, c'est pas contre vous.", "vivecraft.messages.calibrateheight": "Calibrez votre hauteur dans le menu pause.", - "vivecraft.messages.rendersetupfailed": "Erreur d'affichage! (Render setup failed: %s) ", + "vivecraft.messages.rendersetupfailed": "Erreur d'affichage! (Render setup failed: %s\nVR provider: %s) ", "vivecraft.messages.intelgraphics": "Les graphismes intégrés d'Intel ne sont pas supportés. Si ceci est un PC portable, veuillez forcer l'utilisation de la carte vidéo. Carte vidéo détectée: %s", "vivecraft.messages.nosteamvr": "Runtime d'OpenVR non détecté, avez vous installé SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "Exportation du monde finie... Taille de la zone: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/nl_nl.json b/common/src/main/resources/assets/vivecraft/lang/nl_nl.json index b55928c7b..8b11bc9a4 100644 --- a/common/src/main/resources/assets/vivecraft/lang/nl_nl.json +++ b/common/src/main/resources/assets/vivecraft/lang/nl_nl.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Vivecraft-servermod gedetecteerd: %s", "vivecraft.messages.noserverplugin": "Vivecraft-servermod niet gedetecteerd. Deze server biedt mogelijk geen ondersteuning voor teleporteren. De beperkte bewegingsmodus (terugvallen op vrije beweging) is ingeschakeld.", "vivecraft.messages.calibrateheight": "Kalibreer uw lengte in het pauzemenu.", - "vivecraft.messages.rendersetupfailed": "Installatie van weergave mislukt: %s", + "vivecraft.messages.rendersetupfailed": "Installatie van weergave mislukt: %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "Intel Integrated Graphics wordt niet ondersteund. Als dit een laptop is, forceer dan de krachtige GPU. Gedetecteerde GPU: %s", "vivecraft.messages.nosteamvr": "OpenVR runtime niet gedetecteerd. Heb je SteamVR geïnstalleerd?", "vivecraft.messages.menuworldexportcomplete.1": "Wereld export compleet ... gebiedsgrootte: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/pl_pl.json b/common/src/main/resources/assets/vivecraft/lang/pl_pl.json index 5b9536d19..e46711dcd 100644 --- a/common/src/main/resources/assets/vivecraft/lang/pl_pl.json +++ b/common/src/main/resources/assets/vivecraft/lang/pl_pl.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Wykryto serwerowy mod Vivecraft: %s", "vivecraft.messages.noserverplugin": "Nie wykryto serwerowego moda Vivecraft. Ten serwer moze nie wspierać teleportacji. Restrykcyjny tryb ruchu włączony (rezerwa do swobodnego ruchu).", "vivecraft.messages.calibrateheight": "Proszę skalibruj swoją wysokość w menu.", - "vivecraft.messages.rendersetupfailed": "Renderowanie nie powiodło się %s", + "vivecraft.messages.rendersetupfailed": "Renderowanie nie powiodło się %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "Zintegrowana grafika Intela nie jest wspierana. Jeśli to jest laptop, wymuś użycie wysokiej wydajności GPU. Wykryte GPU: %s", "vivecraft.messages.nosteamvr": "OpenVR nie zostało wykryte. Zainstalowałeś SteamVR? ", "vivecraft.messages.menuworldexportcomplete.1": "Export świata pomyślny... rozmiar strefy: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/ru_ru.json b/common/src/main/resources/assets/vivecraft/lang/ru_ru.json index bcab15884..9e9d36a41 100644 --- a/common/src/main/resources/assets/vivecraft/lang/ru_ru.json +++ b/common/src/main/resources/assets/vivecraft/lang/ru_ru.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "Vivecraft обнаружил серверный мод: %s", "vivecraft.messages.noserverplugin": "Vivecraft не обнаружен. Этот сервер может не поддерживать телепортацию. Включен режим ограниченного передвижения (возврат к свободному перемещению).", "vivecraft.messages.calibrateheight": "Пожалуйста, откаллибруйте высоту в меню паузы.", - "vivecraft.messages.rendersetupfailed": "Ошибка рендера: %s", + "vivecraft.messages.rendersetupfailed": "Ошибка рендера: %s\nVR provider: %s", "vivecraft.messages.intelgraphics": "Интегрированная графика Intel не поддерживается. Если это ноутбук, пожалуйста, установите высокопроизводительный GPU. Найденное GPU: %s", "vivecraft.messages.nosteamvr": "OpenVR не обнаружен. Вы установили SteamVR?", "vivecraft.messages.menuworldexportcomplete.1": "Экспорт завершен... размер области: %d", diff --git a/common/src/main/resources/assets/vivecraft/lang/zh_cn.json b/common/src/main/resources/assets/vivecraft/lang/zh_cn.json index ba49bc840..3d35c4e12 100644 --- a/common/src/main/resources/assets/vivecraft/lang/zh_cn.json +++ b/common/src/main/resources/assets/vivecraft/lang/zh_cn.json @@ -363,7 +363,7 @@ "vivecraft.messages.serverplugin": "检测到Vivecraft服务器适应插件(MOD)%s", "vivecraft.messages.noserverplugin": "没有检测到Vivecraft服务器适应插件(MOD),这个服务器也许不支持使用传送移动!已启用有限移动模式!(如果完全无法传送,将切换到备用的自由移动模式!)", "vivecraft.messages.calibrateheight": "请在按下菜单键呼出的暂停菜单中校准您的身高。", - "vivecraft.messages.rendersetupfailed": "客户端启动/渲染失败(Render setup failed):%s", + "vivecraft.messages.rendersetupfailed": "客户端启动/渲染失败(Render setup failed):%s\nVR provider: %s", "vivecraft.messages.intelgraphics": "不支持Intel核芯显卡!如果你使用的使笔记本电脑,请在设置中强制JAVA程序使用“高性能GPU”!已检测到的GPU有:%s", "vivecraft.messages.nosteamvr": "未检测到OpenVR. 您安装SteamVR了吗?", "vivecraft.messages.menuworldexportcomplete.1": "世界文件导出完成!区域大小:%d", diff --git a/common/src/main/resources/vivecraft.modmenu.mixins.json b/common/src/main/resources/vivecraft.modmenu.mixins.json new file mode 100644 index 000000000..6c590ae41 --- /dev/null +++ b/common/src/main/resources/vivecraft.modmenu.mixins.json @@ -0,0 +1,10 @@ +{ + "required": false, + "package": "org.vivecraft.mod_compat_vr.modmenu.mixin", + "plugin": "org.vivecraft.MixinConfig", + "compatibilityLevel": "JAVA_17", + "client": [ + "PauseScreenVRModMenuMixin" + ], + "minVersion": "0.8.4" +} diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 5de6b87d8..9e9e81145 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -34,8 +34,10 @@ "vivecraft.sodium.mixins.json", "vivecraft.fabric.sodium.mixins.json", "vivecraft.iris.mixins.json", + "vivecraft.modmenu.mixins.json", "vivecraft.physicsmod.mixins.json", "vivecraft.rei.mixins.json", + "vivecraft.resolutioncontrol.mixins.json", "vivecraft.fabric.mixins.json" ], "depends": { diff --git a/gradle.properties b/gradle.properties index 9f92f24a2..86584bd06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ minecraft_version=1.20.1 enabled_platforms=fabric,forge archives_base_name=vivecraft -mod_version=1.1.2 +mod_version=1.1.3 maven_group=org.vivecraft architectury_version=9.0.5