Advertisement
Guest User

Untitled

a guest
Jan 16th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.82 KB | None | 0 0
  1. /*
  2. * Minecraft Forge
  3. * Copyright (c) 2016.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation version 2.1
  8. * of the License.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19.  
  20. package net.minecraftforge.fml.client;
  21.  
  22. import static org.lwjgl.opengl.GL11.*;
  23. import static org.lwjgl.opengl.GL12.*;
  24.  
  25. import java.awt.image.BufferedImage;
  26. import java.io.File;
  27. import java.io.FileReader;
  28. import java.io.FileWriter;
  29. import java.io.IOException;
  30. import java.io.InputStream;
  31. import java.io.PrintStream;
  32. import java.io.PrintWriter;
  33. import java.lang.Thread.UncaughtExceptionHandler;
  34. import java.nio.IntBuffer;
  35. import java.util.Iterator;
  36. import java.util.Properties;
  37. import java.util.concurrent.Semaphore;
  38. import java.util.concurrent.locks.Lock;
  39. import java.util.concurrent.locks.ReentrantLock;
  40.  
  41. import javax.imageio.ImageIO;
  42. import javax.imageio.ImageReader;
  43. import javax.imageio.stream.ImageInputStream;
  44.  
  45. import net.minecraft.client.Minecraft;
  46. import net.minecraft.client.gui.FontRenderer;
  47. import net.minecraft.client.renderer.GlStateManager;
  48. import net.minecraft.client.renderer.texture.TextureManager;
  49. import net.minecraft.client.resources.DefaultResourcePack;
  50. import net.minecraft.client.resources.FileResourcePack;
  51. import net.minecraft.client.resources.FolderResourcePack;
  52. import net.minecraft.client.resources.IResource;
  53. import net.minecraft.client.resources.IResourcePack;
  54. import net.minecraft.client.resources.SimpleResource;
  55. import net.minecraft.crash.CrashReport;
  56. import net.minecraft.launchwrapper.Launch;
  57. import net.minecraft.util.ResourceLocation;
  58. import net.minecraftforge.fml.common.EnhancedRuntimeException;
  59. import net.minecraftforge.fml.common.FMLCommonHandler;
  60. import net.minecraftforge.fml.common.FMLLog;
  61. import net.minecraftforge.fml.common.ICrashCallable;
  62. import net.minecraftforge.fml.common.ProgressManager;
  63. import net.minecraftforge.fml.common.ProgressManager.ProgressBar;
  64. import net.minecraftforge.fml.common.asm.FMLSanityChecker;
  65.  
  66. import org.apache.commons.io.IOUtils;
  67. import org.apache.logging.log4j.Level;
  68. import org.lwjgl.BufferUtils;
  69. import org.lwjgl.LWJGLException;
  70. import org.lwjgl.opengl.Display;
  71. import org.lwjgl.opengl.Drawable;
  72. import org.lwjgl.opengl.SharedDrawable;
  73. import org.lwjgl.util.glu.GLU;
  74.  
  75. import net.minecraftforge.fml.common.EnhancedRuntimeException.WrappedPrintStream;
  76.  
  77. /**
  78. * Not a fully fleshed out API, may change in future MC versions.
  79. * However feel free to use and suggest additions.
  80. */
  81. @SuppressWarnings("serial")
  82. public class SplashProgress
  83. {
  84. private static Drawable d;
  85. private static volatile boolean pause = false;
  86. private static volatile boolean done = false;
  87. private static Thread thread;
  88. private static volatile Throwable threadError;
  89. private static int angle = 0;
  90. private static final Lock lock = new ReentrantLock(true);
  91. private static SplashFontRenderer fontRenderer;
  92.  
  93. private static final IResourcePack mcPack = Minecraft.getMinecraft().mcDefaultResourcePack;
  94. private static final IResourcePack fmlPack = createResourcePack(FMLSanityChecker.fmlLocation);
  95. private static IResourcePack miscPack;
  96.  
  97. private static Texture fontTexture;
  98. private static Texture logoTexture;
  99. private static Texture forgeTexture;
  100.  
  101. private static Properties config;
  102.  
  103. private static boolean enabled;
  104. private static boolean rotate;
  105. private static int logoOffset;
  106. private static int backgroundColor;
  107. private static int fontColor;
  108. private static int barBorderColor;
  109. private static int barColor;
  110. private static int barBackgroundColor;
  111. static boolean isDisplayVSyncForced = false;
  112. private static final int TIMING_FRAME_COUNT = 200;
  113. private static final int TIMING_FRAME_THRESHOLD = TIMING_FRAME_COUNT * 5 * 1000000; // 5 ms per frame, scaled to nanos
  114.  
  115. static final Semaphore mutex = new Semaphore(1);
  116.  
  117. private static String getString(String name, String def)
  118. {
  119. String value = config.getProperty(name, def);
  120. config.setProperty(name, value);
  121. return value;
  122. }
  123.  
  124. private static boolean getBool(String name, boolean def)
  125. {
  126. return Boolean.parseBoolean(getString(name, Boolean.toString(def)));
  127. }
  128.  
  129. private static int getInt(String name, int def)
  130. {
  131. return Integer.decode(getString(name, Integer.toString(def)));
  132. }
  133.  
  134. private static int getHex(String name, int def)
  135. {
  136. return Integer.decode(getString(name, "0x" + Integer.toString(def, 16).toUpperCase()));
  137. }
  138.  
  139. public static void start()
  140. {
  141. File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties");
  142.  
  143. File parent = configFile.getParentFile();
  144. if (!parent.exists())
  145. parent.mkdirs();
  146.  
  147. FileReader r = null;
  148. config = new Properties();
  149. try
  150. {
  151. r = new FileReader(configFile);
  152. config.load(r);
  153. }
  154. catch(IOException e)
  155. {
  156. FMLLog.info("Could not load splash.properties, will create a default one");
  157. }
  158. finally
  159. {
  160. IOUtils.closeQuietly(r);
  161. }
  162.  
  163. //Some system do not support this and have weird effects so we need to detect and disable by default.
  164. //The user can always force enable it if they want to take the responsibility for bugs.
  165. //For now macs derp so disable them.
  166. boolean defaultEnabled = !System.getProperty("os.name").toLowerCase().contains("mac");
  167.  
  168. // Enable if we have the flag, and there's either no optifine, or optifine has added a key to the blackboard ("optifine.ForgeSplashCompatible")
  169. // Optifine authors - add this key to the blackboard if you feel your modifications are now compatible with this code.
  170. enabled = getBool("enabled", defaultEnabled) && ( (!FMLClientHandler.instance().hasOptifine()) || Launch.blackboard.containsKey("optifine.ForgeSplashCompatible"));
  171. rotate = getBool("rotate", false);
  172. logoOffset = getInt("logoOffset", 0);
  173. backgroundColor = getHex("background", 0xFFFFFF);
  174. fontColor = getHex("font", 0x000000);
  175. barBorderColor = getHex("barBorder", 0xC0C0C0);
  176. barColor = getHex("bar", 0xCB3D35);
  177. barBackgroundColor = getHex("barBackground", 0xFFFFFF);
  178.  
  179. final ResourceLocation fontLoc = new ResourceLocation(getString("fontTexture", "textures/font/ascii.png"));
  180. final ResourceLocation logoLoc = new ResourceLocation(getString("logoTexture", "textures/gui/title/mojang.png"));
  181. final ResourceLocation forgeLoc = new ResourceLocation(getString("forgeTexture", "fml:textures/gui/forge.gif"));
  182.  
  183.  
  184. File miscPackFile = new File(Minecraft.getMinecraft().mcDataDir, getString("resourcePackPath", "resources"));
  185.  
  186. FileWriter w = null;
  187. try
  188. {
  189. w = new FileWriter(configFile);
  190. config.store(w, "Splash screen properties");
  191. }
  192. catch(IOException e)
  193. {
  194. FMLLog.log(Level.ERROR, e, "Could not save the splash.properties file");
  195. }
  196. finally
  197. {
  198. IOUtils.closeQuietly(w);
  199. }
  200.  
  201. miscPack = createResourcePack(miscPackFile);
  202.  
  203. if(!enabled) return;
  204. // getting debug info out of the way, while we still can
  205. FMLCommonHandler.instance().registerCrashCallable(new ICrashCallable()
  206. {
  207. public String call() throws Exception
  208. {
  209. return "' Vendor: '" + glGetString(GL_VENDOR) +
  210. "' Version: '" + glGetString(GL_VERSION) +
  211. "' Renderer: '" + glGetString(GL_RENDERER) +
  212. "'";
  213. }
  214.  
  215. public String getLabel()
  216. {
  217. return "GL info";
  218. }
  219. });
  220. CrashReport report = CrashReport.makeCrashReport(new Throwable()
  221. {
  222. @Override public String getMessage(){ return "This is just a prompt for computer specs to be printed. THIS IS NOT A ERROR"; }
  223. @Override public void printStackTrace(final PrintWriter s){ s.println(getMessage()); }
  224. @Override public void printStackTrace(final PrintStream s) { s.println(getMessage()); }
  225. }, "Loading screen debug info");
  226. System.out.println(report.getCompleteReport());
  227.  
  228. try
  229. {
  230. d = new SharedDrawable(Display.getDrawable());
  231. Display.getDrawable().releaseContext();
  232. d.makeCurrent();
  233. }
  234. catch (LWJGLException e)
  235. {
  236. e.printStackTrace();
  237. disableSplash(e);
  238. }
  239.  
  240. //Call this ASAP if splash is enabled so that threading doesn't cause issues later
  241. getMaxTextureSize();
  242.  
  243. //Thread mainThread = Thread.currentThread();
  244. thread = new Thread(new Runnable()
  245. {
  246. private final int barWidth = 400;
  247. private final int barHeight = 20;
  248. private final int textHeight2 = 20;
  249. private final int barOffset = 55;
  250. private long updateTiming;
  251. private long framecount;
  252. public void run()
  253. {
  254. setGL();
  255. fontTexture = new Texture(fontLoc);
  256. logoTexture = new Texture(logoLoc, false);
  257. forgeTexture = new Texture(forgeLoc);
  258. glEnable(GL_TEXTURE_2D);
  259. fontRenderer = new SplashFontRenderer();
  260. glDisable(GL_TEXTURE_2D);
  261. while(!done)
  262. {
  263. framecount++;
  264. ProgressBar first = null, penult = null, last = null;
  265. Iterator<ProgressBar> i = ProgressManager.barIterator();
  266. while(i.hasNext())
  267. {
  268. if(first == null) first = i.next();
  269. else
  270. {
  271. penult = last;
  272. last = i.next();
  273. }
  274. }
  275.  
  276. glClear(GL_COLOR_BUFFER_BIT);
  277.  
  278. // matrix setup
  279. int w = Display.getWidth();
  280. int h = Display.getHeight();
  281. glViewport(0, 0, w, h);
  282. glMatrixMode(GL_PROJECTION);
  283. glLoadIdentity();
  284. glOrtho(320 - w/2, 320 + w/2, 240 + h/2, 240 - h/2, -1, 1);
  285. glMatrixMode(GL_MODELVIEW);
  286. glLoadIdentity();
  287.  
  288. // mojang logo
  289. setColor(backgroundColor);
  290. glEnable(GL_TEXTURE_2D);
  291. logoTexture.bind();
  292. glBegin(GL_QUADS);
  293. logoTexture.texCoord(0, 0, 0);
  294. glVertex2f(320 - 256, 240 - 256);
  295. logoTexture.texCoord(0, 0, 1);
  296. glVertex2f(320 - 256, 240 + 256);
  297. logoTexture.texCoord(0, 1, 1);
  298. glVertex2f(320 + 256, 240 + 256);
  299. logoTexture.texCoord(0, 1, 0);
  300. glVertex2f(320 + 256, 240 - 256);
  301. glEnd();
  302. glDisable(GL_TEXTURE_2D);
  303.  
  304. // bars
  305. if(first != null)
  306. {
  307. glPushMatrix();
  308. glTranslatef(320 - (float)barWidth / 2, 310, 0);
  309. //drawBar(first);
  310. if(penult != null)
  311. {
  312. glTranslatef(0, barOffset, 0);
  313. //drawBar(penult);
  314. }
  315. if(last != null)
  316. {
  317. glTranslatef(0, barOffset, 0);
  318. //drawBar(last);
  319. }
  320. glPopMatrix();
  321. }
  322.  
  323. angle += 1;
  324.  
  325. // forge logo
  326. setColor(backgroundColor);
  327. float fw = (float)forgeTexture.getWidth() / 2 / 2;
  328. float fh = (float)forgeTexture.getHeight() / 2 / 2;
  329. if(rotate)
  330. {
  331. float sh = Math.max(fw, fh);
  332. glTranslatef(320 + w/2 - sh - logoOffset, 240 + h/2 - sh - logoOffset, 0);
  333. glRotatef(angle, 0, 0, 1);
  334. }
  335. else
  336. {
  337. glTranslatef(320 + w/2 - fw - logoOffset, 240 + h/2 - fh - logoOffset, 0);
  338. }
  339. int f = (angle / 10) % forgeTexture.getFrames();
  340. glEnable(GL_TEXTURE_2D);
  341. forgeTexture.bind();
  342. glBegin(GL_QUADS);
  343. forgeTexture.texCoord(f, 0, 0);
  344. glVertex2f(-fw, -fh);
  345. forgeTexture.texCoord(f, 0, 1);
  346. glVertex2f(-fw, fh);
  347. forgeTexture.texCoord(f, 1, 1);
  348. glVertex2f(fw, fh);
  349. forgeTexture.texCoord(f, 1, 0);
  350. glVertex2f(fw, -fh);
  351. glEnd();
  352. glDisable(GL_TEXTURE_2D);
  353.  
  354. // We use mutex to indicate safely to the main thread that we're taking the display global lock
  355. // So the main thread can skip processing messages while we're updating.
  356. // There are system setups where this call can pause for a while, because the GL implementation
  357. // is trying to impose a framerate or other thing is occurring. Without the mutex, the main
  358. // thread would delay waiting for the same global display lock
  359. mutex.acquireUninterruptibly();
  360. long updateStart = System.nanoTime();
  361. Display.update();
  362. // As soon as we're done, we release the mutex. The other thread can now ping the processmessages
  363. // call as often as it wants until we get get back here again
  364. long dur = System.nanoTime() - updateStart;
  365. if (framecount < TIMING_FRAME_COUNT) {
  366. updateTiming += dur;
  367. }
  368. mutex.release();
  369. if(pause)
  370. {
  371. clearGL();
  372. setGL();
  373. }
  374. // Such a hack - if the time taken is greater than 10 milliseconds, we're gonna guess that we're on a
  375. // system where vsync is forced through the swapBuffers call - so we have to force a sleep and let the
  376. // loading thread have a turn - some badly designed mods access Keyboard and therefore GlobalLock.lock
  377. // during splash screen, and mutex against the above Display.update call as a result.
  378. // 4 milliseconds is a guess - but it should be enough to trigger in most circumstances. (Maybe if
  379. // 240FPS is possible, this won't fire?)
  380. if (framecount >= TIMING_FRAME_COUNT && updateTiming > TIMING_FRAME_THRESHOLD) {
  381. if (!isDisplayVSyncForced)
  382. {
  383. isDisplayVSyncForced = true;
  384. FMLLog.log(Level.INFO, "Using alternative sync timing : %d frames of Display.update took %d nanos", TIMING_FRAME_COUNT, updateTiming);
  385. }
  386. try { Thread.sleep(16); } catch (InterruptedException ie) {}
  387. } else
  388. {
  389. if (framecount ==TIMING_FRAME_COUNT) {
  390. FMLLog.log(Level.INFO, "Using sync timing. %d frames of Display.update took %d nanos", TIMING_FRAME_COUNT, updateTiming);
  391. }
  392. Display.sync(100);
  393. }
  394. }
  395. clearGL();
  396. }
  397.  
  398. private void setColor(int color)
  399. {
  400. glColor3ub((byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF));
  401. }
  402.  
  403. private void drawBox(int w, int h)
  404. {
  405. glBegin(GL_QUADS);
  406. glVertex2f(0, 0);
  407. glVertex2f(0, h);
  408. glVertex2f(w, h);
  409. glVertex2f(w, 0);
  410. glEnd();
  411. }
  412.  
  413. /*private void drawBar(ProgressBar b)
  414. {
  415. glPushMatrix();
  416. // title - message
  417. setColor(fontColor);
  418. glScalef(2, 2, 1);
  419. glEnable(GL_TEXTURE_2D);
  420. fontRenderer.drawString(b.getTitle() + " - " + b.getMessage(), 0, 0, 0x000000);
  421. glDisable(GL_TEXTURE_2D);
  422. glPopMatrix();
  423. // border
  424. glPushMatrix();
  425. glTranslatef(0, textHeight2, 0);
  426. setColor(barBorderColor);
  427. drawBox(barWidth, barHeight);
  428. // interior
  429. setColor(barBackgroundColor);
  430. glTranslatef(1, 1, 0);
  431. drawBox(barWidth - 2, barHeight - 2);
  432. // slidy part
  433. setColor(barColor);
  434. drawBox((barWidth - 2) * (b.getStep() + 1) / (b.getSteps() + 1), barHeight - 2); // Step can sometimes be 0.
  435. // progress text
  436. String progress = "" + b.getStep() + "/" + b.getSteps();
  437. glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0);
  438. setColor(fontColor);
  439. glScalef(2, 2, 1);
  440. glEnable(GL_TEXTURE_2D);
  441. fontRenderer.drawString(progress, 0, 0, 0x000000);
  442. glPopMatrix();
  443. } */
  444.  
  445. private void setGL()
  446. {
  447. lock.lock();
  448. try
  449. {
  450. Display.getDrawable().makeCurrent();
  451. }
  452. catch (LWJGLException e)
  453. {
  454. e.printStackTrace();
  455. throw new RuntimeException(e);
  456. }
  457. glClearColor((float)((backgroundColor >> 16) & 0xFF) / 0xFF, (float)((backgroundColor >> 8) & 0xFF) / 0xFF, (float)(backgroundColor & 0xFF) / 0xFF, 1);
  458. glDisable(GL_LIGHTING);
  459. glDisable(GL_DEPTH_TEST);
  460. glEnable(GL_BLEND);
  461. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  462. }
  463.  
  464. private void clearGL()
  465. {
  466. Minecraft mc = Minecraft.getMinecraft();
  467. mc.displayWidth = Display.getWidth();
  468. mc.displayHeight = Display.getHeight();
  469. mc.resize(mc.displayWidth, mc.displayHeight);
  470. glClearColor(1, 1, 1, 1);
  471. glEnable(GL_DEPTH_TEST);
  472. glDepthFunc(GL_LEQUAL);
  473. glEnable(GL_ALPHA_TEST);
  474. glAlphaFunc(GL_GREATER, .1f);
  475. try
  476. {
  477. Display.getDrawable().releaseContext();
  478. }
  479. catch (LWJGLException e)
  480. {
  481. e.printStackTrace();
  482. throw new RuntimeException(e);
  483. }
  484. finally
  485. {
  486. lock.unlock();
  487. }
  488. }
  489. });
  490. thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler()
  491. {
  492. public void uncaughtException(Thread t, Throwable e)
  493. {
  494. FMLLog.log(Level.ERROR, e, "Splash thread Exception");
  495. threadError = e;
  496. }
  497. });
  498. thread.start();
  499. checkThreadState();
  500. }
  501.  
  502. private static int max_texture_size = -1;
  503. public static int getMaxTextureSize()
  504. {
  505. if (max_texture_size != -1) return max_texture_size;
  506. for (int i = 0x4000; i > 0; i >>= 1)
  507. {
  508. GlStateManager.glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, i, i, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
  509. if (GlStateManager.glGetTexLevelParameteri(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH) != 0)
  510. {
  511. max_texture_size = i;
  512. return i;
  513. }
  514. }
  515. return -1;
  516. }
  517.  
  518. private static void checkThreadState()
  519. {
  520. if(thread.getState() == Thread.State.TERMINATED || threadError != null)
  521. {
  522. throw new IllegalStateException("Splash thread", threadError);
  523. }
  524. }
  525. /**
  526. * Call before you need to explicitly modify GL context state during loading.
  527. * Resource loading doesn't usually require this call.
  528. * Call {@link #resume()} when you're done.
  529. * @deprecated not a stable API, will break, don't use this yet
  530. */
  531. @Deprecated
  532. public static void pause()
  533. {
  534. if(!enabled) return;
  535. checkThreadState();
  536. pause = true;
  537. lock.lock();
  538. try
  539. {
  540. d.releaseContext();
  541. Display.getDrawable().makeCurrent();
  542. }
  543. catch (LWJGLException e)
  544. {
  545. e.printStackTrace();
  546. throw new RuntimeException(e);
  547. }
  548. }
  549.  
  550. /**
  551. * @deprecated not a stable API, will break, don't use this yet
  552. */
  553. @Deprecated
  554. public static void resume()
  555. {
  556. if(!enabled) return;
  557. checkThreadState();
  558. pause = false;
  559. try
  560. {
  561. Display.getDrawable().releaseContext();
  562. d.makeCurrent();
  563. }
  564. catch (LWJGLException e)
  565. {
  566. e.printStackTrace();
  567. throw new RuntimeException(e);
  568. }
  569. lock.unlock();
  570. }
  571.  
  572. public static void finish()
  573. {
  574. if(!enabled) return;
  575. try
  576. {
  577. checkThreadState();
  578. done = true;
  579. thread.join();
  580. d.releaseContext();
  581. Display.getDrawable().makeCurrent();
  582. fontTexture.delete();
  583. logoTexture.delete();
  584. forgeTexture.delete();
  585. }
  586. catch (Exception e)
  587. {
  588. e.printStackTrace();
  589. disableSplash(e);
  590. }
  591. }
  592.  
  593. private static boolean disableSplash(Exception e)
  594. {
  595. if (disableSplash())
  596. {
  597. throw new EnhancedRuntimeException(e)
  598. {
  599. @Override
  600. protected void printStackTrace(WrappedPrintStream stream)
  601. {
  602. stream.println("SplashProgress has detected a error loading Minecraft.");
  603. stream.println("This can sometimes be caused by bad video drivers.");
  604. stream.println("We have automatically disabled the new Splash Screen in config/splash.properties.");
  605. stream.println("Try reloading minecraft before reporting any errors.");
  606. }
  607. };
  608. }
  609. else
  610. {
  611. throw new EnhancedRuntimeException(e)
  612. {
  613. @Override
  614. protected void printStackTrace(WrappedPrintStream stream)
  615. {
  616. stream.println("SplashProgress has detected a error loading Minecraft.");
  617. stream.println("This can sometimes be caused by bad video drivers.");
  618. stream.println("Please try disabling the new Splash Screen in config/splash.properties.");
  619. stream.println("After doing so, try reloading minecraft before reporting any errors.");
  620. }
  621. };
  622. }
  623. }
  624.  
  625. private static boolean disableSplash()
  626. {
  627. File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties");
  628. File parent = configFile.getParentFile();
  629. if (!parent.exists())
  630. parent.mkdirs();
  631.  
  632. enabled = false;
  633. config.setProperty("enabled", "false");
  634.  
  635. FileWriter w = null;
  636. try
  637. {
  638. w = new FileWriter(configFile);
  639. config.store(w, "Splash screen properties");
  640. }
  641. catch(IOException e)
  642. {
  643. FMLLog.log(Level.ERROR, e, "Could not save the splash.properties file");
  644. return false;
  645. }
  646. finally
  647. {
  648. IOUtils.closeQuietly(w);
  649. }
  650. return true;
  651. }
  652.  
  653. private static IResourcePack createResourcePack(File file)
  654. {
  655. if(file.isDirectory())
  656. {
  657. return new FolderResourcePack(file);
  658. }
  659. else
  660. {
  661. return new FileResourcePack(file);
  662. }
  663. }
  664.  
  665. private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024);
  666.  
  667. private static class Texture
  668. {
  669. private final ResourceLocation location;
  670. private final int name;
  671. private final int width;
  672. private final int height;
  673. private final int frames;
  674. private final int size;
  675.  
  676. public Texture(ResourceLocation location)
  677. {
  678. this(location, true);
  679. }
  680.  
  681. public Texture(ResourceLocation location, boolean allowRP)
  682. {
  683. InputStream s = null;
  684. try
  685. {
  686. this.location = location;
  687. s = open(location, allowRP);
  688. ImageInputStream stream = ImageIO.createImageInputStream(s);
  689. Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);
  690. if(!readers.hasNext()) throw new IOException("No suitable reader found for image" + location);
  691. ImageReader reader = readers.next();
  692. reader.setInput(stream);
  693. frames = reader.getNumImages(true);
  694. BufferedImage[] images = new BufferedImage[frames];
  695. for(int i = 0; i < frames; i++)
  696. {
  697. images[i] = reader.read(i);
  698. }
  699. reader.dispose();
  700. int size = 1;
  701. width = images[0].getWidth();
  702. height = images[0].getHeight();
  703. while((size / width) * (size / height) < frames) size *= 2;
  704. this.size = size;
  705. glEnable(GL_TEXTURE_2D);
  706. synchronized(SplashProgress.class)
  707. {
  708. name = glGenTextures();
  709. glBindTexture(GL_TEXTURE_2D, name);
  710. }
  711. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  712. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  713. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null);
  714. checkGLError("Texture creation");
  715. for(int i = 0; i * (size / width) < frames; i++)
  716. {
  717. for(int j = 0; i * (size / width) + j < frames && j < size / width; j++)
  718. {
  719. buf.clear();
  720. BufferedImage image = images[i * (size / width) + j];
  721. for(int k = 0; k < height; k++)
  722. {
  723. for(int l = 0; l < width; l++)
  724. {
  725. buf.put(image.getRGB(l, k));
  726. }
  727. }
  728. buf.position(0).limit(width * height);
  729. glTexSubImage2D(GL_TEXTURE_2D, 0, j * width, i * height, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf);
  730. checkGLError("Texture uploading");
  731. }
  732. }
  733. glBindTexture(GL_TEXTURE_2D, 0);
  734. glDisable(GL_TEXTURE_2D);
  735. }
  736. catch(IOException e)
  737. {
  738. e.printStackTrace();
  739. throw new RuntimeException(e);
  740. }
  741. finally
  742. {
  743. IOUtils.closeQuietly(s);
  744. }
  745. }
  746.  
  747. public ResourceLocation getLocation()
  748. {
  749. return location;
  750. }
  751.  
  752. public int getName()
  753. {
  754. return name;
  755. }
  756.  
  757. public int getWidth()
  758. {
  759. return width;
  760. }
  761.  
  762. public int getHeight()
  763. {
  764. return height;
  765. }
  766.  
  767. public int getFrames()
  768. {
  769. return frames;
  770. }
  771.  
  772. public int getSize()
  773. {
  774. return size;
  775. }
  776.  
  777. public void bind()
  778. {
  779. glBindTexture(GL_TEXTURE_2D, name);
  780. }
  781.  
  782. public void delete()
  783. {
  784. glDeleteTextures(name);
  785. }
  786.  
  787. public float getU(int frame, float u)
  788. {
  789. return width * (frame % (size / width) + u) / size;
  790. }
  791.  
  792. public float getV(int frame, float v)
  793. {
  794. return height * (frame / (size / width) + v) / size;
  795. }
  796.  
  797. public void texCoord(int frame, float u, float v)
  798. {
  799. glTexCoord2f(getU(frame, u), getV(frame, v));
  800. }
  801. }
  802.  
  803. private static class SplashFontRenderer extends FontRenderer
  804. {
  805. public SplashFontRenderer()
  806. {
  807. super(Minecraft.getMinecraft().gameSettings, fontTexture.getLocation(), null, false);
  808. super.onResourceManagerReload(null);
  809. }
  810.  
  811. @Override
  812. protected void bindTexture(ResourceLocation location)
  813. {
  814. if(location != locationFontTexture) throw new IllegalArgumentException();
  815. fontTexture.bind();
  816. }
  817.  
  818. @Override
  819. protected IResource getResource(ResourceLocation location) throws IOException
  820. {
  821. DefaultResourcePack pack = Minecraft.getMinecraft().mcDefaultResourcePack;
  822. return new SimpleResource(pack.getPackName(), location, pack.getInputStream(location), null, null);
  823. }
  824. }
  825.  
  826. public static void drawVanillaScreen(TextureManager renderEngine) throws LWJGLException
  827. {
  828. if(!enabled)
  829. {
  830. Minecraft.getMinecraft().drawSplashScreen(renderEngine);
  831. }
  832. }
  833.  
  834. public static void clearVanillaResources(TextureManager renderEngine, ResourceLocation mojangLogo)
  835. {
  836. if(!enabled)
  837. {
  838. renderEngine.deleteTexture(mojangLogo);
  839. }
  840. }
  841.  
  842. public static void checkGLError(String where)
  843. {
  844. int err = glGetError();
  845. if (err != 0)
  846. {
  847. throw new IllegalStateException(where + ": " + GLU.gluErrorString(err));
  848. }
  849. }
  850.  
  851. private static InputStream open(ResourceLocation loc, boolean allowRP) throws IOException
  852. {
  853. if (!allowRP)
  854. return mcPack.getInputStream(loc);
  855.  
  856. if(miscPack.resourceExists(loc))
  857. {
  858. return miscPack.getInputStream(loc);
  859. }
  860. else if(fmlPack.resourceExists(loc))
  861. {
  862. return fmlPack.getInputStream(loc);
  863. }
  864. return mcPack.getInputStream(loc);
  865. }
  866. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement