using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using Cosmos.HAL;
namespace Cosmos.System {
///
/// Standard output stream.
///
public class Console {
///
/// Line feed.
///
private const byte LineFeed = (byte)'\n';
///
/// Carriage return.
///
private const byte CarriageReturn = (byte)'\r';
///
/// Tab.
///
private const byte Tab = (byte)'\t';
///
/// Space.
///
private const byte Space = (byte)' ';
///
/// Cursor location on X axis.
///
protected int mX = 0;
///
/// Get and set cursor location on X axis.
///
public int X {
get { return mX; }
set {
mX = value;
UpdateCursor();
}
}
///
/// Cursor location on Y axis.
///
protected int mY = 0;
///
/// Get and set cursor location on Y axis.
///
public int Y {
get { return mY; }
set {
mY = value;
UpdateCursor();
}
}
///
/// Get window width.
///
public int Cols {
get { return mText.Cols; }
}
///
/// Get window height.
///
public int Rows {
get { return mText.Rows; }
}
///
/// Text screen.
///
protected HAL.TextScreenBase mText;
///
/// Console object constructor.
///
/// Output device.
public Console(TextScreenBase textScreen)
{
if (textScreen == null)
{
mText = new TextScreen();
}
else
{
mText = textScreen;
}
}
///
/// Clear console and return cursor to (0,0).
///
public void Clear() {
mText.Clear();
mX = 0;
mY = 0;
UpdateCursor();
}
//TODO: This is slow, batch it and only do it at end of updates
///
/// Update cursor position.
///
protected void UpdateCursor() {
mText.SetCursorPos(mX, mY);
}
///
/// Scroll the console up and move crusor to the start of the line.
///
private void DoLineFeed() {
mY++;
mX = 0;
if (mY == mText.Rows) {
mText.ScrollUp();
mY--;
}
UpdateCursor();
}
///
/// Move cursor to the start of the line.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DoCarriageReturn() {
mX = 0;
UpdateCursor();
}
///
/// Print tab to the console.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DoTab()
{
Write(Space);
Write(Space);
Write(Space);
Write(Space);
}
///
/// Write char to the console.
///
/// A char to write
public void Write(byte aChar)
{
mText[mX, mY] = aChar;
mX++;
if (mX == mText.Cols)
{
DoLineFeed();
}
UpdateCursor();
}
//TODO: Optimize this
///
/// Write byte array to the console.
///
/// A byte array to write to the console.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Write(byte[] aText)
{
if (aText == null)
{
return;
}
for (int i = 0; i < aText.Length; i++)
{
switch (aText[i])
{
case LineFeed:
DoLineFeed();
break;
case CarriageReturn:
DoCarriageReturn();
break;
case Tab:
DoTab();
break;
/* Normal characters, simply write them */
default:
Write(aText[i]);
break;
}
}
}
///
/// Get and set console foreground color.
///
public ConsoleColor Foreground
{
get { return (ConsoleColor)(mText.GetColor() ^ (byte)((byte)Background << 4)); }
set { mText.SetColors(value, Background); }
}
///
/// Get and set console background color.
///
public ConsoleColor Background
{
get { return (ConsoleColor)(mText.GetColor() >> 4); }
set { mText.SetColors(Foreground, value); }
}
///
/// Get and set cursor size.
/// The value is percentage in the range 1-100.
///
/// Thrown when trying to set value out of range.
public int CursorSize
{
get { return mText.GetCursorSize(); }
set {
// Value should be a percentage from [1, 100].
if (value < 1 || value > 100)
throw new ArgumentOutOfRangeException("value", value, "CursorSize value " + value + " out of range (1 - 100)");
mText.SetCursorSize(value);
}
}
///
/// Get and set cursor visiblty.
///
public bool CursorVisible {
get { return mText.GetCursorVisible(); }
set { mText.SetCursorVisible(value); }
}
}
}