diff --git a/src/main/java/llc/redstone/hysentials/guis/hsplayerlist/GuiOnlineList.java b/src/main/java/llc/redstone/hysentials/guis/hsplayerlist/GuiOnlineList.java index 2dec14e..5a60522 100644 --- a/src/main/java/llc/redstone/hysentials/guis/hsplayerlist/GuiOnlineList.java +++ b/src/main/java/llc/redstone/hysentials/guis/hsplayerlist/GuiOnlineList.java @@ -96,14 +96,13 @@ public void renderPlayerlist(int width) { int s; //draw hsob drawRect(width / 2 - r / 2 - 1, 0, width / 2 + r / 2 + 1, (int) ((r/2.688172043) + 10), Integer.MIN_VALUE); + GlStateManager.pushAttrib(); this.mc.getTextureManager().bindTexture(hsob); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.enableAlpha(); GlStateManager.enableBlend(); - GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); drawModalRectWithCustomSizedTexture(width / 2 - (r + 10) / 2, 0, 0, 0, r + 10, (int) ((r/2.688172043) + 10), r + 10, r/3f + 10); + GlStateManager.popAttrib(); q += (int) (r/2.688172043); - this.mc.getTextureManager().bindTexture(GuiIngame.icons); drawRect(width / 2 - r / 2 - 1, q - 1, width / 2 + r / 2 + 1, q + m * 9, Integer.MIN_VALUE); diff --git a/src/main/java/llc/redstone/hysentials/mixin/FMLClientHandlerMixin.java b/src/main/java/llc/redstone/hysentials/mixin/FMLClientHandlerMixin.java new file mode 100644 index 0000000..88bf239 --- /dev/null +++ b/src/main/java/llc/redstone/hysentials/mixin/FMLClientHandlerMixin.java @@ -0,0 +1,47 @@ +package llc.redstone.hysentials.mixin; + +import llc.redstone.hysentials.util.SplashProgress; +import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IReloadableResourceManager; +import net.minecraftforge.fml.client.FMLClientHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; +import java.util.concurrent.Semaphore; + +@Mixin(value=FMLClientHandler.class, remap = false) +public class FMLClientHandlerMixin { + @Redirect(method = "beginMinecraftLoading", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/SplashProgress;start()V")) + private void rdStart() { + SplashProgress.start(); + } + + @Redirect(method = "onInitializationComplete", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/SplashProgress;finish()V")) + private void rdFinish3() { + SplashProgress.finish(); + } + + @Redirect(method = "haltGame", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/SplashProgress;finish()V")) + private void rdFinish() { + SplashProgress.finish(); + } + + @Redirect(method = "finishMinecraftLoading", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/fml/client/SplashProgress;finish()V")) + private void rdFinish2() { + SplashProgress.finish(); + } + + @Redirect(method = "processWindowMessages", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/Semaphore;tryAcquire()Z")) + private boolean rdTryAcquire(Semaphore instance) { + return SplashProgress.mutex.tryAcquire(); + } + + @Redirect(method = "processWindowMessages", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/Semaphore;release()V")) + private void rdRelease(Semaphore instance) { + SplashProgress.mutex.release(); + } +} diff --git a/src/main/java/llc/redstone/hysentials/util/SplashProgress.java b/src/main/java/llc/redstone/hysentials/util/SplashProgress.java new file mode 100644 index 0000000..603a9c9 --- /dev/null +++ b/src/main/java/llc/redstone/hysentials/util/SplashProgress.java @@ -0,0 +1,637 @@ +package llc.redstone.hysentials.util; + +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_GREATER; +import static org.lwjgl.opengl.GL11.GL_LEQUAL; +import static org.lwjgl.opengl.GL11.GL_LIGHTING; +import static org.lwjgl.opengl.GL11.GL_MODELVIEW; +import static org.lwjgl.opengl.GL11.GL_NEAREST; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_PROJECTION; +import static org.lwjgl.opengl.GL11.GL_QUADS; +import static org.lwjgl.opengl.GL11.GL_RENDERER; +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER; +import static org.lwjgl.opengl.GL11.GL_VENDOR; +import static org.lwjgl.opengl.GL11.GL_VERSION; +import static org.lwjgl.opengl.GL11.glAlphaFunc; +import static org.lwjgl.opengl.GL11.glBegin; +import static org.lwjgl.opengl.GL11.glBindTexture; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glClear; +import static org.lwjgl.opengl.GL11.glClearColor; +import static org.lwjgl.opengl.GL11.glColor3ub; +import static org.lwjgl.opengl.GL11.glDeleteTextures; +import static org.lwjgl.opengl.GL11.glDepthFunc; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnd; +import static org.lwjgl.opengl.GL11.glGenTextures; +import static org.lwjgl.opengl.GL11.glGetString; +import static org.lwjgl.opengl.GL11.glLoadIdentity; +import static org.lwjgl.opengl.GL11.glMatrixMode; +import static org.lwjgl.opengl.GL11.glOrtho; +import static org.lwjgl.opengl.GL11.glPopMatrix; +import static org.lwjgl.opengl.GL11.glPushMatrix; +import static org.lwjgl.opengl.GL11.glScalef; +import static org.lwjgl.opengl.GL11.glTexCoord2f; +import static org.lwjgl.opengl.GL11.glTexImage2D; +import static org.lwjgl.opengl.GL11.glTexParameteri; +import static org.lwjgl.opengl.GL11.glTexSubImage2D; +import static org.lwjgl.opengl.GL11.glTranslatef; +import static org.lwjgl.opengl.GL11.glVertex2f; +import static org.lwjgl.opengl.GL11.glViewport; +import static org.lwjgl.opengl.GL12.GL_BGRA; +import static org.lwjgl.opengl.GL12.GL_UNSIGNED_INT_8_8_8_8_REV; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.PrintWriter; +import java.lang.Thread.UncaughtExceptionHandler; +import java.nio.ByteBuffer; +import java.nio.IntBuffer; +import java.util.Iterator; +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.FileResourcePack; +import net.minecraft.client.resources.FolderResourcePack; +import net.minecraft.client.resources.IResourcePack; +import net.minecraft.crash.CrashReport; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.EnhancedRuntimeException; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.ICrashCallable; +import net.minecraftforge.fml.common.ProgressManager; +import net.minecraftforge.fml.common.asm.FMLSanityChecker; + +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.Level; +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.*; +import org.lwjgl.util.glu.GLU; + +@SuppressWarnings("serial") +public class SplashProgress { + private static Drawable d; + private static volatile boolean pause = false; + private static volatile boolean done = false; + private static Thread thread; + private static volatile Throwable threadError; + private static int angle = 0; + private static final Lock lock = new ReentrantLock(true); + private static SplashFontRenderer fontRenderer; + + private static final IResourcePack mcPack = Minecraft.getMinecraft().mcDefaultResourcePack; + private static final IResourcePack fmlPack = createResourcePack(FMLSanityChecker.fmlLocation); + private static IResourcePack miscPack; + + private static Texture fontTexture; + private static Texture logoTexture; + private static Texture forgeTexture; + + + public static final Semaphore mutex = new Semaphore(1); + + public static void start() { + final ResourceLocation fontLoc = new ResourceLocation("textures/font/ascii.png"); + final ResourceLocation logoLoc = new ResourceLocation("hysentials:gui/hysentials.png"); + final ResourceLocation forgeLoc = new ResourceLocation("hysentials:gui/loading.gif"); + + File miscPackFile = new File(Minecraft.getMinecraft().mcDataDir, "resources"); + + miscPack = createResourcePack(miscPackFile); + + // getting debug info out of the way, while we still can + FMLCommonHandler.instance().registerCrashCallable(new ICrashCallable() { + public String call() throws Exception { + return "' Vendor: '" + glGetString(GL_VENDOR) + + "' Version: '" + glGetString(GL_VERSION) + + "' Renderer: '" + glGetString(GL_RENDERER) + + "'"; + } + + public String getLabel() { + return "GL info"; + } + }); + CrashReport report = CrashReport.makeCrashReport(new Throwable() { + @Override + public String getMessage() { + return "This is just a prompt for computer specs to be printed. THIS IS NOT A ERROR"; + } + + @Override + public void printStackTrace(final PrintWriter s) { + s.println(getMessage()); + } + + @Override + public void printStackTrace(final PrintStream s) { + s.println(getMessage()); + } + }, "Loading screen debug info"); + System.out.println(report.getCompleteReport()); + + try { + d = new SharedDrawable(Display.getDrawable()); + Display.getDrawable().releaseContext(); + d.makeCurrent(); + } catch (LWJGLException e) { + e.printStackTrace(); + disableSplash(e); + } + + //Call this ASAP if splash is enabled so that threading doesn't cause issues later + getMaxTextureSize(); + + //Thread mainThread = Thread.currentThread(); + thread = new Thread(new Runnable() { + private final int barWidth = 400; + private final int barHeight = 20; + private final int textHeight2 = 20; + private final int barOffset = 55; + private int actualPercent = 0; + + + public void run() { + setGL(); + fontTexture = new Texture(fontLoc); + logoTexture = new Texture(logoLoc); + forgeTexture = new Texture(forgeLoc); + glEnable(GL_TEXTURE_2D); + fontRenderer = new SplashFontRenderer(); + glDisable(GL_TEXTURE_2D); + while (!done) { + ProgressManager.ProgressBar first = null, penult = null, last = null; + Iterator i = ProgressManager.barIterator(); + float percentComplete = 0; + + while (i.hasNext()) { + if (first == null) { + first = i.next(); + if ((actualPercent < first.getStep() * 100 / first.getSteps())) { + percentComplete = first.getStep() * 100f / first.getSteps(); + if (Math.round(percentComplete) == actualPercent && actualPercent < (first.getStep() + 1) * 100 / first.getSteps()) { + percentComplete += 1; + } + } + + } else { + penult = last; + last = i.next(); + if (actualPercent < (actualPercent + (last.getStep() * 100f / last.getSteps()) / 14.285f)) { + percentComplete += (last.getStep() * 100f / last.getSteps()) / 14.285f; + } + } + if (actualPercent < percentComplete) { + actualPercent = (int) percentComplete; + } + } + + glClear(GL_COLOR_BUFFER_BIT); + + // matrix setup + int w = Display.getWidth(); + int h = Display.getHeight(); + + float scale = new ScaledResolution(Minecraft.getMinecraft()).getScaleFactor(); + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(320 - w / 2, 320 + w / 2, 240 + h / 2, 240 - h / 2, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //Width: 675, Height : 225 + // mojang logo + setColor(0xFFFFFF); + glTranslatef(0, -50 * scale, 0); + glEnable(GL_TEXTURE_2D); + logoTexture.bind(); + glBegin(GL_QUADS); + logoTexture.texCoord(0, 0, 0); + glVertex2f(320 - 337.5f, 240 - 112.5f); + logoTexture.texCoord(0, 0, 1); + glVertex2f(320 - 337.5f, 240 + 112.5f); + logoTexture.texCoord(0, 1, 1); + glVertex2f(320 + 337.5f, 240 + 112.5f); + logoTexture.texCoord(0, 1, 0); + glVertex2f(320 + 337.5f, 240 - 112.5f); + glEnd(); + glDisable(GL_TEXTURE_2D); + + //bars + if (first != null) { + glPushMatrix(); + glTranslatef(320 - (float) barWidth / 2, 360, 0); + drawBar(first); + } + + angle += 1; + // forge logo + setColor(0xFFFFFF); + float fw = (float) forgeTexture.getWidth() / 2 / 1.5f; + float fh = (float) forgeTexture.getHeight() / 2 / 1.5f; + + glTranslatef(0, h / 2, 0); + + int f = (angle / 2) % forgeTexture.getFrames(); + glEnable(GL_TEXTURE_2D); + forgeTexture.bind(); + glBegin(GL_QUADS); + forgeTexture.texCoord(f, 0, 0); + glVertex2f(320 - fw, 240 - fh); + forgeTexture.texCoord(f, 0, 1); + glVertex2f(320 - fw, 240 + fh); + forgeTexture.texCoord(f, 1, 1); + glVertex2f(320 + fw, 240 + fh); + forgeTexture.texCoord(f, 1, 0); + glVertex2f(320 + fw, 240 - fh); + glEnd(); + glDisable(GL_TEXTURE_2D); + + // We use mutex to indicate safely to the main thread that we're taking the display global lock + // So the main thread can skip processing messages while we're updating. + // There are system setups where this call can pause for a while, because the GL implementation + // is trying to impose a framerate or other thing is occurring. Without the mutex, the main + // thread would delay waiting for the same global display lock + mutex.acquireUninterruptibly(); + Display.update(); + // As soon as we're done, we release the mutex. The other thread can now ping the processmessages + // call as often as it wants until we get get back here again + mutex.release(); + if (pause) { + clearGL(); + setGL(); + } + Display.sync(100); + } + clearGL(); + } + + private void setColor(int color) { + glColor3ub((byte) ((color >> 16) & 0xFF), (byte) ((color >> 8) & 0xFF), (byte) (color & 0xFF)); + } + + private void drawBox(int w, int h) { + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(0, h); + glVertex2f(w, h); + glVertex2f(w, 0); + glEnd(); + } + + private void drawBar(ProgressManager.ProgressBar b) { + glPushMatrix(); + // border + glPushMatrix(); + glTranslatef(0, textHeight2, 0); + setColor(0xC0C0C0); + drawBox(barWidth, barHeight + 2); + + // slidy part + glTranslatef(2, 2, 0); + setColor(0x1E1E1E); + drawBox((barWidth - 4) * (b.getStep() + 1) / (b.getSteps() + 1), barHeight - 2); // Step can sometimes be 0. + // progress text + String progress = actualPercent + "%"; + glTranslatef(((float) barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 40, 0); + setColor(0x000000); + glScalef(2, 2, 1); + glEnable(GL_TEXTURE_2D); + fontRenderer.drawString(progress, 0, 0, 0x000000); + glPopMatrix(); + } + + private void setGL() { + lock.lock(); + try { + Display.getDrawable().makeCurrent(); + } catch (LWJGLException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + glClearColor((float) ((0xFFFFFF >> 16) & 0xFF) / 0xFF, (float) ((0xFFFFFF >> 8) & 0xFF) / 0xFF, (float) (0xFFFFFF & 0xFF) / 0xFF, 1); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + private void clearGL() { + Minecraft mc = Minecraft.getMinecraft(); + mc.displayWidth = Display.getWidth(); + mc.displayHeight = Display.getHeight(); + mc.resize(mc.displayWidth, mc.displayHeight); + glClearColor(1, 1, 1, 1); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, .1f); + try { + Display.getDrawable().releaseContext(); + } catch (LWJGLException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + lock.unlock(); + } + } + }); + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + public void uncaughtException(Thread t, Throwable e) { + FMLLog.log(Level.ERROR, e, "Splash thread Exception"); + threadError = e; + } + }); + thread.start(); + checkThreadState(); + } + + private static int max_texture_size = -1; + + public static int getMaxTextureSize() { + if (max_texture_size != -1) return max_texture_size; + for (int i = 0x4000; i > 0; i >>= 1) { + GL11.glTexImage2D(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_RGBA, i, i, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null); + if (GL11.glGetTexLevelParameteri(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_TEXTURE_WIDTH) != 0) { + max_texture_size = i; + return i; + } + } + return -1; + } + + private static void checkThreadState() { + if (thread.getState() == Thread.State.TERMINATED || threadError != null) { + throw new IllegalStateException("Splash thread", threadError); + } + } + + /** + * Call before you need to explicitly modify GL context state during loading. + * Resource loading doesn't usually require this call. + * Call {@link #resume()} when you're done. + * + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static void pause() { + checkThreadState(); + pause = true; + lock.lock(); + try { + d.releaseContext(); + Display.getDrawable().makeCurrent(); + } catch (LWJGLException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static void resume() { + checkThreadState(); + pause = false; + try { + Display.getDrawable().releaseContext(); + d.makeCurrent(); + } catch (LWJGLException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + lock.unlock(); + } + + public static void finish() { + try { + checkThreadState(); + done = true; + thread.join(); + d.releaseContext(); + Display.getDrawable().makeCurrent(); + fontTexture.delete(); + logoTexture.delete(); + forgeTexture.delete(); + } catch (Exception e) { + e.printStackTrace(); + disableSplash(e); + } + } + + private static boolean disableSplash(Exception e) { + if (disableSplash()) { + throw new EnhancedRuntimeException(e) { + @Override + protected void printStackTrace(WrappedPrintStream stream) { + stream.println("SplashProgress has detected a error loading Minecraft."); + stream.println("This can sometimes be caused by bad video drivers."); + stream.println("We have automatically disabeled the new Splash Screen in config/splash.properties."); + stream.println("Try reloading minecraft before reporting any errors."); + } + }; + } else { + throw new EnhancedRuntimeException(e) { + @Override + protected void printStackTrace(WrappedPrintStream stream) { + stream.println("SplashProgress has detected a error loading Minecraft."); + stream.println("This can sometimes be caused by bad video drivers."); + stream.println("Please try disabeling the new Splash Screen in config/splash.properties."); + stream.println("After doing so, try reloading minecraft before reporting any errors."); + } + }; + } + } + + private static boolean disableSplash() { + return true; + } + + private static IResourcePack createResourcePack(File file) { + if (file.isDirectory()) { + return new FolderResourcePack(file); + } else { + return new FileResourcePack(file); + } + } + + private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024); + + @SuppressWarnings("unused") + private static class Texture { + private final ResourceLocation location; + private final int name; + private final int width; + private final int height; + private final int frames; + private final int size; + + public Texture(ResourceLocation location) { + InputStream s = null; + try { + this.location = location; + s = open(location); + ImageInputStream stream = ImageIO.createImageInputStream(s); + Iterator readers = ImageIO.getImageReaders(stream); + if (!readers.hasNext()) throw new IOException("No suitable reader found for image" + location); + ImageReader reader = readers.next(); + reader.setInput(stream); + frames = reader.getNumImages(true); + BufferedImage[] images = new BufferedImage[frames]; + for (int i = 0; i < frames; i++) { + images[i] = reader.read(i); + } + reader.dispose(); + int size = 1; + width = images[0].getWidth(); + height = images[0].getHeight(); + while ((size / width) * (size / height) < frames) size *= 2; + this.size = size; + glEnable(GL_TEXTURE_2D); + synchronized (SplashProgress.class) { + name = glGenTextures(); + glBindTexture(GL_TEXTURE_2D, name); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer) null); + checkGLError("Texture creation"); + for (int i = 0; i * (size / width) < frames; i++) { + for (int j = 0; i * (size / width) + j < frames && j < size / width; j++) { + buf.clear(); + BufferedImage image = images[i * (size / width) + j]; + for (int k = 0; k < height; k++) { + for (int l = 0; l < width; l++) { + buf.put(image.getRGB(l, k)); + } + } + buf.position(0).limit(width * height); + glTexSubImage2D(GL_TEXTURE_2D, 0, j * width, i * height, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf); + checkGLError("Texture uploading"); + } + } + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + IOUtils.closeQuietly(s); + } + } + + public ResourceLocation getLocation() { + return location; + } + + public int getName() { + return name; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public int getFrames() { + return frames; + } + + public int getSize() { + return size; + } + + public void bind() { + glBindTexture(GL_TEXTURE_2D, name); + } + + public void delete() { + glDeleteTextures(name); + } + + public float getU(int frame, float u) { + return width * (frame % (size / width) + u) / size; + } + + public float getV(int frame, float v) { + return height * (frame / (size / width) + v) / size; + } + + public void texCoord(int frame, float u, float v) { + glTexCoord2f(getU(frame, u), getV(frame, v)); + } + } + + private static class SplashFontRenderer extends FontRenderer { + public SplashFontRenderer() { + super(Minecraft.getMinecraft().gameSettings, fontTexture.getLocation(), null, false); + super.onResourceManagerReload(null); + } + + @Override + protected void bindTexture(ResourceLocation location) { + if (location != locationFontTexture) throw new IllegalArgumentException(); + fontTexture.bind(); + } + + @Override + protected InputStream getResourceInputStream(ResourceLocation location) throws IOException { + return Minecraft.getMinecraft().mcDefaultResourcePack.getInputStream(location); + } + } + + public static void drawVanillaScreen(TextureManager renderEngine) throws LWJGLException { + if (!true) { + Minecraft.getMinecraft().drawSplashScreen(renderEngine); + } + } + + public static void clearVanillaResources(TextureManager renderEngine, ResourceLocation mojangLogo) { + if (!true) { + renderEngine.deleteTexture(mojangLogo); + } + } + + public static void checkGLError(String where) { + int err = GL11.glGetError(); + if (err != 0) { + throw new IllegalStateException(where + ": " + GLU.gluErrorString(err)); + } + } + + private static InputStream open(ResourceLocation loc) throws IOException { + if (miscPack.resourceExists(loc)) { + return miscPack.getInputStream(loc); + } else if (fmlPack.resourceExists(loc)) { + return fmlPack.getInputStream(loc); + } + return mcPack.getInputStream(loc); + } +} diff --git a/src/main/resources/assets/hysentials/gui/hysentials.png b/src/main/resources/assets/hysentials/gui/hysentials.png new file mode 100644 index 0000000..1a45197 Binary files /dev/null and b/src/main/resources/assets/hysentials/gui/hysentials.png differ diff --git a/src/main/resources/assets/hysentials/gui/loading.gif b/src/main/resources/assets/hysentials/gui/loading.gif new file mode 100644 index 0000000..9c52cb9 Binary files /dev/null and b/src/main/resources/assets/hysentials/gui/loading.gif differ diff --git a/src/main/resources/mixins.hysentials.json b/src/main/resources/mixins.hysentials.json index 4fae3f4..e3e7135 100644 --- a/src/main/resources/mixins.hysentials.json +++ b/src/main/resources/mixins.hysentials.json @@ -30,5 +30,8 @@ "SlotDecorationMixin", "fancyformatting.ImageIconsMixin", "fancyformatting.ReplacementMixin" + ], + "mixins": [ + "FMLClientHandlerMixin" ] } \ No newline at end of file