aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle57
-rw-r--r--src/main/java/io/polyfrost/oneconfig/command/OneConfigCommand.java29
-rw-r--r--src/main/java/io/polyfrost/oneconfig/lwjgl/IOUtil.java65
-rw-r--r--src/main/java/io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java39
-rw-r--r--src/main/java/io/polyfrost/oneconfig/lwjgl/NanoVGUtils.java99
-rw-r--r--src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java55
-rw-r--r--src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java52
-rw-r--r--src/main/java/io/polyfrost/oneconfig/test/TestNanoVGGui.java19
-rw-r--r--src/main/java/io/polyfrost/oneconfig/utils/TickDelay.java2
-rw-r--r--src/main/resources/assets/oneconfig/font/Roboto-Regular.ttfbin0 -> 145348 bytes
10 files changed, 384 insertions, 33 deletions
diff --git a/build.gradle b/build.gradle
index 7efe09c..558b4c9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,7 @@
//file:noinspection UnnecessaryQualifiedReference
//file:noinspection GroovyAssignabilityCheck
+//file:noinspection GradlePackageUpdate
+import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
id "dev.architectury.architectury-pack200" version "0.1.3"
@@ -26,7 +28,7 @@ compileJava.options.encoding = 'UTF-8'
loom {
launchConfigs {
client {
-
+ property("fml.coreMods.load", "io.polyfrost.oneconfig.lwjgl.plugin.LoadingPlugin")
}
}
runConfigs {
@@ -42,16 +44,43 @@ loom {
configurations {
include
implementation.extendsFrom(include)
+ lwjgl
+ lwjglNative {
+ transitive = false
+ }
}
+sourceSets.main.runtimeClasspath += configurations.lwjglNative
+
repositories {
maven { url 'https://repo.woverflow.cc/' }
}
+task lwjglJar(type: ShadowJar) {
+ group = "shadow"
+ archiveClassifier.set("lwjgl")
+ configurations = [project.configurations.lwjgl]
+ exclude "META-INF/versions/**"
+ exclude "**/module-info.class"
+ exclude "**/package-info.class"
+ relocate("org.lwjgl", "org.lwjgl3") {
+ include "org.lwjgl.PointerBuffer"
+ include "org.lwjgl.BufferUtils"
+ }
+}
+
dependencies {
minecraft("com.mojang:minecraft:1.8.9")
mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9")
forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9")
+
+ lwjgl "org.lwjgl:lwjgl:3.3.0"
+ lwjgl "org.lwjgl:lwjgl-tinyfd:3.3.0"
+ lwjgl "org.lwjgl:lwjgl-nanovg:3.3.0"
+ lwjglNative "org.lwjgl:lwjgl:3.3.0:natives-windows"
+ lwjglNative "org.lwjgl:lwjgl-tinyfd:3.3.0:natives-windows"
+ lwjglNative "org.lwjgl:lwjgl-nanovg:3.3.0:natives-windows"
+ implementation lwjglJar.outputs.files
}
processResources {
@@ -71,28 +100,34 @@ processResources {
rename '(.+_at.cfg)', 'META-INF/$1'
}
+/*/
sourceSets {
main {
output.resourcesDir = java.classesDirectory
}
}
+ */
+
+shadowJar {
+ archiveClassifier.set('dev')
+ configurations = [project.configurations.include, project.configurations.lwjglNative]
+ duplicatesStrategy DuplicatesStrategy.EXCLUDE
+}
+
remapJar {
- archiveClassifier = "nodeps"
+ archiveClassifier.set('')
+ from(shadowJar.archiveFile)
}
jar {
manifest.attributes(
'ModSide': 'CLIENT',
'ForceLoadAsMod': true,
- "TweakOrder": "0"
+ "TweakOrder": "0",
+ "FMLCorePlugin": "io.polyfrost.oneconfig.lwjgl.plugin.LoadingPlugin",
+ "FMLCorePluginContainsFMLMod": "lol"
)
+ enabled = false
}
-
-shadowJar {
- archiveClassifier.set('')
- from(remapJar.archiveFile)
- configurations = [project.configurations.include]
- duplicatesStrategy DuplicatesStrategy.EXCLUDE
-}
-assemble.dependsOn shadowJar \ No newline at end of file
+jar.dependsOn(shadowJar) \ No newline at end of file
diff --git a/src/main/java/io/polyfrost/oneconfig/command/OneConfigCommand.java b/src/main/java/io/polyfrost/oneconfig/command/OneConfigCommand.java
index df727a0..c2e6447 100644
--- a/src/main/java/io/polyfrost/oneconfig/command/OneConfigCommand.java
+++ b/src/main/java/io/polyfrost/oneconfig/command/OneConfigCommand.java
@@ -2,20 +2,19 @@ package io.polyfrost.oneconfig.command;
import io.polyfrost.oneconfig.gui.Window;
import io.polyfrost.oneconfig.hud.gui.HudGui;
+import io.polyfrost.oneconfig.test.TestNanoVGGui;
import io.polyfrost.oneconfig.themes.Themes;
import io.polyfrost.oneconfig.utils.TickDelay;
import net.minecraft.client.Minecraft;
-import net.minecraft.command.ICommand;
+import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender;
-import net.minecraft.util.BlockPos;
import net.minecraft.util.ChatComponentText;
-import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-public class OneConfigCommand implements ICommand {
+public class OneConfigCommand extends CommandBase {
private static final Minecraft mc = Minecraft.getMinecraft();
@@ -49,27 +48,15 @@ public class OneConfigCommand implements ICommand {
mc.thePlayer.addChatMessage(new ChatComponentText("reloading theme!"));
Themes.openTheme(new File("OneConfig/themes/one.zip").getAbsoluteFile());
break;
+ case "lwjgl":
+ new TickDelay(() -> mc.displayGuiScreen(new TestNanoVGGui()), 1);
+ break;
}
}
}
@Override
- public boolean canCommandSenderUseCommand(ICommandSender sender) {
- return true;
- }
-
- @Override
- public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) {
- return null;
- }
-
- @Override
- public boolean isUsernameIndex(String[] args, int index) {
- return false;
- }
-
- @Override
- public int compareTo(@NotNull ICommand o) {
- return 0;
+ public int getRequiredPermissionLevel() {
+ return -1;
}
}
diff --git a/src/main/java/io/polyfrost/oneconfig/lwjgl/IOUtil.java b/src/main/java/io/polyfrost/oneconfig/lwjgl/IOUtil.java
new file mode 100644
index 0000000..d0f54f7
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/lwjgl/IOUtil.java
@@ -0,0 +1,65 @@
+package io.polyfrost.oneconfig.lwjgl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import static org.lwjgl.BufferUtils.createByteBuffer;
+import static org.lwjgl.system.MemoryUtil.memSlice;
+
+final class IOUtil {
+
+ private IOUtil() {
+ }
+
+ private static ByteBuffer resizeBuffer(ByteBuffer buffer, int newCapacity) {
+ ByteBuffer newBuffer = createByteBuffer(newCapacity);
+ buffer.flip();
+ newBuffer.put(buffer);
+ return newBuffer;
+ }
+
+ static ByteBuffer resourceToByteBuffer(String resource, int bufferSize) throws IOException {
+ ByteBuffer buffer;
+
+ Path path = Paths.get(resource);
+ if (Files.isReadable(path)) {
+ try (SeekableByteChannel fc = Files.newByteChannel(path)) {
+ buffer = createByteBuffer((int)fc.size() + 1);
+ while (fc.read(buffer) != -1) {
+ //noinspection UnnecessarySemicolon
+ ;
+ }
+ }
+ } else {
+ try (
+ InputStream source = IOUtil.class.getResourceAsStream(resource);
+ ReadableByteChannel rbc = Channels.newChannel(source)
+ ) {
+ buffer = createByteBuffer(bufferSize);
+
+ while (true) {
+ int bytes = rbc.read(buffer);
+ if (bytes == -1) {
+ break;
+ }
+ if (buffer.remaining() == 0) {
+ buffer = resizeBuffer(buffer, buffer.capacity() * 3 / 2); // 50%
+ }
+ }
+ }
+ }
+
+ //noinspection RedundantCast
+ ((Buffer) buffer).flip();
+ return memSlice(buffer);
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java b/src/main/java/io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java
new file mode 100644
index 0000000..ea1a44b
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider.java
@@ -0,0 +1,39 @@
+package io.polyfrost.oneconfig.lwjgl;
+
+import org.lwjgl.opengl.GLContext;
+import org.lwjgl.system.FunctionProvider;
+
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+public class Lwjgl2FunctionProvider implements FunctionProvider {
+
+ private final Method m_getFunctionAddress;
+
+ public Lwjgl2FunctionProvider() {
+ try {
+ m_getFunctionAddress = GLContext.class.getDeclaredMethod("getFunctionAddress", String.class);
+ m_getFunctionAddress.setAccessible(true);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public long getFunctionAddress(CharSequence functionName) {
+ try {
+ return (long) m_getFunctionAddress.invoke(null, functionName.toString());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public long getFunctionAddress(ByteBuffer byteBuffer) {
+ throw new UnsupportedOperationException();
+ }
+} \ No newline at end of file
diff --git a/src/main/java/io/polyfrost/oneconfig/lwjgl/NanoVGUtils.java b/src/main/java/io/polyfrost/oneconfig/lwjgl/NanoVGUtils.java
new file mode 100644
index 0000000..c9d0615
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/lwjgl/NanoVGUtils.java
@@ -0,0 +1,99 @@
+package io.polyfrost.oneconfig.lwjgl;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.shader.Framebuffer;
+import org.lwjgl.nanovg.NVGColor;
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.system.MemoryStack;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.function.LongConsumer;
+
+import static org.lwjgl.nanovg.NanoVG.*;
+import static org.lwjgl.nanovg.NanoVGGL2.*;
+
+public final class NanoVGUtils {
+ private NanoVGUtils() {
+
+ }
+ private static long vg = -1;
+ private static int font = -1;
+
+ public static void setupAndDraw(LongConsumer consumer) {
+ if (vg == -1) {
+ vg = nvgCreate(NVG_ANTIALIAS);
+ if (vg == -1) {
+ throw new RuntimeException("Failed to create nvg context");
+ }
+ }
+ if (font == -1) {
+ try {
+ font = nvgCreateFontMem(vg, "custom-font", IOUtil.resourceToByteBuffer("/assets/oneconfig/font/Roboto-Regular.ttf", 150 * 1024), 0);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (font == -1) {
+ throw new RuntimeException("Failed to create custom font");
+ }
+ }
+
+ Framebuffer fb = Minecraft.getMinecraft().getFramebuffer();
+ if (!fb.isStencilEnabled()) {
+ fb.enableStencil();
+ }
+ GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
+
+ nvgBeginFrame(vg, Display.getWidth(), Display.getHeight(), 1);
+
+ consumer.accept(vg);
+
+ nvgEndFrame(vg);
+
+ GlStateManager.popAttrib();
+ }
+
+ public static void drawRect(long vg, float x, float y, float width, float height, int color) {
+ nvgBeginPath(vg);
+ nvgRect(vg, x, y, width, height);
+ color(vg, color);
+ nvgFill(vg);
+ }
+
+ public static void drawRoundedRect(long vg, float x, float y, float width, float height, int color, float radius) {
+ nvgBeginPath(vg);
+ nvgRoundedRect(vg, x, y, width, height, radius);
+ color(vg, color);
+ nvgFill(vg);
+ }
+
+ public static void drawCircle(long vg, float x, float y, float radius, int color) {
+ nvgBeginPath(vg);
+ nvgCircle(vg, x, y, radius);
+ color(vg, color);
+ nvgFill(vg);
+ }
+
+ public static void drawString(long vg, String text, float x, float y, int color, float size) {
+ nvgBeginPath(vg);
+ nvgFontSize(vg, size);
+ nvgFontFace(vg, "custom-font");
+ nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
+ try (MemoryStack stack = MemoryStack.stackPush()) {
+ ByteBuffer textByte = stack.ASCII(text, false);
+ nvgFontBlur(vg, 0);
+ color(vg, color);
+ nvgText(vg, x, y, textByte);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void color(long vg, int color) {
+ NVGColor nvgColor = NVGColor.create();
+ nvgRGBA((byte) (color >> 16 & 0xFF), (byte) (color >> 8 & 0xFF), (byte) (color & 0xFF), (byte) (color >> 24 & 0xFF), nvgColor);
+ nvgFillColor(vg, nvgColor);
+ }
+}
diff --git a/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java b/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java
new file mode 100644
index 0000000..066677b
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/ClassTransformer.java
@@ -0,0 +1,55 @@
+package io.polyfrost.oneconfig.lwjgl.plugin;
+
+import net.minecraft.launchwrapper.IClassTransformer;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.*;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+public class ClassTransformer implements IClassTransformer {
+ @Override
+ public byte[] transform(String name, String transformedName, byte[] basicClass) {
+ if (name.equals("org.lwjgl.nanovg.NanoVGGLConfig")) {
+ ClassReader reader = new ClassReader(basicClass);
+ ClassNode node = new ClassNode();
+ reader.accept(node, ClassReader.EXPAND_FRAMES);
+
+ for (MethodNode method : node.methods) {
+ if (method.name.equals("configGL")) {
+ InsnList list = new InsnList();
+
+ list.add(new VarInsnNode(Opcodes.LLOAD, 0));
+ list.add(new TypeInsnNode(Opcodes.NEW, "io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider"));
+ list.add(new InsnNode(Opcodes.DUP));
+ list.add(new MethodInsnNode(
+ Opcodes.INVOKESPECIAL,
+ "io/polyfrost/oneconfig/lwjgl/Lwjgl2FunctionProvider",
+ "<init>",
+ "()V",
+ false
+ ));
+ list.add(new MethodInsnNode(
+ Opcodes.INVOKESTATIC,
+ "org/lwjgl/nanovg/NanoVGGLConfig",
+ "config",
+ "(JLorg/lwjgl/system/FunctionProvider;)V",
+ false
+ ));
+ list.add(new InsnNode(Opcodes.RETURN));
+
+ method.instructions.clear();
+ method.instructions.insert(list);
+ }
+ }
+
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+ node.accept(cw);
+ return cw.toByteArray();
+ }
+ return basicClass;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java b/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java
new file mode 100644
index 0000000..1f48135
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/lwjgl/plugin/LoadingPlugin.java
@@ -0,0 +1,52 @@
+package io.polyfrost.oneconfig.lwjgl.plugin;
+
+import net.minecraft.launchwrapper.Launch;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Taken from LWJGLTwoPointFive under The Unlicense
+ * https://github.com/DJtheRedstoner/LWJGLTwoPointFive/blob/master/LICENSE/
+ */
+public class LoadingPlugin implements IFMLLoadingPlugin {
+
+ public LoadingPlugin() {
+ try {
+ Field f_exceptions = LaunchClassLoader.class.getDeclaredField("classLoaderExceptions");
+ f_exceptions.setAccessible(true);
+ Set<String> exceptions = (Set<String>) f_exceptions.get(Launch.classLoader);
+ exceptions.remove("org.lwjgl.");
+ } catch (Exception e) {
+ throw new RuntimeException("e");
+ }
+ }
+
+ @Override
+ public String[] getASMTransformerClass() {
+ return new String[]{"io.polyfrost.oneconfig.lwjgl.plugin.ClassTransformer"};
+ }
+
+ @Override
+ public String getModContainerClass() {
+ return null;
+ }
+
+ @Override
+ public String getSetupClass() {
+ return null;
+ }
+
+ @Override
+ public void injectData(Map<String, Object> data) {
+
+ }
+
+ @Override
+ public String getAccessTransformerClass() {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/io/polyfrost/oneconfig/test/TestNanoVGGui.java b/src/main/java/io/polyfrost/oneconfig/test/TestNanoVGGui.java
new file mode 100644
index 0000000..74d6a1e
--- /dev/null
+++ b/src/main/java/io/polyfrost/oneconfig/test/TestNanoVGGui.java
@@ -0,0 +1,19 @@
+package io.polyfrost.oneconfig.test;
+
+import io.polyfrost.oneconfig.lwjgl.NanoVGUtils;
+import net.minecraft.client.gui.GuiScreen;
+
+import java.awt.*;
+
+public class TestNanoVGGui extends GuiScreen {
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ NanoVGUtils.setupAndDraw((vg) -> {
+ NanoVGUtils.drawRect(vg, 0, 0, 300, 300, Color.BLUE.getRGB());
+ NanoVGUtils.drawRoundedRect(vg, 305, 305, 100, 100, Color.BLACK.getRGB(), 8);
+ NanoVGUtils.drawString(vg, "Hello!", 500, 500, Color.BLACK.getRGB(), 50);
+ });
+ }
+}
diff --git a/src/main/java/io/polyfrost/oneconfig/utils/TickDelay.java b/src/main/java/io/polyfrost/oneconfig/utils/TickDelay.java
index 33b02fe..b28a20a 100644
--- a/src/main/java/io/polyfrost/oneconfig/utils/TickDelay.java
+++ b/src/main/java/io/polyfrost/oneconfig/utils/TickDelay.java
@@ -6,7 +6,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
public class TickDelay {
- Integer delay;
+ int delay;
Runnable function;
public TickDelay(Runnable functionName, int ticks) {
diff --git a/src/main/resources/assets/oneconfig/font/Roboto-Regular.ttf b/src/main/resources/assets/oneconfig/font/Roboto-Regular.ttf
new file mode 100644
index 0000000..3e6e2e7
--- /dev/null
+++ b/src/main/resources/assets/oneconfig/font/Roboto-Regular.ttf
Binary files differ