📄 ascscrn.cpp
字号:
if (0 == _CallScrollFunc(top,bottom,amount))
_Invalidate(Pos(0,top), Size(Width(),bottom-top+1));
};
}
// _IsOnScreen - returns 0 if pos is off the screen!
int AsciiScreen::IsOnScreen(const Pos & pos) const
{
return ((pos.X() >= 0)
&& (pos.X() < Width())
&& (pos.Y() >= 0)
&& (pos.Y() < Height()));
}
// ------------------------------------------------------------------------
// _AnsiColor - Modify the text attributes
//
void AsciiScreen::_AnsiColor(const EscapeSequence & esc)
{
int update_color = 0; // Set to 1 if color changes
if (esc.ParameterCount() == 0) // Clear attributes?
{
_useAnsiColor = 0;
_cursorIsBold = 0;
update_color = 1;
}
else
{
for (int i=0; i < esc.ParameterCount(); i++)
{
int attr = esc.Parameter(i);
if (EscapeSequence::CLEAR_ATTR == attr)
{
_cursorIsBold = 0;
update_color = 1;
}
else if (EscapeSequence::BOLD == attr)
{
_cursorIsBold = 1;
update_color = 1;
}
else if (attr >= 30 && attr <= 37) // Foreground color!
{
_useAnsiColor = 1;
_cursorAnsiColor = attr - 30;
update_color = 1;
}
else if (attr >= 40 && attr <= 47) // Background color!
{
; // Not implemented yet!
};
// Other attributes not implemented
};
};
// If color has changed, update the current color
if (update_color)
{
if (_useAnsiColor)
{
_cursorForeground = _LookupAnsiColor(_cursorIsBold,
_cursorAnsiColor);;
}
else if (_cursorIsBold)
_cursorForeground = _boldForeground;
else
_cursorForeground = _normalForeground;
};
}
// _BackSpace - move backwards a space, but not beyond the beginning of
// the line
void AsciiScreen::_BackSpace()
{
if (_cursor.X() > 0)
{
_cursor.X() -= 1;
_Invalidate(_cursor, Size(2,1));
};
}
// _CopyRow - copies row from source to target
//
// This is mainly a Scroll helper function
//
void AsciiScreen::_CopyRow(int target_row, int source_row)
{
ASSERT(target_row >= 0 && target_row < Height(), "Row off screen?");
ASSERT(source_row >= 0 && source_row < Height(), "Row off screen?");
if (source_row == target_row)
return;
void * target = &_TextElement(Pos(0,target_row));
const void * source = &_TextElement(Pos(0,source_row));
memcpy(target, source, Width() * sizeof(char));
// Move color info now (cross your fingers!)
Pos source_pos(0,source_row);
Pos target_pos(0,target_row);
for (int i = 0; i < Width(); i++)
{
_ForegroundElement(target_pos) = _ForegroundElement(source_pos);
source_pos.X() += 1;
target_pos.X() += 1;
};
}
// _ClearRows - quick and dirty
//
void AsciiScreen::_ClearRows(int top, int bottom)
{
for (int i=top; i <= bottom; i++)
_ClearRow(i);
}
// ClearRow - clears row to spaces and sets it to the current color!
void AsciiScreen::_ClearRow(int row)
{
ASSERT(row >= 0 && row < Height(), "Row must be on screen");
_Invalidate(Pos(0,row), Size(Width(),1));
// Just set the row to all spaces
memset(&_TextElement(Pos(0,row)), ' ', (Width() * sizeof(char)));
int start = (row * Width());
int end = start + Width();
for (int i = start; i < end; i++)
{
ASSERT(i < (Width() * Height()), "Index past end of array?");
ASSERT(i >= 0, "Negative array index not allowed");
_foreground[i] = _cursorForeground;
};
}
void AsciiScreen::_ClearScreen()
{
// Initialize screen memory
memset(_text, (int)' ', (Width() * Height() * sizeof(char)));
// Initialize all screen colors
for (int i=0; i < (Width() * Height()); i++)
_foreground[i] = _cursorForeground;
_Invalidate(Pos(0,0), Size(Width(),Height()));
}
void AsciiScreen::_ClearToEOL()
{
int width = Width() - _cursor.X();
memset(&_TextElement(_cursor), ' ', width * sizeof(char));
_Invalidate(_cursor, Size(width,1));
// Set Color
int start = ((_cursor.Y() * Width()) + _cursor.X()) - 1;
int end = ((_cursor.Y() + 1) * Width()) - 1;
ASSERT(end < (Width() * Height()), "Index past end of array?");
ASSERT(end >= 0, "Negative array index?");
for (int i = start; i < end; i++)
_foreground[i] = _cursorForeground;
}
void AsciiScreen::_EscapeSequence(EscapeSequence & esc)
{
// We are assuming that the sequence is comeplete, etc.
//
// Note that screen locations are 1-indexed in the escape sequences,
// so there's lots of "subtract one" here.
switch (esc.Type())
{
case EscapeSequence::CMOVE:
{
Pos new_pos(esc.Parameter(1) - 1, // Column
esc.Parameter(0) - 1); // Row
if (IsOnScreen(new_pos)) // Ignore if off screen
{
_Invalidate(_cursor, Size(1,1));
_cursor = new_pos;
_Invalidate(_cursor, Size(1,1));
};
};
break;
case EscapeSequence::SCROLL: // Set scroll region
_scrollRegionTop = esc.Parameter(0) - 1;
_scrollRegionBottom = esc.Parameter(1) - 1;
// Make sure the scroll region is on screen
if (_scrollRegionTop < 0)
_scrollRegionTop = 0;
else if (_scrollRegionTop >= Height())
_scrollRegionTop = Height() - 1;
if (_scrollRegionBottom < 0)
_scrollRegionBottom = 0;
else if (_scrollRegionBottom >= Height())
_scrollRegionBottom = Height() - 1;
if (_scrollRegionBottom < _scrollRegionTop)
_scrollRegionBottom = _scrollRegionTop;
break;
case EscapeSequence::REV_NEWLINE: // Scroll current region back one
_ReverseNewLine();
break;
case EscapeSequence::CLRSCR:
_ClearScreen();
_cursor.X() = 0;
_cursor.Y() = 0;
break;
case EscapeSequence::CLREOL:
_ClearToEOL();
break;
case EscapeSequence::ANSI_COLOR:
_AnsiColor(esc);
break;
case EscapeSequence::UNKNOWN: // Unrecoginzed by parser
case EscapeSequence::NONE: // Error, not parsed correctly
default:
ASSERT(0, "Unexpected escape sequence");
break; // Not reached
};
}
// _IncrementPos - move cursor one space
//
// This automatically wraps the cursor if at eol, and scrolls the screen
// if it is the last point on the screen
void AsciiScreen::_IncrementPos()
{
if ((_cursor.X() + 1) >= Width())
{
_Invalidate(_cursor, Size(1,1));
_NewLine();
_Invalidate(_cursor, Size(1,1));
}
else
{
_Invalidate(_cursor, Size(2,1)); // Invalidate two spaces
_cursor.X() += 1;
};
}
void AsciiScreen::_ReverseNewLine()
{
_cursor.X() = 0; // Wrap X of cursor
// Either wrap Y or scroll
if ((_cursor.Y() - 1) < _scrollRegionTop) // Need to scroll?
_ScrollCurrentRegion(-1);
else
_cursor.Y() -= 1;
ASSERT(IsOnScreen(_cursor), "Logic error moved cursor off screen");
}
// ------------------------------------------------------------------
// _CarriageReturn - cursor to column 0, no line feed.
//
void AsciiScreen::_CarriageReturn()
{
if (0 != _cursor.X()) // Don't bother if already at col 0
{
_Invalidate(_cursor, Size(1,1)); // Invalidate old pos
_cursor.X() = 0;
_Invalidate(_cursor, Size(1,1)); // Invalidate new pos
};
}
// ------------------------------------------------------------------
// _NewLine - wrap cursor
//
void AsciiScreen::_NewLine(int count)
{
_cursor.X() = 0; // Wrap X of cursor
int scroll_count = 0; // Amount to scroll current screen
while (count)
{
-- count;
// Either wrap Y or scroll
if (_cursor.Y() >= _scrollRegionBottom) // Need to scroll?
++ scroll_count;
else
_cursor.Y() += 1;
};
if (0 < scroll_count)
_ScrollCurrentRegion(scroll_count);
ASSERT(IsOnScreen(_cursor), "Cursor moved past bottom of screen");
}
// EOF //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -