1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-26 07:03:22 +00:00

Merge pull request #197 from Lignum/colour-palettes

Modifiable terminal colour palette
This commit is contained in:
Daniel Ratcliffe 2017-05-07 17:31:14 +01:00 committed by GitHub
commit e063f5a6b8
10 changed files with 404 additions and 94 deletions

View File

@ -7,7 +7,7 @@
package dan200.computercraft.client.gui;
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
@ -16,6 +16,8 @@
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import java.util.Arrays;
public class FixedWidthFontRenderer
{
public static ResourceLocation font = new ResourceLocation( "computercraft", "textures/gui/termFont.png" );
@ -31,28 +33,50 @@ public FixedWidthFontRenderer( TextureManager textureManager )
m_textureManager = textureManager;
}
private void drawChar( VertexBuffer renderer, double x, double y, int index, int color )
private static void greyscaleify( float[] rgb )
{
Arrays.fill( rgb, ( rgb[0] + rgb[1] + rgb[2] ) / 3.0f );
}
private void drawChar( VertexBuffer renderer, double x, double y, int index, int color, Palette p, boolean greyscale )
{
int column = index % 16;
int row = index / 16;
Colour colour = Colour.values()[ 15 - color ];
renderer.pos( x, y, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT ) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
float[] colour = p.getColour( 15 - color );
if(greyscale)
{
greyscaleify( colour );
}
float r = colour[0];
float g = colour[1];
float b = colour[2];
renderer.pos( x, y, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT ) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) (row * FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).tex( (double) (column * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
renderer.pos( x + FONT_WIDTH, y + FONT_HEIGHT, 0.0 ).tex( (double) ((column + 1) * FONT_WIDTH) / 256.0, (double) ((row + 1) * FONT_HEIGHT) / 256.0 ).color( r, g, b, 1.0f ).endVertex();
}
private void drawQuad( VertexBuffer renderer, double x, double y, int color, double width )
private void drawQuad( VertexBuffer renderer, double x, double y, int color, double width, Palette p, boolean greyscale )
{
Colour colour = Colour.values()[ 15 - color ];
renderer.pos( x, y, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + width, y, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + width, y, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x, y + FONT_HEIGHT, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
renderer.pos( x + width, y + FONT_HEIGHT, 0.0 ).color( colour.getR(), colour.getG(), colour.getB(), 1.0f ).endVertex();
float[] colour = p.getColour( 15 - color );
if(greyscale)
{
greyscaleify( colour );
}
float r = colour[0];
float g = colour[1];
float b = colour[2];
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();
}
private boolean isGreyScale( int colour )
@ -60,7 +84,7 @@ private boolean isGreyScale( int colour )
return (colour == 0 || colour == 15 || colour == 7 || colour == 8);
}
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
{
// Draw the quads
Tessellator tessellator = Tessellator.getInstance();
@ -73,7 +97,7 @@ public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour,
{
colour1 = 15;
}
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize );
drawQuad( renderer, x - leftMarginSize, y, colour1, leftMarginSize, p, greyScale );
}
if( rightMarginSize > 0.0 )
{
@ -82,7 +106,7 @@ public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour,
{
colour2 = 15;
}
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize );
drawQuad( renderer, x + backgroundColour.length() * FONT_WIDTH, y, colour2, rightMarginSize, p, greyScale );
}
for( int i = 0; i < backgroundColour.length(); i++ )
{
@ -91,14 +115,14 @@ public void drawStringBackgroundPart( int x, int y, TextBuffer backgroundColour,
{
colour = 15;
}
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH );
drawQuad( renderer, x + i * FONT_WIDTH, y, colour, FONT_WIDTH, p, greyScale );
}
GlStateManager.disableTexture2D();
tessellator.draw();
GlStateManager.enableTexture2D();
}
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale )
public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColour, boolean greyScale, Palette p )
{
// Draw the quads
Tessellator tessellator = Tessellator.getInstance();
@ -119,12 +143,12 @@ public void drawStringTextPart( int x, int y, TextBuffer s, TextBuffer textColou
{
index = (int)'?';
}
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour );
drawChar( renderer, x + i * FONT_WIDTH, y, index, colour, p, greyScale );
}
tessellator.draw();
}
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale )
public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextBuffer backgroundColour, double leftMarginSize, double rightMarginSize, boolean greyScale, Palette p )
{
// Draw background
if( backgroundColour != null )
@ -133,7 +157,7 @@ public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextB
m_textureManager.bindTexture( background );
// Draw the quads
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale );
drawStringBackgroundPart( x, y, backgroundColour, leftMarginSize, rightMarginSize, greyScale, p );
}
// Draw text
@ -143,7 +167,7 @@ public void drawString( TextBuffer s, int x, int y, TextBuffer textColour, TextB
m_textureManager.bindTexture( font );
// Draw the quads
drawStringTextPart( x, y, s, textColour, greyScale );
drawStringTextPart( x, y, s, textColour, greyScale, p );
}
}

View File

@ -10,6 +10,7 @@
import dan200.computercraft.core.terminal.TextBuffer;
import dan200.computercraft.shared.media.inventory.ContainerHeldItem;
import dan200.computercraft.shared.media.items.ItemPrintout;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
@ -204,7 +205,7 @@ public void drawScreen(int mouseX, int mouseY, float f)
int lineIdx = ItemPrintout.LINES_PER_PAGE * m_page + line;
if( lineIdx >= 0 && lineIdx < m_text.length )
{
fontRenderer.drawString( m_text[lineIdx], x, y, m_colours[lineIdx], null, 0, 0, false );
fontRenderer.drawString( m_text[lineIdx], x, y, m_colours[lineIdx], null, 0, 0, false, Palette.DEFAULT );
}
y = y + FixedWidthFontRenderer.FONT_HEIGHT;
}

View File

@ -13,6 +13,7 @@
import dan200.computercraft.shared.computer.core.IComputer;
import dan200.computercraft.shared.computer.core.IComputerContainer;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager;
@ -28,7 +29,7 @@ public class WidgetTerminal extends Widget
private static final ResourceLocation background = new ResourceLocation( "computercraft", "textures/gui/termBackground.png" );
private static float TERMINATE_TIME = 0.5f;
private IComputerContainer m_computer;
private final IComputerContainer m_computer;
private float m_terminateTimer;
private float m_rebootTimer;
@ -368,24 +369,27 @@ public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY
int startX = xOrigin + getXPosition();
int startY = yOrigin + getYPosition();
// Draw the screen contents
IComputer computer = m_computer.getComputer();
Terminal terminal = (computer != null) ? computer.getTerminal() : null;
if( terminal != null )
synchronized( m_computer )
{
// Draw the terminal
boolean greyscale = !computer.isColour();
synchronized( terminal )
// Draw the screen contents
IComputer computer = m_computer.getComputer();
Terminal terminal = ( computer != null ) ? computer.getTerminal() : null;
if( terminal != null )
{
// Draw the terminal
boolean greyscale = !computer.isColour();
Palette palette = terminal.getPalette();
// Get the data from the terminal first
// Unfortunately we have to keep the lock for the whole of drawing, so the text doesn't change under us.
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer)ComputerCraft.getFixedWidthFontRenderer();
FixedWidthFontRenderer fontRenderer = (FixedWidthFontRenderer) ComputerCraft.getFixedWidthFontRenderer();
boolean tblink = m_focus && terminal.getCursorBlink() && ComputerCraft.getGlobalCursorBlink();
int tw = terminal.getWidth();
int th = terminal.getHeight();
int tx = terminal.getCursorX();
int ty = terminal.getCursorY();
int x = startX + m_leftMargin;
int y = startY + m_topMargin;
@ -393,20 +397,20 @@ public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY
TextBuffer emptyLine = new TextBuffer( ' ', tw );
if( m_topMargin > 0 )
{
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale );
fontRenderer.drawString( emptyLine, x, startY, terminal.getTextColourLine( 0 ), terminal.getBackgroundColourLine( 0 ), m_leftMargin, m_rightMargin, greyscale, palette );
}
if( m_bottomMargin > 0 )
{
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + ( th - 1 ) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale );
fontRenderer.drawString( emptyLine, x, startY + 2 * m_bottomMargin + ( th - 1 ) * FixedWidthFontRenderer.FONT_HEIGHT, terminal.getTextColourLine( th - 1 ), terminal.getBackgroundColourLine( th - 1 ), m_leftMargin, m_rightMargin, greyscale, palette );
}
// Draw lines
for( int line=0; line<th; ++line )
for( int line = 0; line < th; ++line )
{
TextBuffer text = terminal.getLine(line);
TextBuffer text = terminal.getLine( line );
TextBuffer colour = terminal.getTextColourLine( line );
TextBuffer backgroundColour = terminal.getBackgroundColourLine( line );
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale );
fontRenderer.drawString( text, x, y, colour, backgroundColour, m_leftMargin, m_rightMargin, greyscale, palette );
y += FixedWidthFontRenderer.FONT_HEIGHT;
}
@ -421,24 +425,23 @@ public void draw( Minecraft mc, int xOrigin, int yOrigin, int mouseX, int mouseY
startY + m_topMargin + FixedWidthFontRenderer.FONT_HEIGHT * ty,
cursorColour, null,
0, 0,
greyscale
greyscale,
palette
);
}
}
}
else
{
// Draw a black background
mc.getTextureManager().bindTexture( background );
Colour black = Colour.Black;
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
try
} else
{
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
}
finally
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
// Draw a black background
mc.getTextureManager().bindTexture( background );
Colour black = Colour.Black;
GlStateManager.color( black.getR(), black.getG(), black.getB(), 1.0f );
try
{
drawTexturedModalRect( startX, startY, 0, 0, getWidth(), getHeight() );
} finally
{
GlStateManager.color( 1.0f, 1.0f, 1.0f, 1.0f );
}
}
}
}

