CC-Tweaked/src/main/java/dan200/computercraft/core/terminal/Terminal.java

390 lines
11 KiB
Java

/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2019. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.terminal;
import dan200.computercraft.shared.util.Palette;
import net.minecraft.nbt.NBTTagCompound;
public class Terminal
{
private static final String base16 = "0123456789abcdef";
private int m_cursorX;
private int m_cursorY;
private boolean m_cursorBlink;
private int m_cursorColour;
private int m_cursorBackgroundColour;
private int m_width;
private int m_height;
private TextBuffer[] m_text;
private TextBuffer[] m_textColour;
private TextBuffer[] m_backgroundColour;
private final Palette m_palette;
private boolean m_changed;
private final Runnable onChanged;
public Terminal( int width, int height )
{
this( width, height, null );
}
public Terminal( int width, int height, Runnable changedCallback )
{
m_width = width;
m_height = height;
onChanged = changedCallback;
m_cursorColour = 0;
m_cursorBackgroundColour = 15;
m_text = new TextBuffer[m_height];
m_textColour = new TextBuffer[m_height];
m_backgroundColour = new TextBuffer[m_height];
for( int i = 0; i < m_height; i++ )
{
m_text[i] = new TextBuffer( ' ', m_width );
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
}
m_cursorX = 0;
m_cursorY = 0;
m_cursorBlink = false;
m_changed = false;
m_palette = new Palette();
}
public synchronized void reset()
{
m_cursorColour = 0;
m_cursorBackgroundColour = 15;
m_cursorX = 0;
m_cursorY = 0;
m_cursorBlink = false;
clear();
setChanged();
m_palette.resetColours();
}
public int getWidth()
{
return m_width;
}
public int getHeight()
{
return m_height;
}
public synchronized void resize( int width, int height )
{
if( width == m_width && height == m_height )
{
return;
}
int oldHeight = m_height;
int oldWidth = m_width;
TextBuffer[] oldText = m_text;
TextBuffer[] oldTextColour = m_textColour;
TextBuffer[] oldBackgroundColour = m_backgroundColour;
m_width = width;
m_height = height;
m_text = new TextBuffer[m_height];
m_textColour = new TextBuffer[m_height];
m_backgroundColour = new TextBuffer[m_height];
for( int i = 0; i < m_height; i++ )
{
if( i >= oldHeight )
{
m_text[i] = new TextBuffer( ' ', m_width );
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
}
else if( m_width == oldWidth )
{
m_text[i] = oldText[i];
m_textColour[i] = oldTextColour[i];
m_backgroundColour[i] = oldBackgroundColour[i];
}
else
{
m_text[i] = new TextBuffer( ' ', m_width );
m_textColour[i] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
m_backgroundColour[i] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
m_text[i].write( oldText[i] );
m_textColour[i].write( oldTextColour[i] );
m_backgroundColour[i].write( oldBackgroundColour[i] );
}
}
setChanged();
}
public void setCursorPos( int x, int y )
{
if( m_cursorX != x || m_cursorY != y )
{
m_cursorX = x;
m_cursorY = y;
setChanged();
}
}
public void setCursorBlink( boolean blink )
{
if( m_cursorBlink != blink )
{
m_cursorBlink = blink;
setChanged();
}
}
public void setTextColour( int colour )
{
if( m_cursorColour != colour )
{
m_cursorColour = colour;
setChanged();
}
}
public void setBackgroundColour( int colour )
{
if( m_cursorBackgroundColour != colour )
{
m_cursorBackgroundColour = colour;
setChanged();
}
}
public int getCursorX()
{
return m_cursorX;
}
public int getCursorY()
{
return m_cursorY;
}
public boolean getCursorBlink()
{
return m_cursorBlink;
}
public int getTextColour()
{
return m_cursorColour;
}
public int getBackgroundColour()
{
return m_cursorBackgroundColour;
}
public Palette getPalette()
{
return m_palette;
}
public synchronized void blit( String text, String textColour, String backgroundColour )
{
int x = m_cursorX;
int y = m_cursorY;
if( y >= 0 && y < m_height )
{
m_text[y].write( text, x );
m_textColour[y].write( textColour, x );
m_backgroundColour[y].write( backgroundColour, x );
setChanged();
}
}
public synchronized void write( String text )
{
int x = m_cursorX;
int y = m_cursorY;
if( y >= 0 && y < m_height )
{
m_text[y].write( text, x );
m_textColour[y].fill( base16.charAt( m_cursorColour ), x, x + text.length() );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ), x, x + text.length() );
setChanged();
}
}
public synchronized void scroll( int yDiff )
{
if( yDiff != 0 )
{
TextBuffer[] newText = new TextBuffer[m_height];
TextBuffer[] newTextColour = new TextBuffer[m_height];
TextBuffer[] newBackgroundColour = new TextBuffer[m_height];
for( int y = 0; y < m_height; y++ )
{
int oldY = y + yDiff;
if( oldY >= 0 && oldY < m_height )
{
newText[y] = m_text[oldY];
newTextColour[y] = m_textColour[oldY];
newBackgroundColour[y] = m_backgroundColour[oldY];
}
else
{
newText[y] = new TextBuffer( ' ', m_width );
newTextColour[y] = new TextBuffer( base16.charAt( m_cursorColour ), m_width );
newBackgroundColour[y] = new TextBuffer( base16.charAt( m_cursorBackgroundColour ), m_width );
}
}
m_text = newText;
m_textColour = newTextColour;
m_backgroundColour = newBackgroundColour;
setChanged();
}
}
public synchronized void clear()
{
for( int y = 0; y < m_height; y++ )
{
m_text[y].fill( ' ' );
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
}
setChanged();
}
public synchronized void clearLine()
{
int y = m_cursorY;
if( y >= 0 && y < m_height )
{
m_text[y].fill( ' ' );
m_textColour[y].fill( base16.charAt( m_cursorColour ) );
m_backgroundColour[y].fill( base16.charAt( m_cursorBackgroundColour ) );
setChanged();
}
}
public synchronized TextBuffer getLine( int y )
{
if( y >= 0 && y < m_height )
{
return m_text[y];
}
return null;
}
public synchronized void setLine( int y, String text, String textColour, String backgroundColour )
{
m_text[y].write( text );
m_textColour[y].write( textColour );
m_backgroundColour[y].write( backgroundColour );
setChanged();
}
public synchronized TextBuffer getTextColourLine( int y )
{
if( y >= 0 && y < m_height )
{
return m_textColour[y];
}
return null;
}
public synchronized TextBuffer getBackgroundColourLine( int y )
{
if( y >= 0 && y < m_height )
{
return m_backgroundColour[y];
}
return null;
}
/**
* @deprecated All {@code *Changed()} methods are deprecated: one should pass in a callback
* instead.
*/
@Deprecated
public final boolean getChanged()
{
return m_changed;
}
public final void setChanged()
{
m_changed = true;
if( onChanged != null ) onChanged.run();
}
public final void clearChanged()
{
m_changed = false;
}
public synchronized NBTTagCompound writeToNBT( NBTTagCompound nbt )
{
nbt.putInt( "term_cursorX", m_cursorX );
nbt.putInt( "term_cursorY", m_cursorY );
nbt.putBoolean( "term_cursorBlink", m_cursorBlink );
nbt.putInt( "term_textColour", m_cursorColour );
nbt.putInt( "term_bgColour", m_cursorBackgroundColour );
for( int n = 0; n < m_height; n++ )
{
nbt.putString( "term_text_" + n, m_text[n].toString() );
nbt.putString( "term_textColour_" + n, m_textColour[n].toString() );
nbt.putString( "term_textBgColour_" + n, m_backgroundColour[n].toString() );
}
if( m_palette != null )
{
m_palette.writeToNBT( nbt );
}
return nbt;
}
public synchronized void readFromNBT( NBTTagCompound nbt )
{
m_cursorX = nbt.getInt( "term_cursorX" );
m_cursorY = nbt.getInt( "term_cursorY" );
m_cursorBlink = nbt.getBoolean( "term_cursorBlink" );
m_cursorColour = nbt.getInt( "term_textColour" );
m_cursorBackgroundColour = nbt.getInt( "term_bgColour" );
for( int n = 0; n < m_height; n++ )
{
m_text[n].fill( ' ' );
if( nbt.contains( "term_text_" + n ) )
{
m_text[n].write( nbt.getString( "term_text_" + n ) );
}
m_textColour[n].fill( base16.charAt( m_cursorColour ) );
if( nbt.contains( "term_textColour_" + n ) )
{
m_textColour[n].write( nbt.getString( "term_textColour_" + n ) );
}
m_backgroundColour[n].fill( base16.charAt( m_cursorBackgroundColour ) );
if( nbt.contains( "term_textBgColour_" + n ) )
{
m_backgroundColour[n].write( nbt.getString( "term_textBgColour_" + n ) );
}
}
if( m_palette != null )
{
m_palette.readFromNBT( nbt );
}
setChanged();
}
}