Move GLErrorTransformer into 1.7.10 project
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user