View File

@ -14,6 +14,7 @@
import dan200.computercraft.shared.peripheral.monitor.TileMonitor;
import dan200.computercraft.shared.util.Colour;
import dan200.computercraft.shared.util.DirectionUtil;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
@ -105,6 +106,8 @@ private void renderMonitorAt( TileMonitor monitor, double posX, double posY, dou
{
if( terminal != null )
{
Palette palette = terminal.getPalette();
// Allocate display lists
if( origin.m_renderDisplayList < 0 )
{
@ -145,9 +148,9 @@ private void renderMonitorAt( TileMonitor monitor, double posX, double posY, dou
{
GlStateManager.scale( 1.0, marginSquash, 1.0 );
GlStateManager.translate( 0.0, -marginYSize / marginSquash, 0.0 );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( 0 ), marginXSize, marginXSize, greyscale );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( 0 ), marginXSize, marginXSize, greyscale, palette );
GlStateManager.translate( 0.0, ( marginYSize + height * FixedWidthFontRenderer.FONT_HEIGHT ) / marginSquash, 0.0 );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( height - 1 ), marginXSize, marginXSize, greyscale );
fontRenderer.drawStringBackgroundPart( 0, 0, terminal.getBackgroundColourLine( height - 1 ), marginXSize, marginXSize, greyscale, palette );
}
finally
{
@ -161,7 +164,8 @@ private void renderMonitorAt( TileMonitor monitor, double posX, double posY, dou
0, FixedWidthFontRenderer.FONT_HEIGHT * y,
terminal.getBackgroundColourLine( y ),
marginXSize, marginXSize,
greyscale
greyscale,
palette
);
}
}
@ -187,7 +191,8 @@ private void renderMonitorAt( TileMonitor monitor, double posX, double posY, dou
0, FixedWidthFontRenderer.FONT_HEIGHT * y,
terminal.getLine( y ),
terminal.getTextColourLine( y ),
greyscale
greyscale,
palette
);
}
}
@ -217,7 +222,8 @@ private void renderMonitorAt( TileMonitor monitor, double posX, double posY, dou
FixedWidthFontRenderer.FONT_HEIGHT * cursorY,
cursorColour, null,
0, 0,
greyscale
greyscale,
palette
);
}
}

View File

