diff --git a/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java b/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java index dac9dde9..743815c4 100644 --- a/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java +++ b/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java @@ -1,95 +1 @@ -//#if MC<=10710 -//$$ package com.replaymod.core.asm; -//$$ -//$$ import net.minecraft.launchwrapper.IClassTransformer; -//$$ import org.lwjgl.opengl.GL11; -//$$ import org.lwjgl.util.glu.GLU; -//$$ import org.objectweb.asm.ClassReader; -//$$ import org.objectweb.asm.ClassVisitor; -//$$ import org.objectweb.asm.ClassWriter; -//$$ import org.objectweb.asm.MethodVisitor; -//$$ import org.objectweb.asm.Opcodes; -//$$ -//$$ /** -//$$ * Insert glGetError checks after all calls to any method in any GL*, ARB* and EXT* classes -//$$ */ -//$$ public class GLErrorTransformer implements IClassTransformer { -//$$ private static final String GL_CLASS = "org.lwjgl.opengl.GL"; -//$$ private static final String GL = GL_CLASS.replace('.', '/'); -//$$ private static final String ARB_CLASS = "org.lwjgl.opengl.ARB"; -//$$ private static final String ARB = ARB_CLASS.replace('.', '/'); -//$$ private static final String EXT_CLASS = "org.lwjgl.opengl.EXT"; -//$$ private static final String EXT = EXT_CLASS.replace('.', '/'); -//$$ private static final String GLErrorTransformer_CLASS = GLErrorTransformer.class.getName(); -//$$ private static final String GLErrorTransformer = GLErrorTransformer_CLASS.replace('.', '/'); -//$$ -//$$ @Override -//$$ public byte[] transform(String name, String transformedName, byte[] basicClass) { -//$$ if (basicClass == null) return null; -//$$ -//$$ ClassReader reader = new ClassReader(basicClass); -//$$ ClassWriter writer = new ClassWriter(reader, 0); -//$$ reader.accept(new ClassVisitor(Opcodes.ASM5, writer) { -//$$ @Override -//$$ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { -//$$ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); -//$$ return new MethodVisitor(Opcodes.ASM5, mv) { -//$$ @Override -//$$ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { -//$$ super.visitMethodInsn(opcode, owner, name, desc, itf); -//$$ if (owner.startsWith(GL) || owner.startsWith(ARB) || owner.startsWith(EXT)) { -//$$ visitLdcInsn(owner.replace('/', '.')); -//$$ visitLdcInsn(name); -//$$ super.visitMethodInsn(Opcodes.INVOKESTATIC, GLErrorTransformer, "glErrorCheck", "(Ljava/lang/String;Ljava/lang/String;)V", false); -//$$ } -//$$ } -//$$ -//$$ @Override -//$$ public void visitMaxs(int maxStack, int maxLocals) { -//$$ super.visitMaxs(maxStack + 2, maxLocals); -//$$ } -//$$ }; -//$$ } -//$$ }, 0); -//$$ return writer.toByteArray(); -//$$ } -//$$ -//$$ private static boolean inGlBegin; -//$$ -//$$ @SuppressWarnings("unused") // Called via ASM -//$$ public static void glErrorCheck(String cls, String method) { -//$$ if (method.equals("glBegin") && cls.equals(GL_CLASS + "11")) { -//$$ if (inGlBegin) { -//$$ // glBegin within glBegin -//$$ throw new GLError(GL11.GL_INVALID_OPERATION, cls, method); -//$$ } -//$$ inGlBegin = true; -//$$ return; -//$$ } -//$$ if (inGlBegin && method.equals("glEnd") && cls.equals(GL_CLASS + "11")) { -//$$ inGlBegin = false; -//$$ } -//$$ if (inGlBegin) { -//$$ return; // Cannot call glGetError in between of glBegin and glEnd -//$$ } -//$$ int err = GL11.glGetError(); -//$$ if (err != 0) { -//$$ GLError e = new GLError(err, cls, method); -//$$ if ("true".equals(System.getProperty("replaymod.glerrors.throw", "true"))) { -//$$ throw e; -//$$ } else { -//$$ e.printStackTrace(); -//$$ } -//$$ } -//$$ } -//$$ -//$$ public static class GLError extends RuntimeException { -//$$ private GLError(int err, String cls, String method) { -//$$ super(GLU.gluErrorString(err) + " (" + err + ")"); -//$$ StackTraceElement[] stack = getStackTrace(); -//$$ stack[0] = new StackTraceElement(cls, method, stack[0].getFileName(), stack[0].getLineNumber()); -//$$ setStackTrace(stack); -//$$ } -//$$ } -//$$ } -//#endif +// 1.7.10 and below diff --git a/versions/1.7.10/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java b/versions/1.7.10/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java new file mode 100644 index 00000000..06098167 --- /dev/null +++ b/versions/1.7.10/src/main/java/com/replaymod/core/asm/GLErrorTransformer.java @@ -0,0 +1,93 @@ +package com.replaymod.core.asm; + +import net.minecraft.launchwrapper.IClassTransformer; +import org.lwjgl.opengl.GL11; +import org.lwjgl.util.glu.GLU; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +/** + * Insert glGetError checks after all calls to any method in any GL*, ARB* and EXT* classes + */ +public class GLErrorTransformer implements IClassTransformer { + private static final String GL_CLASS = "org.lwjgl.opengl.GL"; + private static final String GL = GL_CLASS.replace('.', '/'); + private static final String ARB_CLASS = "org.lwjgl.opengl.ARB"; + private static final String ARB = ARB_CLASS.replace('.', '/'); + private static final String EXT_CLASS = "org.lwjgl.opengl.EXT"; + private static final String EXT = EXT_CLASS.replace('.', '/'); + private static final String GLErrorTransformer_CLASS = GLErrorTransformer.class.getName(); + private static final String GLErrorTransformer = GLErrorTransformer_CLASS.replace('.', '/'); + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if (basicClass == null) return null; + + ClassReader reader = new ClassReader(basicClass); + ClassWriter writer = new ClassWriter(reader, 0); + reader.accept(new ClassVisitor(Opcodes.ASM5, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); + return new MethodVisitor(Opcodes.ASM5, mv) { + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + super.visitMethodInsn(opcode, owner, name, desc, itf); + if (owner.startsWith(GL) || owner.startsWith(ARB) || owner.startsWith(EXT)) { + visitLdcInsn(owner.replace('/', '.')); + visitLdcInsn(name); + super.visitMethodInsn(Opcodes.INVOKESTATIC, GLErrorTransformer, "glErrorCheck", "(Ljava/lang/String;Ljava/lang/String;)V", false); + } + } + + @Override + public void visitMaxs(int maxStack, int maxLocals) { + super.visitMaxs(maxStack + 2, maxLocals); + } + }; + } + }, 0); + return writer.toByteArray(); + } + + private static boolean inGlBegin; + + @SuppressWarnings("unused") // Called via ASM + public static void glErrorCheck(String cls, String method) { + if (method.equals("glBegin") && cls.equals(GL_CLASS + "11")) { + if (inGlBegin) { + // glBegin within glBegin + throw new GLError(GL11.GL_INVALID_OPERATION, cls, method); + } + inGlBegin = true; + return; + } + if (inGlBegin && method.equals("glEnd") && cls.equals(GL_CLASS + "11")) { + inGlBegin = false; + } + if (inGlBegin) { + return; // Cannot call glGetError in between of glBegin and glEnd + } + int err = GL11.glGetError(); + if (err != 0) { + GLError e = new GLError(err, cls, method); + if ("true".equals(System.getProperty("replaymod.glerrors.throw", "true"))) { + throw e; + } else { + e.printStackTrace(); + } + } + } + + public static class GLError extends RuntimeException { + private GLError(int err, String cls, String method) { + super(GLU.gluErrorString(err) + " (" + err + ")"); + StackTraceElement[] stack = getStackTrace(); + stack[0] = new StackTraceElement(cls, method, stack[0].getFileName(), stack[0].getLineNumber()); + setStackTrace(stack); + } + } +}