Compare commits

...

2 Commits

Author SHA1 Message Date
Martin Prokoph
f263908f5f fix: multiple touch-related bug fixes 2025-05-08 00:08:27 +02:00
Martin Prokoph
28de7312f8 fix: get touchscreen controls working again 2025-05-07 15:08:52 +02:00
9 changed files with 55 additions and 18 deletions

View File

@@ -89,8 +89,8 @@ public class MidnightControlsClient extends MidnightControls {
public void run() { public void run() {
try { try {
if (lateInitDone && client.isRunning()) { if (lateInitDone && client.isRunning()) {
if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) { if (MidnightControlsConfig.controlsMode != ControlsMode.DEFAULT && (client.isWindowFocused() || MidnightControlsConfig.unfocusedInput)) {
input.tickCameraStick(); if (MidnightControlsConfig.controlsMode == ControlsMode.CONTROLLER) input.tickCameraStick();
input.updateCamera(); input.updateCamera();
} }
} }

View File

@@ -0,0 +1,14 @@
package eu.midnightdust.midnightcontrols.client.mixin;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.WorldView;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(AbstractBlock.class)
public interface AbstractBlockAccessor {
@Invoker("canPlaceAt")
boolean midnightcontrols$canPlaceAt(BlockState state, WorldView world, BlockPos pos);
}

View File

@@ -44,7 +44,7 @@ public abstract class GameRendererMixin {
drawContext.draw(); drawContext.draw();
} }
@Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z"), method = "renderWorld") @Inject(at = @At(value = "FIELD", target = "Lnet/minecraft/client/render/GameRenderer;renderHand:Z"), method = "renderWorld")
private void midnigtcontrols$captureMatrices(RenderTickCounter tickCounter, CallbackInfo ci, @Local(ordinal = 1) Matrix4f matrices) { private void midnigtcontrols$captureMatrices(RenderTickCounter tickCounter, CallbackInfo ci, @Local(ordinal = 2) Matrix4f matrices) {
TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix()); TouchUtils.lastProjMat.set(RenderSystem.getProjectionMatrix());
TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix()); TouchUtils.lastModMat.set(RenderSystem.getModelViewMatrix());
TouchUtils.lastWorldSpaceMatrix.set(matrices); TouchUtils.lastWorldSpaceMatrix.set(matrices);

View File

@@ -28,6 +28,7 @@ import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.profiler.Profiler;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
@@ -38,6 +39,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.client;
import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.reacharound; import static eu.midnightdust.midnightcontrols.client.MidnightControlsClient.reacharound;
@Mixin(MinecraftClient.class) @Mixin(MinecraftClient.class)
@@ -54,6 +56,10 @@ public abstract class MinecraftClientMixin {
@Shadow public abstract void setScreen(Screen screen); @Shadow public abstract void setScreen(Screen screen);
@Shadow public int attackCooldown;
@Shadow protected abstract void handleInputEvents();
@Unique private BlockPos midnightcontrols$lastTargetPos; @Unique private BlockPos midnightcontrols$lastTargetPos;
@Unique private Vec3d midnightcontrols$lastPos; @Unique private Vec3d midnightcontrols$lastPos;
@Unique private Direction midnightcontrols$lastTargetSide; @Unique private Direction midnightcontrols$lastTargetSide;
@@ -144,10 +150,21 @@ public abstract class MinecraftClientMixin {
} }
} }
} }
// This is always supposed to be located at before the line 'this.profiler.swap("Keybindings");' // TODO: Replace this with MixinExtras' Expressions once that's officially released
// @Redirect(method = "tick", at = @At(value = "FIELD",target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;", ordinal = 6)) @Inject(method = "tick", at = @At(value = "INVOKE",target = "Lnet/minecraft/client/gui/hud/DebugHud;shouldShowDebugHud()Z"))
// private Screen midnightcontrols$ignoreTouchOverlay(MinecraftClient instance) { private void midnightcontrols$handleKeybindsWithTouchOverlay(CallbackInfo ci, @Local Profiler profiler) {
// if (instance.currentScreen instanceof TouchscreenOverlay) return null; if (client.currentScreen instanceof TouchscreenOverlay) {
// return instance.currentScreen; profiler.swap("Keybindings");
// } this.handleInputEvents();
if (this.attackCooldown > 0) {
--this.attackCooldown;
}
}
}
// Needed, as it will cause item actions not to work in touchscreen mode otherwise with the above method
@Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"), cancellable = true)
private void midnightcontrols$dontHandleItemAndBlockInteractions(CallbackInfo ci) {
if (client.currentScreen instanceof TouchscreenOverlay) ci.cancel();
}
} }

View File

@@ -78,6 +78,7 @@ public abstract class MouseMixin implements MouseAccessor {
int slotX = centerX - 90 + slot * 20 + 2; int slotX = centerX - 90 + slot * 20 + 2;
if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) { if (mouseX >= (double) slotX && mouseX <= (double) (slotX + 20)) {
client.player.getInventory().setSelectedSlot(slot); client.player.getInventory().setSelectedSlot(slot);
TouchInput.clickStartTime = -1;
ci.cancel(); ci.cancel();
return; return;
} }

View File

@@ -38,7 +38,7 @@ public class TouchUtils {
if (entityCast != null && entityCast.getType() == HitResult.Type.ENTITY) return entityCast; if (entityCast != null && entityCast.getType() == HitResult.Type.ENTITY) return entityCast;
BlockHitResult result = client.world.raycast(new RaycastContext(near, far, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.ANY, client.player)); BlockHitResult result = client.world.raycast(new RaycastContext(near, far, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, client.player));
if (client.player.getPos().distanceTo(result.getPos()) > playerRange) return null; if (client.player.getPos().distanceTo(result.getPos()) > playerRange) return null;
return result; return result;

View File

@@ -1,5 +1,6 @@
package eu.midnightdust.midnightcontrols.client.touch.gui; package eu.midnightdust.midnightcontrols.client.touch.gui;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
import org.thinkingstudio.obsidianui.Position; import org.thinkingstudio.obsidianui.Position;
import org.thinkingstudio.obsidianui.widget.SpruceTexturedButtonWidget; import org.thinkingstudio.obsidianui.widget.SpruceTexturedButtonWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@@ -34,6 +35,7 @@ public class SilentTexturedButtonWidget extends SpruceTexturedButtonWidget {
public void onClick(double mouseX, double mouseY) { public void onClick(double mouseX, double mouseY) {
this.setActive(true); this.setActive(true);
super.onClick(mouseX, mouseY); super.onClick(mouseX, mouseY);
TouchInput.clickStartTime = -1;
this.setActive(false); this.setActive(false);
} }
} }

View File

@@ -9,8 +9,10 @@
package eu.midnightdust.midnightcontrols.client.touch.gui; package eu.midnightdust.midnightcontrols.client.touch.gui;
import eu.midnightdust.midnightcontrols.client.mixin.KeyBindingIDAccessor;
import eu.midnightdust.midnightcontrols.client.touch.TouchInput; import eu.midnightdust.midnightcontrols.client.touch.TouchInput;
import eu.midnightdust.midnightcontrols.client.util.storage.AxisStorage; import eu.midnightdust.midnightcontrols.client.util.storage.AxisStorage;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen; import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.screen.GameMenuScreen; import net.minecraft.client.gui.screen.GameMenuScreen;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@@ -298,7 +300,13 @@ public class TouchscreenOverlay extends Screen {
if (binding == null) continue; if (binding == null) continue;
boolean hasTexture = client.getGuiAtlasManager().getSprite(id("binding/"+bindName)) != missingSprite; boolean hasTexture = client.getGuiAtlasManager().getSprite(id("binding/"+bindName)) != missingSprite;
if (MidnightControlsConfig.debug) System.out.println(left +" "+id("binding/"+bindName)+" "+ hasTexture); if (MidnightControlsConfig.debug) System.out.println(left +" "+id("binding/"+bindName)+" "+ hasTexture);
var button = TextIconButtonWidget.builder(Text.translatable(binding.getTranslationKey()), b -> binding.handle(client, 1, ButtonState.PRESS), hasTexture) var button = TextIconButtonWidget.builder(Text.translatable(binding.getTranslationKey()), b -> {
binding.handle(client, 1.0f, ButtonState.PRESS);
if (binding.asKeyBinding().isPresent()) {
binding.asKeyBinding().get().setPressed(true);
((KeyBindingAccessor)binding.asKeyBinding().get()).midnightcontrols$press();
}
}, hasTexture)
.texture(hasTexture ? id("binding/"+bindName) : emptySprite, 20, 20).dimension(20, 20).build(); .texture(hasTexture ? id("binding/"+bindName) : emptySprite, 20, 20).dimension(20, 20).build();
button.setPosition(left ? (3+(i*23)) : this.width-(23+(i*23)), 3); button.setPosition(left ? (3+(i*23)) : this.width-(23+(i*23)), 3);
button.setAlpha(MidnightControlsConfig.touchTransparency / 100f); button.setAlpha(MidnightControlsConfig.touchTransparency / 100f);
@@ -359,10 +367,4 @@ public class TouchscreenOverlay extends Screen {
} }
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
} }
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
KeyBinding.onKeyPressed(InputUtil.fromKeyCode(keyCode, scanCode));
super.keyPressed(keyCode,scanCode,modifiers);
return true;
}
} }

View File

@@ -24,7 +24,8 @@
"RecipeBookWidgetAccessor", "RecipeBookWidgetAccessor",
"ScreenMixin", "ScreenMixin",
"TabNavigationWidgetAccessor", "TabNavigationWidgetAccessor",
"WorldRendererMixin" "WorldRendererMixin",
"AbstractBlockAccessor"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1