@ -10,11 +10,17 @@
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.computer.IComputerEnvironment;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.util.Palette;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class TermAPI implements ILuaAPI
{
private Terminal m_terminal;
private IComputerEnvironment m_environment;
private final Terminal m_terminal;
private final IComputerEnvironment m_environment;
public TermAPI( IAPIEnvironment _environment )
{
@ -67,13 +73,17 @@ public String[] getMethodNames()
"getTextColor",
"getBackgroundColour",
"getBackgroundColor",
"blit"
"blit",
"setPaletteColour",
"setPaletteColor",
"getPaletteColour",
"getPaletteColor"
};
}
public static int parseColour( Object[] args, boolean _enableColours ) throws LuaException
public static int parseColour( Object[] args ) throws LuaException
{
if( args.length != 1 || args[0] == null || !(args[0] instanceof Double) )
if( args.length < 1 || args[0] == null || !(args[0] instanceof Double) )
{
throw new LuaException( "Expected number" );
}
@ -87,10 +97,6 @@ public static int parseColour( Object[] args, boolean _enableColours ) throws Lu
{
throw new LuaException( "Colour out of range" );
}
if( !_enableColours && (colour != 0 && colour != 15 && colour != 7 && colour != 8) )
{
throw new LuaException( "Colour not supported" );
}
return colour;
}
@ -101,6 +107,15 @@ public static Object[] encodeColour( int colour ) throws LuaException
};
}
public static void setColour( Terminal terminal, int colour, float r, float g, float b )
{
if( terminal.getPalette() != null )
{
terminal.getPalette().setColour( colour, r, g, b );
terminal.setChanged();
}
}
@Override
public Object[] callMethod( ILuaContext context, int method, Object[] args ) throws LuaException
{
@ -160,7 +175,7 @@ public Object[] callMethod( ILuaContext context, int method, Object[] args ) thr
{
throw new LuaException( "Expected boolean" );
}
boolean b = ((Boolean)args[0]).booleanValue();
boolean b = (Boolean) args[ 0 ];
synchronized( m_terminal )
{
m_terminal.setCursorBlink( b );
@ -211,7 +226,7 @@ public Object[] callMethod( ILuaContext context, int method, Object[] args ) thr
case 9:
{
// setTextColour/setTextColor
int colour = parseColour( args, m_environment.isColour() );
int colour = parseColour( args );
synchronized( m_terminal )
{
m_terminal.setTextColour( colour );
@ -222,7 +237,7 @@ public Object[] callMethod( ILuaContext context, int method, Object[] args ) thr
case 11:
{
// setBackgroundColour/setBackgroundColor
int colour = parseColour( args, m_environment.isColour() );
int colour = parseColour( args );
synchronized( m_terminal )
{
m_terminal.setBackgroundColour( colour );
@ -270,6 +285,50 @@ public Object[] callMethod( ILuaContext context, int method, Object[] args ) thr
}
return null;
}
case 19:
case 20:
{
// setPaletteColour/setPaletteColor
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double)
{
int colour = 15 - parseColour( args );
int hex = ((Double)args[1]).intValue();
float[] rgb = Palette.decodeRGB8( hex );
setColour( m_terminal, colour, rgb[0], rgb[1], rgb[2] );
return null;
}
if(args.length >= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double)
{
int colour = 15 - parseColour( args );
float r = ((Double)args[1]).floatValue();
float g = ((Double)args[2]).floatValue();
float b = ((Double)args[3]).floatValue();
setColour( m_terminal, colour, r, g, b );
return null;
}
throw new LuaException( "Expected number, number or number, number, number, number" );
}
case 21:
case 22:
{
// getPaletteColour/getPaletteColor
if(args.length < 1 || !(args[0] instanceof Double))
{
throw new LuaException( "Expected number" );
}
int colour = 15 - parseColour( args );
synchronized( m_terminal )
{
if ( m_terminal.getPalette() != null )
{
return ArrayUtils.toObject( m_terminal.getPalette().getColour( colour ) );
}
}
return null;
}
default:
{
return null;

View File

@ -5,6 +5,7 @@
*/
package dan200.computercraft.core.terminal;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.nbt.NBTTagCompound;
public class Terminal
@ -24,6 +25,8 @@ public class Terminal
private TextBuffer m_textColour[];
private TextBuffer m_backgroundColour[];
private final Palette m_palette;
private boolean m_changed;
public Terminal( int width, int height )
@ -49,6 +52,8 @@ public Terminal( int width, int height )
m_cursorBlink = false;
m_changed = false;
m_palette = new Palette();
}
public void reset()
@ -60,6 +65,7 @@ public void reset()
m_cursorBlink = false;
clear();
m_changed = true;
m_palette.resetColours();
}
public int getWidth() {
@ -178,6 +184,11 @@ public int getBackgroundColour()
return m_cursorBackgroundColour;
}
public Palette getPalette()
{
return m_palette;
}
public void blit( String text, String textColour, String backgroundColour )
{
int x = m_cursorX;
@ -296,7 +307,12 @@ public boolean getChanged()
{
return m_changed;
}
public void setChanged()
{
m_changed = true;
}
public void clearChanged()
{
m_changed = false;
@ -315,6 +331,10 @@ public NBTTagCompound writeToNBT( NBTTagCompound nbttagcompound )
nbttagcompound.setString( "term_textColour_" + n, m_textColour[n].toString() );
nbttagcompound.setString( "term_textBgColour_" + n, m_backgroundColour[ n ].toString() );
}
if(m_palette != null)
{
m_palette.writeToNBT( nbttagcompound );
}
return nbttagcompound;
}
@ -344,6 +364,10 @@ public void readFromNBT( NBTTagCompound nbttagcompound )
m_backgroundColour[n].write( nbttagcompound.getString( "term_textBgColour_" + n ) );
}
}
if (m_palette != null)
{
m_palette.readFromNBT( nbttagcompound );
}
m_changed = true;
}
}

