2017-05-07 00:18:59 +00:00
|
|
|
/*
|
2017-05-01 13:32:39 +00:00
|
|
|
* This file is part of ComputerCraft - http://www.computercraft.info
|
2019-01-01 01:10:18 +00:00
|
|
|
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
|
2017-05-01 13:32:39 +00:00
|
|
|
* Send enquiries to dratcliffe@gmail.com
|
|
|
|
*/
|
|
|
|
|
|
|
|
package dan200.computercraft.client.gui;
|
|
|
|
|
|
|
|
import dan200.computercraft.core.terminal.TextBuffer;
|
2017-05-05 13:24:29 +00:00
|
|
|
import dan200.computercraft.shared.util.Palette;
|
2018-12-27 11:58:08 +00:00
|
|
|
import net.minecraft.client.Minecraft;
|
2017-06-12 08:14:57 +00:00
|
|
|
import net.minecraft.client.renderer.BufferBuilder;
|
2017-05-04 21:49:08 +00:00
|
|
|
import net.minecraft.client.renderer.GlStateManager;
|
2017-05-01 13:32:39 +00:00
|
|
|
import net.minecraft.client.renderer.Tessellator;
|
|
|
|
import net.minecraft.client.renderer.texture.TextureManager;
|
|
|
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
|
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import org.lwjgl.opengl.GL11;
|
|
|
|
|
2017-05-07 11:04:54 +00:00
|
|
|
import java.util.Arrays;
|
|
|
|
|
2017-05-01 13:32:39 +00:00
|
|
|
public class FixedWidthFontRenderer
|
|
|
|
{
|
2018-12-27 11:58:08 +00:00
|
|
|
private static final ResourceLocation FONT = new ResourceLocation( "computercraft", "textures/gui/term_font.png" );
|
|
|
|
public static final ResourceLocation BACKGROUND = new ResourceLocation( "computercraft", "textures/gui/term_background.png" );
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2018-12-27 11:58:08 +00:00
|
|
|
public static final int FONT_HEIGHT = 9;
|
|
|
|
public static final int FONT_WIDTH = 6;
|
|
|
|
|
|
|
|
private static FixedWidthFontRenderer instance;
|
|
|
|
|
|
|
|
public static FixedWidthFontRenderer instance()
|
|
|
|
{
|
|
|
|
if( instance != null ) return instance;
|
|
|
|
return instance = new FixedWidthFontRenderer();
|
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2018-12-30 16:14:07 +00:00
|
|
|
private final TextureManager m_textureManager;
|
2017-05-01 13:32:39 +00:00
|
|
|
|
2018-12-27 11:58:08 +00:00
|
|
|
private FixedWidthFontRenderer()
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2018-12-27 11:58:08 +00:00
|
|
|
m_textureManager = Minecraft.getMinecraft().getTextureManager();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2017-05-28 12:08:15 +00:00
|
|
|
private static void greyscaleify( double[] rgb )
|
2017-05-07 11:04:54 +00:00
|
|
|
{
|
2018-12-23 17:46:58 +00:00
|
|
|
Arrays.fill( rgb, (rgb[0] + rgb[1] + rgb[2]) / 3.0f );
|
2017-05-07 11:04:54 +00:00
|
|
|
}
|
|
|
|
|
2017-06-12 08:14:57 +00:00
|
|
|
private void drawChar( BufferBuilder renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
int column = index % 16;
|
|
|
|
int row = index / 16;
|
2017-05-05 13:24:29 +00:00
|
|
|
|
2017-05-28 12:08:15 +00:00
|
|
|
double[] colour = p.getColour( 15 - color );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( greyscale )
|
2017-05-07 11:04:54 +00:00
|
|
|
{
|
|
|
|
greyscaleify( colour );
|
|
|
|
}
|
2018-12-23 17:46:58 +00:00
|
|
|
float r = (float) colour[0];
|
|
|
|
float g = (float) colour[1];
|
|
|
|
float b = (float) colour[2];
|
2017-05-05 13:24:29 +00:00
|
|
|
|
2017-07-10 21:20:07 +00:00
|
|
|
int xStart = 1 + column * (FONT_WIDTH + 2);
|
|
|
|
int yStart = 1 + row * (FONT_HEIGHT + 2);
|
|
|
|
|
|
|
|
renderer.pos( x, y, 0.0 ).tex( xStart / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, yStart / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( xStart / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (xStart + FONT_WIDTH) / 256.0, (yStart + FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2017-06-12 08:14:57 +00:00
|
|
|
private void drawQuad( BufferBuilder renderer, double x, double y, int color, double width, Palette p, boolean greyscale )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2017-05-28 12:08:15 +00:00
|
|
|
double[] colour = p.getColour( 15 - color );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( greyscale )
|
2017-05-07 11:04:54 +00:00
|
|
|
{
|
|
|
|
greyscaleify( colour );
|
|
|
|
}
|
2018-12-23 17:46:58 +00:00
|
|
|
float r = (float) colour[0];
|
|
|
|
float g = (float) colour[1];
|
|
|
|
float b = (float) colour[2];
|
2017-05-05 13:24:29 +00:00
|
|
|
|
|
|
|
renderer.pos( x, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + width, y, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
|
|
|
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).color( r, g, b, 1.0f ).endVertex();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isGreyScale( int colour )
|
|
|
|
{
|
|
|
|
return (colour == 0 || colour == 15 || colour == 7 || colour == 8);
|
|
|
|
}
|
|
|
|
|
2017-05-05 13:24:29 +00:00
|
|
|
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
// Draw the quads
|
|
|
|
Tessellator tessellator = Tessellator.getInstance();
|
2017-06-12 08:14:57 +00:00
|
|
|
BufferBuilder renderer = tessellator.getBuffer();
|
2017-05-04 21:49:08 +00:00
|
|
|
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR );
|
2017-05-01 13:32:39 +00:00
|
|
|
if( leftMarginSize > 0.0 )
|
|
|
|
{
|
|
|
|
int colour1 = "0123456789abcdef".indexOf( backgroundColour.charAt( 0 ) );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( colour1 < 0 || (greyScale && !isGreyScale( colour1 )) )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
colour1 = 15;
|
|
|
|
}
|
2017-05-07 11:04:54 +00:00
|
|
|
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize, p, greyScale );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
if( rightMarginSize > 0.0 )
|
|
|
|
{
|
|
|
|
int colour2 = "0123456789abcdef".indexOf( backgroundColour.charAt( backgroundColour.length() - 1 ) );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( colour2 < 0 || (greyScale && !isGreyScale( colour2 )) )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
colour2 = 15;
|
|
|
|
}
|
2017-05-07 11:04:54 +00:00
|
|
|
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize, p, greyScale );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
for( int i = 0; i < backgroundColour.length(); i++ )
|
|
|
|
{
|
|
|
|
int colour = "0123456789abcdef".indexOf( backgroundColour.charAt( i ) );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( colour < 0 || (greyScale && !isGreyScale( colour )) )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
colour = 15;
|
|
|
|
}
|
2017-05-07 11:04:54 +00:00
|
|
|
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
2017-05-04 21:49:08 +00:00
|
|
|
GlStateManager.disableTexture2D();
|
2017-05-01 13:32:39 +00:00
|
|
|
tessellator.draw();
|
2017-05-04 21:49:08 +00:00
|
|
|
GlStateManager.enableTexture2D();
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2017-05-05 13:24:29 +00:00
|
|
|
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
// Draw the quads
|
|
|
|
Tessellator tessellator = Tessellator.getInstance();
|
2017-06-12 08:14:57 +00:00
|
|
|
BufferBuilder renderer = tessellator.getBuffer();
|
2017-05-04 21:43:05 +00:00
|
|
|
renderer.begin( GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_TEX_COLOR );
|
2017-05-01 13:32:39 +00:00
|
|
|
for( int i = 0; i < s.length(); i++ )
|
|
|
|
{
|
|
|
|
// Switch colour
|
|
|
|
int colour = "0123456789abcdef".indexOf( textColour.charAt( i ) );
|
2018-12-23 17:46:58 +00:00
|
|
|
if( colour < 0 || (greyScale && !isGreyScale( colour )) )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
colour = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Draw char
|
2017-09-24 05:18:20 +00:00
|
|
|
int index = s.charAt( i );
|
2017-05-01 13:32:39 +00:00
|
|
|
if( index < 0 || index > 255 )
|
|
|
|
{
|
2017-09-24 05:18:20 +00:00
|
|
|
index = '?';
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
2017-05-07 11:04:54 +00:00
|
|
|
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
tessellator.draw();
|
|
|
|
}
|
|
|
|
|
2017-05-05 13:24:29 +00:00
|
|
|
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
// Draw background
|
|
|
|
if( backgroundColour != null )
|
|
|
|
{
|
2017-05-01 14:48:44 +00:00
|
|
|
// Bind the background texture
|
2018-12-27 11:58:08 +00:00
|
|
|
m_textureManager.bindTexture( BACKGROUND );
|
2017-05-01 13:32:39 +00:00
|
|
|
|
|
|
|
// Draw the quads
|
2017-05-05 13:24:29 +00:00
|
|
|
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p );
|
2017-05-01 14:48:44 +00:00
|
|
|
}
|
2018-12-23 17:46:58 +00:00
|
|
|
|
2017-05-01 14:48:44 +00:00
|
|
|
// Draw text
|
2017-05-01 13:32:39 +00:00
|
|
|
if( s != null && textColour != null )
|
2017-05-01 14:48:44 +00:00
|
|
|
{
|
|
|
|
// Bind the font texture
|
2017-07-10 21:20:07 +00:00
|
|
|
bindFont();
|
2018-12-23 17:46:58 +00:00
|
|
|
|
2017-05-01 13:32:39 +00:00
|
|
|
// Draw the quads
|
2017-05-05 13:24:29 +00:00
|
|
|
drawStringTextPart( x, y, s, textColour, greyScale, p );
|
2017-05-01 14:48:44 +00:00
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|
|
|
|
|
2018-12-23 17:46:58 +00:00
|
|
|
public int getStringWidth( String s )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
2018-12-23 17:46:58 +00:00
|
|
|
if( s == null )
|
2017-05-01 13:32:39 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return s.length() * FONT_WIDTH;
|
|
|
|
}
|
2017-07-10 21:20:07 +00:00
|
|
|
|
|
|
|
public void bindFont()
|
|
|
|
{
|
2018-12-27 11:58:08 +00:00
|
|
|
m_textureManager.bindTexture( FONT );
|
2017-07-10 21:20:07 +00:00
|
|
|
GlStateManager.glTexParameteri( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
|
|
|
|
}
|
2017-05-01 13:32:39 +00:00
|
|
|
}
|