2015-05-11 03:55:11 +00:00
|
|
|
package net.minecraftforge.fml.client;
|
|
|
|
|
|
|
|
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.glRotatef;
|
|
|
|
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;
|
2015-04-25 02:12:02 +00:00
|
|
|
|
|
|
|
import java.awt.image.BufferedImage;
|
2015-04-25 21:11:29 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileReader;
|
|
|
|
import java.io.FileWriter;
|
2015-04-21 01:42:59 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2015-05-25 19:17:33 +00:00
|
|
|
import java.io.PrintStream;
|
|
|
|
import java.io.PrintWriter;
|
2015-04-24 02:38:32 +00:00
|
|
|
import java.lang.Thread.UncaughtExceptionHandler;
|
2015-04-25 02:12:02 +00:00
|
|
|
import java.nio.IntBuffer;
|
2015-04-21 01:42:59 +00:00
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.Properties;
|
2015-05-16 16:55:15 +00:00
|
|
|
import java.util.concurrent.Semaphore;
|
2015-04-21 01:42:59 +00:00
|
|
|
import java.util.concurrent.locks.Lock;
|
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
|
|
|
|
|
import javax.imageio.ImageIO;
|
2015-04-25 02:12:02 +00:00
|
|
|
import javax.imageio.ImageReader;
|
|
|
|
import javax.imageio.stream.ImageInputStream;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
|
import net.minecraft.client.gui.FontRenderer;
|
|
|
|
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;
|
2015-04-29 12:15:35 +00:00
|
|
|
import net.minecraft.launchwrapper.Launch;
|
2015-04-21 01:42:59 +00:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
2015-05-25 20:34:04 +00:00
|
|
|
import net.minecraftforge.fml.common.EnhancedRuntimeException;
|
|
|
|
import net.minecraftforge.fml.common.EnhancedRuntimeException.WrappedPrintStream;
|
2015-05-11 03:55:11 +00:00
|
|
|
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.ProgressManager.ProgressBar;
|
|
|
|
import net.minecraftforge.fml.common.asm.FMLSanityChecker;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
import org.apache.commons.io.IOUtils;
|
2015-04-24 02:38:32 +00:00
|
|
|
import org.apache.logging.log4j.Level;
|
2015-04-25 02:12:02 +00:00
|
|
|
import org.lwjgl.BufferUtils;
|
2015-04-21 01:42:59 +00:00
|
|
|
import org.lwjgl.LWJGLException;
|
|
|
|
import org.lwjgl.opengl.Display;
|
|
|
|
import org.lwjgl.opengl.Drawable;
|
|
|
|
import org.lwjgl.opengl.GL11;
|
|
|
|
import org.lwjgl.opengl.SharedDrawable;
|
2015-04-25 02:12:02 +00:00
|
|
|
import org.lwjgl.util.glu.GLU;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @deprecated not a stable API, will break, don't use this yet
|
|
|
|
*/
|
|
|
|
@Deprecated
|
|
|
|
public class SplashProgress
|
|
|
|
{
|
|
|
|
private static Drawable d;
|
|
|
|
private static volatile boolean pause = false;
|
|
|
|
private static volatile boolean done = false;
|
|
|
|
private static Thread thread;
|
2015-04-24 22:27:57 +00:00
|
|
|
private static volatile Throwable threadError;
|
2015-04-21 01:42:59 +00:00
|
|
|
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;
|
2015-04-25 21:11:29 +00:00
|
|
|
private static final IResourcePack fmlPack = createResourcePack(FMLSanityChecker.fmlLocation);
|
|
|
|
private static IResourcePack miscPack;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
2015-04-25 02:12:02 +00:00
|
|
|
private static Texture fontTexture;
|
|
|
|
private static Texture logoTexture;
|
|
|
|
private static Texture forgeTexture;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
2015-04-25 21:11:29 +00:00
|
|
|
private static Properties config;
|
2015-04-21 01:42:59 +00:00
|
|
|
|
2015-04-25 21:11:29 +00:00
|
|
|
private static boolean enabled;
|
|
|
|
private static boolean rotate;
|
|
|
|
private static int logoOffset;
|
|
|
|
private static int backgroundColor;
|
|
|
|
private static int fontColor;
|
|
|
|
private static int barBorderColor;
|
|
|
|
private static int barColor;
|
|
|
|
private static int barBackgroundColor;
|
2015-05-16 16:55:15 +00:00
|
|
|
static final Semaphore mutex = new Semaphore(1);
|
2015-04-25 21:11:29 +00:00
|
|
|
|
|
|
|
private static String getString(String name, String def)
|
|
|
|
{
|
|
|
|
String value = config.getProperty(name, def);
|
|
|
|
config.setProperty(name, value);
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static boolean getBool(String name, boolean def)
|
|
|
|
{
|
|
|
|
return Boolean.parseBoolean(getString(name, Boolean.toString(def)));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static int getInt(String name, int def)
|
|
|
|
{
|
|
|
|
return Integer.decode(getString(name, Integer.toString(def)));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static int getHex(String name, int def)
|
|
|
|
{
|
|
|
|
return Integer.decode(getString(name, "0x" + Integer.toString(def, 16).toUpperCase()));
|
|
|
|
}
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
public static void start()
|
|
|
|
{
|
2015-05-04 19:10:36 +00:00
|
|
|
File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties");
|
2015-04-25 21:11:29 +00:00
|
|
|
FileReader r = null;
|
|
|
|
config = new Properties();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
r = new FileReader(configFile);
|
|
|
|
config.load(r);
|
|
|
|
}
|
|
|
|
catch(IOException e)
|
|
|
|
{
|
|
|
|
FMLLog.info("Could not load splash.properties, will create a default one");
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
IOUtils.closeQuietly(r);
|
|
|
|
}
|
|
|
|
|
2015-04-29 12:15:35 +00:00
|
|
|
// Enable if we have the flag, and there's either no optifine, or optifine has added a key to the blackboard ("optifine.ForgeSplashCompatible")
|
|
|
|
// Optifine authors - add this key to the blackboard if you feel your modifications are now compatible with this code.
|
|
|
|
enabled = getBool("enabled", true) && ( (!FMLClientHandler.instance().hasOptifine()) || Launch.blackboard.containsKey("optifine.ForgeSplashCompatible"));
|
2015-05-04 19:10:36 +00:00
|
|
|
rotate = getBool("rotate", false);
|
|
|
|
logoOffset = getInt("logoOffset", 0);
|
2015-04-25 21:11:29 +00:00
|
|
|
backgroundColor = getHex("background", 0xFFFFFF);
|
|
|
|
fontColor = getHex("font", 0x000000);
|
|
|
|
barBorderColor = getHex("barBorder", 0xC0C0C0);
|
|
|
|
barColor = getHex("bar", 0xCB3D35);
|
|
|
|
barBackgroundColor = getHex("barBackground", 0xFFFFFF);
|
|
|
|
|
|
|
|
final ResourceLocation fontLoc = new ResourceLocation(getString("fontTexture", "textures/font/ascii.png"));
|
|
|
|
final ResourceLocation logoLoc = new ResourceLocation(getString("logoTexture", "textures/gui/title/mojang.png"));
|
2015-05-04 19:10:36 +00:00
|
|
|
final ResourceLocation forgeLoc = new ResourceLocation(getString("forgeTexture", "fml:textures/gui/forge.gif"));
|
2015-04-25 21:11:29 +00:00
|
|
|
|
|
|
|
File miscPackFile = new File(Minecraft.getMinecraft().mcDataDir, getString("resourcePackPath", "resources"));
|
|
|
|
|
|
|
|
FileWriter w = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
w = new FileWriter(configFile);
|
|
|
|
config.store(w, "Splash screen properties");
|
|
|
|
}
|
|
|
|
catch(IOException e)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, e, "Could not save the splash.properties file");
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
IOUtils.closeQuietly(w);
|
|
|
|
}
|
|
|
|
|
|
|
|
miscPack = createResourcePack(miscPackFile);
|
|
|
|
|
2015-04-21 01:42:59 +00:00
|
|
|
if(!enabled) return;
|
|
|
|
// getting debug info out of the way, while we still can
|
|
|
|
FMLCommonHandler.instance().registerCrashCallable(new ICrashCallable()
|
|
|
|
{
|
|
|
|
public String call() throws Exception
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
return "' Vendor: '" + glGetString(GL_VENDOR) +
|
|
|
|
"' Version: '" + glGetString(GL_VERSION) +
|
|
|
|
"' Renderer: '" + glGetString(GL_RENDERER) +
|
2015-04-21 01:42:59 +00:00
|
|
|
"'";
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLabel()
|
|
|
|
{
|
|
|
|
return "GL info";
|
|
|
|
}
|
|
|
|
});
|
2015-05-25 19:17:33 +00:00
|
|
|
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");
|
2015-04-21 01:42:59 +00:00
|
|
|
System.out.println(report.getCompleteReport());
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
d = new SharedDrawable(Display.getDrawable());
|
|
|
|
Display.getDrawable().releaseContext();
|
|
|
|
d.makeCurrent();
|
|
|
|
}
|
|
|
|
catch (LWJGLException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
2015-04-24 02:38:32 +00:00
|
|
|
Thread mainThread = Thread.currentThread();
|
2015-04-21 01:42:59 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
public void run()
|
|
|
|
{
|
|
|
|
setGL();
|
2015-04-25 21:11:29 +00:00
|
|
|
fontTexture = new Texture(fontLoc);
|
|
|
|
logoTexture = new Texture(logoLoc);
|
|
|
|
forgeTexture = new Texture(forgeLoc);
|
2015-04-25 02:12:02 +00:00
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
fontRenderer = new SplashFontRenderer();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
2015-04-21 01:42:59 +00:00
|
|
|
while(!done)
|
|
|
|
{
|
|
|
|
ProgressBar first = null, penult = null, last = null;
|
|
|
|
Iterator<ProgressBar> i = ProgressManager.barIterator();
|
|
|
|
while(i.hasNext())
|
|
|
|
{
|
|
|
|
if(first == null) first = i.next();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
penult = last;
|
|
|
|
last = i.next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-25 02:12:02 +00:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
// matrix setup
|
|
|
|
int w = Display.getWidth();
|
|
|
|
int h = Display.getHeight();
|
2015-04-25 02:12:02 +00:00
|
|
|
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();
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
// mojang logo
|
|
|
|
setColor(backgroundColor);
|
2015-04-25 02:12:02 +00:00
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
logoTexture.bind();
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
logoTexture.texCoord(0, 0, 0);
|
|
|
|
glVertex2f(320 - 256, 240 - 256);
|
|
|
|
logoTexture.texCoord(0, 0, 1);
|
|
|
|
glVertex2f(320 - 256, 240 + 256);
|
|
|
|
logoTexture.texCoord(0, 1, 1);
|
|
|
|
glVertex2f(320 + 256, 240 + 256);
|
|
|
|
logoTexture.texCoord(0, 1, 0);
|
|
|
|
glVertex2f(320 + 256, 240 - 256);
|
|
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
2015-04-21 01:42:59 +00:00
|
|
|
|
|
|
|
// bars
|
|
|
|
if(first != null)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(320 - (float)barWidth / 2, 310, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
drawBar(first);
|
|
|
|
if(penult != null)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glTranslatef(0, barOffset, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
drawBar(penult);
|
|
|
|
}
|
|
|
|
if(last != null)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glTranslatef(0, barOffset, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
drawBar(last);
|
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
glPopMatrix();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
angle += 1;
|
|
|
|
|
|
|
|
// forge logo
|
|
|
|
setColor(backgroundColor);
|
2015-05-25 19:17:33 +00:00
|
|
|
float fw = (float)forgeTexture.getWidth() / 2 / 2;
|
|
|
|
float fh = (float)forgeTexture.getHeight() / 2 / 2;
|
2015-04-25 02:12:02 +00:00
|
|
|
if(rotate)
|
|
|
|
{
|
|
|
|
float sh = Math.max(fw, fh);
|
|
|
|
glTranslatef(320 + w/2 - sh - logoOffset, 240 + h/2 - sh - logoOffset, 0);
|
|
|
|
glRotatef(angle, 0, 0, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
glTranslatef(320 + w/2 - fw - logoOffset, 240 + h/2 - fh - logoOffset, 0);
|
|
|
|
}
|
|
|
|
int f = (angle / 10) % forgeTexture.getFrames();
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
forgeTexture.bind();
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
forgeTexture.texCoord(f, 0, 0);
|
|
|
|
glVertex2f(-fw, -fh);
|
|
|
|
forgeTexture.texCoord(f, 0, 1);
|
|
|
|
glVertex2f(-fw, fh);
|
|
|
|
forgeTexture.texCoord(f, 1, 1);
|
|
|
|
glVertex2f(fw, fh);
|
|
|
|
forgeTexture.texCoord(f, 1, 0);
|
|
|
|
glVertex2f(fw, -fh);
|
|
|
|
glEnd();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
2015-04-21 01:42:59 +00:00
|
|
|
|
2015-05-16 16:55:15 +00:00
|
|
|
// 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();
|
2015-04-21 01:42:59 +00:00
|
|
|
Display.update();
|
2015-05-16 16:55:15 +00:00
|
|
|
// 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();
|
2015-04-21 01:42:59 +00:00
|
|
|
if(pause)
|
|
|
|
{
|
|
|
|
clearGL();
|
|
|
|
setGL();
|
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
Display.sync(100);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
clearGL();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void setColor(int color)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glColor3ub((byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF));
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void drawBox(int w, int h)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glVertex2f(0, 0);
|
|
|
|
glVertex2f(0, h);
|
|
|
|
glVertex2f(w, h);
|
|
|
|
glVertex2f(w, 0);
|
|
|
|
glEnd();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void drawBar(ProgressBar b)
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
glPushMatrix();
|
2015-04-21 01:42:59 +00:00
|
|
|
// title - message
|
|
|
|
setColor(fontColor);
|
2015-04-25 02:12:02 +00:00
|
|
|
glScalef(2, 2, 1);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-04-21 01:42:59 +00:00
|
|
|
fontRenderer.drawString(b.getTitle() + " - " + b.getMessage(), 0, 0, 0x000000);
|
2015-04-25 02:12:02 +00:00
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
glPopMatrix();
|
2015-04-21 01:42:59 +00:00
|
|
|
// border
|
2015-04-25 02:12:02 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(0, textHeight2, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
setColor(barBorderColor);
|
|
|
|
drawBox(barWidth, barHeight);
|
|
|
|
// interior
|
|
|
|
setColor(barBackgroundColor);
|
2015-04-25 02:12:02 +00:00
|
|
|
glTranslatef(1, 1, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
drawBox(barWidth - 2, barHeight - 2);
|
|
|
|
// slidy part
|
|
|
|
setColor(barColor);
|
2015-06-19 05:18:27 +00:00
|
|
|
drawBox((barWidth - 2) * (b.getStep() + 1) / (b.getSteps() + 1), barHeight - 2); // Step can sometimes be 0.
|
2015-04-21 01:42:59 +00:00
|
|
|
// progress text
|
|
|
|
String progress = "" + b.getStep() + "/" + b.getSteps();
|
2015-04-25 02:12:02 +00:00
|
|
|
glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0);
|
2015-04-21 01:42:59 +00:00
|
|
|
setColor(fontColor);
|
2015-04-25 02:12:02 +00:00
|
|
|
glScalef(2, 2, 1);
|
|
|
|
glEnable(GL_TEXTURE_2D);
|
2015-04-21 01:42:59 +00:00
|
|
|
fontRenderer.drawString(progress, 0, 0, 0x000000);
|
2015-04-25 02:12:02 +00:00
|
|
|
glPopMatrix();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void setGL()
|
|
|
|
{
|
|
|
|
lock.lock();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Display.getDrawable().makeCurrent();
|
|
|
|
}
|
|
|
|
catch (LWJGLException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
glClearColor((float)((backgroundColor >> 16) & 0xFF) / 0xFF, (float)((backgroundColor >> 8) & 0xFF) / 0xFF, (float)(backgroundColor & 0xFF) / 0xFF, 1);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void clearGL()
|
|
|
|
{
|
|
|
|
Minecraft mc = Minecraft.getMinecraft();
|
|
|
|
mc.displayWidth = Display.getWidth();
|
|
|
|
mc.displayHeight = Display.getHeight();
|
|
|
|
mc.resize(mc.displayWidth, mc.displayHeight);
|
2015-04-25 02:12:02 +00:00
|
|
|
glClearColor(1, 1, 1, 1);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
|
|
glEnable(GL_ALPHA_TEST);
|
|
|
|
glAlphaFunc(GL_GREATER, .1f);
|
2015-04-21 01:42:59 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
Display.getDrawable().releaseContext();
|
|
|
|
}
|
|
|
|
catch (LWJGLException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
lock.unlock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2015-04-24 02:38:32 +00:00
|
|
|
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler()
|
|
|
|
{
|
|
|
|
public void uncaughtException(Thread t, Throwable e)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, e, "Splash thread Exception");
|
2015-04-24 22:27:57 +00:00
|
|
|
threadError = e;
|
2015-04-24 02:38:32 +00:00
|
|
|
}
|
|
|
|
});
|
2015-04-21 01:42:59 +00:00
|
|
|
thread.start();
|
2015-04-24 22:27:57 +00:00
|
|
|
checkThreadState();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
2015-04-24 22:27:57 +00:00
|
|
|
private static void checkThreadState()
|
|
|
|
{
|
|
|
|
if(thread.getState() == Thread.State.TERMINATED || threadError != null)
|
|
|
|
{
|
|
|
|
throw new IllegalStateException("Splash thread", threadError);
|
|
|
|
}
|
|
|
|
}
|
2015-04-21 01:42:59 +00:00
|
|
|
/**
|
|
|
|
* 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()
|
|
|
|
{
|
|
|
|
if(!enabled) return;
|
2015-04-24 22:27:57 +00:00
|
|
|
checkThreadState();
|
2015-04-21 01:42:59 +00:00
|
|
|
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()
|
|
|
|
{
|
|
|
|
if(!enabled) return;
|
2015-04-24 22:27:57 +00:00
|
|
|
checkThreadState();
|
2015-04-21 01:42:59 +00:00
|
|
|
pause = false;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Display.getDrawable().releaseContext();
|
|
|
|
d.makeCurrent();
|
|
|
|
}
|
|
|
|
catch (LWJGLException e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
lock.unlock();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void finish()
|
|
|
|
{
|
|
|
|
if(!enabled) return;
|
|
|
|
try
|
|
|
|
{
|
2015-06-16 22:26:00 +00:00
|
|
|
checkThreadState();
|
2015-04-21 01:42:59 +00:00
|
|
|
done = true;
|
|
|
|
thread.join();
|
|
|
|
d.releaseContext();
|
|
|
|
Display.getDrawable().makeCurrent();
|
2015-04-25 02:12:02 +00:00
|
|
|
fontTexture.delete();
|
|
|
|
logoTexture.delete();
|
|
|
|
forgeTexture.delete();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
2015-05-25 20:34:04 +00:00
|
|
|
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()
|
|
|
|
{
|
|
|
|
File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties");
|
2015-06-19 03:11:23 +00:00
|
|
|
File parent = configFile.getParentFile();
|
|
|
|
if (!parent.exists())
|
|
|
|
parent.mkdirs();
|
|
|
|
|
2015-05-25 20:34:04 +00:00
|
|
|
FileReader r = null;
|
|
|
|
enabled = false;
|
|
|
|
config.setProperty("enabled", "false");
|
|
|
|
|
|
|
|
FileWriter w = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
w = new FileWriter(configFile);
|
|
|
|
config.store(w, "Splash screen properties");
|
|
|
|
}
|
|
|
|
catch(IOException e)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, e, "Could not save the splash.properties file");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
IOUtils.closeQuietly(w);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
2015-05-25 20:34:04 +00:00
|
|
|
return true;
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
2015-04-25 21:11:29 +00:00
|
|
|
private static IResourcePack createResourcePack(File file)
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 21:11:29 +00:00
|
|
|
if(file.isDirectory())
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 21:11:29 +00:00
|
|
|
return new FolderResourcePack(file);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-04-25 21:11:29 +00:00
|
|
|
return new FileResourcePack(file);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-25 02:12:02 +00:00
|
|
|
private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024);
|
|
|
|
|
|
|
|
private static class Texture
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
private final ResourceLocation location;
|
|
|
|
private final int name;
|
|
|
|
private final int width;
|
|
|
|
private final int height;
|
|
|
|
private final int frames;
|
|
|
|
private final int size;
|
|
|
|
|
2015-04-25 21:11:29 +00:00
|
|
|
public Texture(ResourceLocation location)
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
InputStream s = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
this.location = location;
|
2015-04-25 21:11:29 +00:00
|
|
|
s = open(location);
|
2015-04-25 02:12:02 +00:00
|
|
|
ImageInputStream stream = ImageIO.createImageInputStream(s);
|
|
|
|
Iterator<ImageReader> 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);
|
2015-05-04 18:53:39 +00:00
|
|
|
synchronized(SplashProgress.class)
|
|
|
|
{
|
|
|
|
name = glGenTextures();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, name);
|
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
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);
|
|
|
|
}
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
|
|
|
|
public ResourceLocation getLocation()
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
return location;
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
|
|
|
|
public int getName()
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
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));
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class SplashFontRenderer extends FontRenderer
|
|
|
|
{
|
|
|
|
public SplashFontRenderer()
|
|
|
|
{
|
2015-04-25 02:12:02 +00:00
|
|
|
super(Minecraft.getMinecraft().gameSettings, fontTexture.getLocation(), null, false);
|
2015-04-21 01:42:59 +00:00
|
|
|
super.onResourceManagerReload(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void bindTexture(ResourceLocation location)
|
|
|
|
{
|
|
|
|
if(location != locationFontTexture) throw new IllegalArgumentException();
|
2015-04-25 02:12:02 +00:00
|
|
|
fontTexture.bind();
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected InputStream getResourceInputStream(ResourceLocation location) throws IOException
|
|
|
|
{
|
|
|
|
return Minecraft.getMinecraft().mcDefaultResourcePack.getInputStream(location);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-11 03:55:11 +00:00
|
|
|
public static void drawVanillaScreen(TextureManager renderEngine) throws LWJGLException
|
2015-04-21 01:42:59 +00:00
|
|
|
{
|
|
|
|
if(!enabled)
|
|
|
|
{
|
2015-05-11 03:55:11 +00:00
|
|
|
Minecraft.getMinecraft().drawSplashScreen(renderEngine);
|
2015-04-21 01:42:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void clearVanillaResources(TextureManager renderEngine, ResourceLocation mojangLogo)
|
|
|
|
{
|
|
|
|
if(!enabled)
|
|
|
|
{
|
|
|
|
renderEngine.deleteTexture(mojangLogo);
|
|
|
|
}
|
|
|
|
}
|
2015-04-25 02:12:02 +00:00
|
|
|
|
|
|
|
public static void checkGLError(String where)
|
|
|
|
{
|
|
|
|
int err = GL11.glGetError();
|
|
|
|
if (err != 0)
|
|
|
|
{
|
|
|
|
throw new IllegalStateException(where + ": " + GLU.gluErrorString(err));
|
|
|
|
}
|
|
|
|
}
|
2015-04-25 21:11:29 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2015-06-19 05:18:27 +00:00
|
|
|
}
|