View File

@ -11,6 +11,10 @@
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.util.Palette;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
public class MonitorPeripheral implements IPeripheral
{
@ -52,7 +56,11 @@ public String[] getMethodNames()
"getTextColor",
"getBackgroundColour",
"getBackgroundColor",
"blit"
"blit",
"setPaletteColour",
"setPaletteColor",
"getPaletteColour",
"getPaletteColor"
};
}
@ -161,7 +169,7 @@ public Object[] callMethod( IComputerAccess computer, ILuaContext context, int m
case 10:
{
// setTextColour/setTextColor
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args, m_monitor.getTerminal().isColour() );
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setTextColour( colour );
return null;
@ -170,7 +178,7 @@ public Object[] callMethod( IComputerAccess computer, ILuaContext context, int m
case 12:
{
// setBackgroundColour/setBackgroundColor
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args, m_monitor.getTerminal().isColour() );
int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args );
Terminal terminal = m_monitor.getTerminal().getTerminal();
terminal.setBackgroundColour( colour );
return null;
@ -218,6 +226,48 @@ public Object[] callMethod( IComputerAccess computer, ILuaContext context, int m
terminal.setCursorPos( terminal.getCursorX() + text.length(), terminal.getCursorY() );
return null;
}
case 20:
case 21:
{
// setPaletteColour/setPaletteColor
Terminal terminal = m_monitor.getTerminal().getTerminal();
if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double)
{
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
int hex = ((Double)args[1]).intValue();
float[] rgb = Palette.decodeRGB8( hex );
dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, rgb[0], rgb[1], rgb[2] );
return null;
}
if (args.length >= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double)
{
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
float r = ((Double)args[1]).floatValue();
float g = ((Double)args[2]).floatValue();
float b = ((Double)args[3]).floatValue();
dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, r, g, b );
return null;
}
throw new LuaException( "Expected number, number, number, number" );
}
case 22:
case 23:
{
// getPaletteColour/getPaletteColor
Terminal terminal = m_monitor.getTerminal().getTerminal();
Palette palette = terminal.getPalette();
int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args );
if( palette != null )
{
return ArrayUtils.toObject( palette.getColour( colour ) );
}
return null;
}
}
return null;
}

View File

@ -0,0 +1,99 @@
package dan200.computercraft.shared.util;
import net.minecraft.nbt.NBTTagCompound;
public class Palette
{
private static final int PALETTE_SIZE = 16;
private final float[][] colours = new float[PALETTE_SIZE][3];
public static final Palette DEFAULT = new Palette();
public Palette()
{
// Get the default palette
resetColours();
}
public void setColour(int i, float r, float g, float b)
{
if( i >= 0 && i < colours.length )
{
colours[i][0] = r;
colours[i][1] = g;
colours[i][2] = b;
}
}
public void setColour(int i, Colour colour)
{
setColour( i, colour.getR(), colour.getG(), colour.getB() );
}
public float[] getColour( int i )
{
if( i >= 0 && i < colours.length )
{
return colours[i];
}
return null;
}
public void resetColour( int i )
{
if( i >= 0 && i < colours.length )
{
setColour( i, Colour.values()[i] );
}
}
public void resetColours()
{
for(int i = 0; i < Colour.values().length; ++i)
{
resetColour( i );
}
}
public static int encodeRGB8( float[] rgb )
{
int r = (int)( rgb[0] * 255 ) & 0xFF;
int g = (int)( rgb[1] * 255 ) & 0xFF;
int b = (int)( rgb[2] * 255 ) & 0xFF;
return ( r << 16 ) | ( g << 8 ) | b;
}
public static float[] decodeRGB8( int rgb )
{
return new float[]
{
(( rgb >> 16 ) & 0xFF) / 255.0f,
(( rgb >> 8 ) & 0xFF) / 255.0f,
( rgb & 0xFF ) / 255.0f
};
}
public NBTTagCompound writeToNBT( NBTTagCompound nbt )
{
int[] rgb8 = new int[colours.length];
for(int i = 0; i < colours.length; ++i)
{
rgb8[i] = encodeRGB8( colours[i] );
}
nbt.setIntArray( "term_palette", rgb8 );
return nbt;
}
public void readFromNBT( NBTTagCompound nbt )
{
int[] rgb8 = nbt.getIntArray( "term_palette" );
for(int i = 0; i < colours.length; ++i)
{
colours[i] = decodeRGB8( rgb8[i] );
}
}
}

