diff --git a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala index 2ca3df676..2dc17b32e 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/font/DynamicFontRenderer.scala @@ -2,6 +2,8 @@ package li.cil.oc.client.renderer.font import li.cil.oc.client.renderer.font.DynamicFontRenderer.CharTexture import li.cil.oc.util.{FontUtil, RenderState} +import net.minecraft.client.Minecraft +import net.minecraft.client.resources.{ReloadableResourceManager, ResourceManager, ResourceManagerReloadListener} import org.lwjgl.BufferUtils import org.lwjgl.opengl._ @@ -11,16 +13,37 @@ import scala.collection.mutable * Font renderer that dynamically generates lookup textures by rendering a font * to it. It's pretty broken right now, and font rendering looks crappy as hell. */ -class DynamicFontRenderer extends TextureFontRenderer { - private val glyphProvider = new FontParserUnifont() +class DynamicFontRenderer extends TextureFontRenderer with ResourceManagerReloadListener { + private val glyphProvider: IGlyphProvider = new FontParserUnifont() - private val textures = mutable.ArrayBuffer(new DynamicFontRenderer.CharTexture(this)) + private val textures = mutable.ArrayBuffer.empty[CharTexture] private val charMap = mutable.Map.empty[Char, DynamicFontRenderer.CharIcon] - var activeTexture: CharTexture = textures(0) + private var activeTexture: CharTexture = _ - generateChars(basicChars.toCharArray) + initialize() + + Minecraft.getMinecraft.getResourceManager match { + case reloadable: ReloadableResourceManager => reloadable.registerReloadListener(this) + case _ => + } + + def initialize() { + for (texture <- textures) { + texture.delete() + } + textures.clear() + charMap.clear() + textures += new DynamicFontRenderer.CharTexture(this) + activeTexture = textures(0) + generateChars(basicChars.toCharArray) + } + + def onResourceManagerReload(manager: ResourceManager) { + glyphProvider.initialize() + initialize() + } override protected def charWidth = glyphProvider.getGlyphWidth @@ -40,7 +63,7 @@ class DynamicFontRenderer extends TextureFontRenderer { override protected def drawChar(tx: Float, ty: Float, char: Char) { val icon = charMap(char) - if (icon.texture == activeTexture) { + if (icon != null && icon.texture == activeTexture) { icon.draw(tx, ty) } } @@ -84,6 +107,10 @@ object DynamicFontRenderer { private var chars = 0 + def delete() { + GL11.glDeleteTextures(id) + } + def bind() { GL11.glBindTexture(GL11.GL_TEXTURE_2D, id) } diff --git a/src/main/scala/li/cil/oc/client/renderer/font/FontParserUnifont.java b/src/main/scala/li/cil/oc/client/renderer/font/FontParserUnifont.java index 68ca9f5cb..8338ed9fa 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/FontParserUnifont.java +++ b/src/main/scala/li/cil/oc/client/renderer/font/FontParserUnifont.java @@ -1,39 +1,64 @@ package li.cil.oc.client.renderer.font; import li.cil.oc.OpenComputers; +import li.cil.oc.Settings; +import net.minecraft.client.Minecraft; +import net.minecraft.util.ResourceLocation; import org.lwjgl.BufferUtils; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.ByteBuffer; +import java.util.logging.Level; public class FontParserUnifont implements IGlyphProvider { - private final byte[][] glyphs; - - public FontParserUnifont() throws Exception { - OpenComputers.log().info("Initialized Unifont glyph provider."); - glyphs = new byte[65536][]; - final InputStream font = getClass().getResourceAsStream("/assets/opencomputers/unifont.hex"); - final BufferedReader input = new BufferedReader(new InputStreamReader(font)); - String line; - int glyphCount = 0; - while ((line = input.readLine()) != null) { - glyphCount++; - final String[] info = line.split(":"); - final int charCode = Integer.parseInt(info[0], 16); - final byte[] glyph = new byte[info[1].length() >> 1]; - for (int i = 0; i < glyph.length; i++) { - glyph[i] = (byte) Integer.parseInt(info[1].substring(i * 2, i * 2 + 2), 16); - } - glyphs[charCode] = glyph; - } - OpenComputers.log().info("Loaded " + glyphCount + " glyphs."); - } - private static final byte[] b_set = {(byte) 255, (byte) 255, (byte) 255, (byte) 255}; private static final byte[] b_unset = {0, 0, 0, 0}; + private final byte[][] glyphs = new byte[65536][]; + + public FontParserUnifont() { + initialize(); + } + + @Override + public void initialize() { + for (int i = 0; i < glyphs.length; ++i) { + glyphs[i] = null; + } + final InputStream font = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "unifont.hex")).getInputStream(); + if (font == null) { + OpenComputers.log().warning("Failed opening unifont file."); + return; + } + try { + OpenComputers.log().info("Initialized Unifont glyph provider."); + final BufferedReader input = new BufferedReader(new InputStreamReader(font)); + String line; + int glyphCount = 0; + while ((line = input.readLine()) != null) { + glyphCount++; + final String[] info = line.split(":"); + final int charCode = Integer.parseInt(info[0], 16); + final byte[] glyph = new byte[info[1].length() >> 1]; + for (int i = 0; i < glyph.length; i++) { + glyph[i] = (byte) Integer.parseInt(info[1].substring(i * 2, i * 2 + 2), 16); + } + glyphs[charCode] = glyph; + } + OpenComputers.log().info("Loaded " + glyphCount + " glyphs."); + } catch (IOException ex) { + OpenComputers.log().log(Level.WARNING, "Failed loading glyphs.", ex); + } finally { + try { + font.close(); + } catch (IOException ignored) { + } + } + } + @Override public ByteBuffer getGlyph(int charCode) { if (charCode >= 65536 || glyphs[charCode] == null || glyphs[charCode].length == 0) diff --git a/src/main/scala/li/cil/oc/client/renderer/font/IGlyphProvider.java b/src/main/scala/li/cil/oc/client/renderer/font/IGlyphProvider.java index ac42a1b9e..160fd7109 100644 --- a/src/main/scala/li/cil/oc/client/renderer/font/IGlyphProvider.java +++ b/src/main/scala/li/cil/oc/client/renderer/font/IGlyphProvider.java @@ -3,7 +3,11 @@ package li.cil.oc.client.renderer.font; import java.nio.ByteBuffer; public interface IGlyphProvider { - public ByteBuffer getGlyph(int charCode); - public int getGlyphWidth(); - public int getGlyphHeight(); + public void initialize(); + + public ByteBuffer getGlyph(int charCode); + + public int getGlyphWidth(); + + public int getGlyphHeight(); }