86 lines
3.9 KiB
Java
86 lines
3.9 KiB
Java
|
|
package moe.nea.firmament.init;
|
|
|
|
import me.shedaniel.mm.api.ClassTinkerers;
|
|
import net.minecraft.client.gui.screen.Screen;
|
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
|
import org.objectweb.asm.Opcodes;
|
|
import org.objectweb.asm.Type;
|
|
import org.objectweb.asm.tree.ClassNode;
|
|
import org.objectweb.asm.tree.InsnList;
|
|
import org.objectweb.asm.tree.InsnNode;
|
|
import org.objectweb.asm.tree.JumpInsnNode;
|
|
import org.objectweb.asm.tree.LabelNode;
|
|
import org.objectweb.asm.tree.LdcInsnNode;
|
|
import org.objectweb.asm.tree.MethodInsnNode;
|
|
import org.objectweb.asm.tree.MethodNode;
|
|
import org.objectweb.asm.tree.VarInsnNode;
|
|
|
|
import java.lang.reflect.Modifier;
|
|
|
|
public class HandledScreenRiser extends RiserUtils {
|
|
@IntermediaryName(net.minecraft.client.gui.screen.Screen.class)
|
|
String Screen;
|
|
@IntermediaryName(net.minecraft.client.gui.screen.ingame.HandledScreen.class)
|
|
String HandledScreen;
|
|
Type mouseScrolledDesc = Type.getMethodType(Type.BOOLEAN_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE);
|
|
String mouseScrolled = remapper.mapMethodName("intermediary", "net.minecraft.class_364", "method_25401",
|
|
mouseScrolledDesc.getDescriptor());
|
|
|
|
@Override
|
|
public void addTinkerers() {
|
|
ClassTinkerers.addTransformation(HandledScreen, this::handle);
|
|
}
|
|
|
|
void handle(ClassNode classNode) {
|
|
MethodNode mouseScrolledNode = findMethod(classNode, mouseScrolled, mouseScrolledDesc);
|
|
if (mouseScrolledNode == null) {
|
|
mouseScrolledNode = new MethodNode(
|
|
Modifier.PUBLIC,
|
|
mouseScrolled,
|
|
mouseScrolledDesc.getDescriptor(),
|
|
null,
|
|
new String[0]
|
|
);
|
|
var insns = mouseScrolledNode.instructions;
|
|
// ALOAD 0, load this
|
|
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
|
|
// DLOAD 1-4, load the 4 argument doubles. Note that since doubles are two entries wide we skip 2 each time.
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 1));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 3));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 5));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 7));
|
|
// INVOKESPECIAL call super method
|
|
insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, getTypeForClassName(Screen).getInternalName(), mouseScrolled, mouseScrolledDesc.getDescriptor()));
|
|
// IRETURN return int on stack (booleans are int at runtime)
|
|
insns.add(new InsnNode(Opcodes.IRETURN));
|
|
classNode.methods.add(mouseScrolledNode);
|
|
}
|
|
|
|
var insns = new InsnList();
|
|
// ALOAD 0, load this
|
|
insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
|
|
// DLOAD 1-4, load the 4 argument doubles. Note that since doubles are two entries wide we skip 2 each time.
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 1));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 3));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 5));
|
|
insns.add(new VarInsnNode(Opcodes.DLOAD, 7));
|
|
// INVOKEVIRTUAL call custom handler
|
|
insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
|
|
getTypeForClassName(HandledScreen).getInternalName(),
|
|
"mouseScrolled_firmament",
|
|
mouseScrolledDesc.getDescriptor()));
|
|
// Create jump target (but not insert it yet)
|
|
var jumpIfFalse = new LabelNode();
|
|
// IFEQ (if returned boolean == 0), jump to jumpIfFalse
|
|
insns.add(new JumpInsnNode(Opcodes.IFEQ, jumpIfFalse));
|
|
// LDC 1 (as int, which is what booleans are at runtime)
|
|
insns.add(new LdcInsnNode(1));
|
|
// IRETURN return int on stack (booleans are int at runtime)
|
|
insns.add(new InsnNode(Opcodes.IRETURN));
|
|
insns.add(jumpIfFalse);
|
|
mouseScrolledNode.instructions.insert(insns);
|
|
}
|
|
|
|
}
|