View File

@ -25,13 +25,26 @@ function combine( ... )
end
function subtract( colors, ... )
local r = colors
for n,c in ipairs( { ... } ) do
r = bit32.band(r, bit32.bnot(c))
end
return r
local r = colors
for n,c in ipairs( { ... } ) do
r = bit32.band(r, bit32.bnot(c))
end
return r
end
function test( colors, color )
return ((bit32.band(colors, color)) == color)
end
function rgb8( r, g, b )
if type(r) == "number" and g == nil and b == nil then
return bit32.band( bit32.rshift( r, 16 ), 0xFF ) / 255, bit32.band( bit32.rshift( r, 8 ), 0xFF ) / 255, bit32.band( r, 0xFF ) / 255
elseif type(r) == "number" and type(g) == "number" and type(b) == "number" then
return
bit32.lshift( bit32.band(r * 255, 0xFF), 16 ) +
bit32.lshift( bit32.band(g * 255, 0xFF), 8 ) +
bit32.band(b * 255 0xFF)
else
error( "Expected 1 or 3 numbers" )
end
end

View File

@ -20,6 +20,7 @@ local tHex = {
local string_rep = string.rep
local string_sub = string.sub
local table_unpack = table.unpack
function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
@ -57,6 +58,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
local nTextColor = colors.white
local nBackgroundColor = colors.black
local tLines = {}
local tPalette = {}
do
local sEmptyText = sEmptySpaceLine
local sEmptyTextColor = tEmptyColorLines[ nTextColor ]
@ -68,6 +70,11 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
backgroundColor = sEmptyBackgroundColor,
}
end
for i=0,15 do
local c = 2 ^ i
tPalette[c] = { parent.getPaletteColour( c ) }
end
end
-- Helper functions
@ -87,7 +94,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
local function updateCursorColor()
parent.setTextColor( nTextColor )
end
local function redrawLine( n )
local tLine = tLines[ n ]
parent.setCursorPos( nX, nY + n - 1 )
@ -100,6 +107,12 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
end
end
local function updatePalette()
for k,v in pairs( tPalette ) do
parent.setPaletteColour( k, v[1], v[2], v[3] )
end
end
local function internalBlit( sText, sTextColor, sBackgroundColor )
local nStart = nCursorX
local nEnd = nStart + #sText - 1
@ -257,11 +270,6 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
end
local function setTextColor( color )
if not parent.isColor() then
if color ~= colors.white and color ~= colors.black and color ~= colors.gray and color ~= colors.lightGray then
error( "Color not supported", 3 )
end
end
nTextColor = color
if bVisible then
updateCursorColor()
@ -276,12 +284,34 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
setTextColor( color )
end
local function setBackgroundColor( color )
if not parent.isColor() then
if color ~= colors.white and color ~= colors.black and color ~= colors.gray and color ~= colors.lightGray then
error( "Color not supported", 3 )
end
function window.setPaletteColour( colour, r, g, b )
local tCol
if type(colour) == "number" and type(r) == "number" and g == nil and b == nil then
tCol = { colours.rgb8( r ) }
elseif type(colour) == "number" and type(r) == "number" and type(g) == "number" and type(b) == "number" then
tCol = tPalette[ colour ]
tCol[1] = r
tCol[2] = g
tCol[3] = b
else
error("Expected number, number, number, number")
end
if bVisible then
return parent.setPaletteColour( colour, tCol[1], tCol[2], tCol[3] ) )
end
end
window.setPaletteColor = window.setPaletteColour
function window.getPaletteColour( colour )
local tCol = tPalette[ colour ]
return tCol[1], tCol[2], tCol[3]
end
window.getPaletteColor = window.getPaletteColour
local function setBackgroundColor( color )
nBackgroundColor = color
end
@ -353,6 +383,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible )
function window.redraw()
if bVisible then
redraw()
updatePalette()
updateCursorBlink()
updateCursorColor()
updateCursorPos()