@ -57,23 +57,12 @@ void ConsoleListener::Open(int Width, int Height, const char *Title)
# ifdef _WIN32
// Open the console window and create the window handle for GetStdHandle()
AllocConsole ( ) ;
// Save the window handle that AllocConsole() created
hConsole = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
// Set the console window title
SetConsoleTitle ( Title ) ;
// Set the total l etter s pace to MAX_BYTES
int LWidth = Width / 8 ;
int LBufHeight = floor ( ( float ) ( MAX_BYTES / ( LWidth + 1 ) ) ) ;
COORD co = { LWidth , LBufHeight } ;
SetConsoleScreenBufferSize ( hConsole , co ) ;
/* Set the window size in number of letters. The height is hard coded here
because it can be changed with MoveWindow() later */
SMALL_RECT coo = { 0 , 0 , ( LWidth - 1 ) , 50 } ; // Top, left, right, bottom
SetConsoleWindowInfo ( hConsole , TRUE , & coo ) ;
// Set letter space
L etterS pace( 80 , 4000 ) ;
# endif
}
@ -104,68 +93,175 @@ bool ConsoleListener::IsOpen()
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Size
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
/*
Short documentation:
LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are dependent on each other, that's the
reason for the additional checks.
*/
void ConsoleListener : : BufferWidthHeight ( int BufferWidth , int BufferHeight , int ScreenWidth , int ScreenHeight , bool BufferFirst )
{
# ifdef _WIN32
bool SB , SW ;
if ( BufferFirst )
{
// Change screen buffer size
COORD Co = { BufferWidth , BufferHeight } ;
SB = SetConsoleScreenBufferSize ( hConsole , Co ) ;
// Change the screen buffer window size
SMALL_RECT coo = { 0 , 0 , ScreenWidth , ScreenHeight } ; // top, left, right, bottom
SW = SetConsoleWindowInfo ( hConsole , TRUE , & coo ) ;
}
else
{
// Change the screen buffer window size
SMALL_RECT coo = { 0 , 0 , ScreenWidth , ScreenHeight } ; // top, left, right, bottom
SW = SetConsoleWindowInfo ( hConsole , TRUE , & coo ) ;
// Change screen buffer size
COORD Co = { BufferWidth , BufferHeight } ;
SB = SetConsoleScreenBufferSize ( hConsole , Co ) ;
}
# endif
}
void ConsoleListener : : LetterSpace ( int Width , int Height )
{
# ifdef _WIN32
// Get console info
CONSOLE_SCREEN_BUFFER_INFO ConInfo ;
GetConsoleScreenBufferInfo ( hConsole , & ConInfo ) ;
// Change the screen buffer window size
SMALL_RECT coo = { 0 , 0 , Width , Height } ; // top, left, right, bottom
bool SW = SetConsoleWindow Info( hConsole , TRUE , & coo ) ;
//
int OldBufferWidth = ConInfo . dwSize . X ;
int OldBufferHeight = Con Info . dwSize . Y ;
int OldScreenWidth = ( ConInfo . srWindow . Right - ConInfo . srWindow . Left ) ;
int OldScreenHeight = ( ConInfo . srWindow . Bottom - ConInfo . srWindow . Top ) ;
//
int NewBufferWidth = Width ;
int NewBufferHeight = Height ;
int NewScreenWidth = NewBufferWidth - 1 ;
int NewScreenHeight = OldScreenHeight ;
// Change screen buffer to the screen buffer window size
COORD Co = { Width + 1 , Height + 1 } ;
bool SB = SetConsoleScreenBufferSize ( hConsole , Co ) ;
// Width
BufferWidthHeight ( NewBufferWidth , OldBufferHeight , NewScreenWidth , OldScreenHeight , ( NewBufferWidth > OldScreenWidth - 1 ) ) ;
// Height
BufferWidthHeight ( NewBufferWidth , NewBufferHeight , NewScreenWidth , NewScreenHeight , ( NewBufferHeight > OldScreenHeight - 1 ) ) ;
// Resize the window too
MoveWindow( GetConsoleWindow( ) , 200 , 200 , ( Width * 8 + 50 ) , ( Height * 12 + 50 ) , true ) ;
// Logging
//printf("LetterSpace(): L:%i T:%i Iconic:%i\n", ConsoleLeft, ConsoleTop, ConsoleIconic);
// MoveWindow( GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
# endif
}
# ifdef _WIN32
COORD ConsoleListener : : GetCoordinates ( int BytesRead , int BufferWidth )
{
COORD Ret = { 0 , 0 } ;
// Full rows
int Step = floor ( ( float ) BytesRead / ( float ) BufferWidth ) ;
Ret . Y + = Step ;
// Partial row
Ret . X = BytesRead - ( BufferWidth * Step ) ;
return Ret ;
}
# endif
void ConsoleListener : : PixelSpace ( int Left , int Top , int Width , int Height , bool Resize )
{
# ifdef _WIN32
// Check size
if ( Width < 8 | | Height < 12 ) return ;
bool DBef = true ;
bool DAft = true ;
std : : string SLog = " " ;
HWND hWnd = GetConsoleWindow ( ) ;
HANDLE hConsole = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
// Get console info
CONSOLE_SCREEN_BUFFER_INFO ConInfo ;
GetConsoleScreenBufferInfo ( hConsole , & ConInfo ) ;
// Letter space
int LWidth = floor ( ( float ) ( Width / 8 ) ) ;
int LHeight = floor ( ( float ) ( Height / 12 ) ) ;
int LBufHeight = floor ( ( float ) ( MAX_BYTES / ( LWidth + 1 ) ) ) ;
DWORD BufferSize = ConInfo . dwSize . X * ConInfo . dwSize . Y ;
// Check size
DWORD dwConSize = ConInfo . dwSize . X * ConInfo . dwSize . Y ;
if ( dwConSize > MAX_BYTES ) return ;
// Read the current text
char Str [ MAX_BYTES ] ;
// ---------------------------------------------------------------------
// Save the current text
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
DWORD cCharsRead = 0 ;
COORD coordScreen = { 0 , 0 } ;
ReadConsoleOutputCharacter ( hConsole , Str , dwConSize , coordScreen , & cCharsRead ) ;
// Change the screen buffer window size
SMALL_RECT coo = { 0 , 0 , LWidth , LHeight } ; // top, left, right, bottom
bool bW = SetConsoleWindowInfo ( hConsole , TRUE , & coo ) ;
// Change screen buffer to the screen buffer window size
COORD Co = { LWidth + 1 , LBufHeight } ;
bool bB = SetConsoleScreenBufferSize ( hConsole , Co ) ;
std : : vector < char * > Str ;
std : : vector < WORD * > Attr ;
// ReadConsoleOutputAttribute seems to have a limit at this level
const int MAX_BYTES = 1024 * 16 ;
int ReadBufferSize = MAX_BYTES - 32 ;
DWORD cAttrRead = ReadBufferSize ;
int BytesRead = 0 ;
int i = 0 ;
int LastAttrRead = 0 ;
while ( BytesRead < BufferSize )
{
Str . push_back ( new char [ MAX_BYTES ] ) ;
if ( ! ReadConsoleOutputCharacter ( hConsole , Str [ i ] , ReadBufferSize , coordScreen , & cCharsRead ) )
SLog + = StringFromFormat ( " WriteConsoleOutputCharacter error " ) ;
Attr . push_back ( new WORD [ MAX_BYTES ] ) ;
if ( ! ReadConsoleOutputAttribute ( hConsole , Attr [ i ] , ReadBufferSize , coordScreen , & cAttrRead ) )
SLog + = StringFromFormat ( " WriteConsoleOutputAttribute error " ) ;
// Break on error
if ( cAttrRead = = 0 ) break ;
BytesRead + = cAttrRead ;
i + + ;
coordScreen = GetCoordinates ( BytesRead , ConInfo . dwSize . X ) ;
LastAttrRead = cAttrRead ;
}
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Modify the buffer proportions
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// Letter space
int LWidth = floor ( ( float ) Width / 8.0 ) - 1.0 ;
int LHeight = floor ( ( float ) Height / 12.0 ) - 1.0 ;
int LBufWidth = LWidth + 1 ;
int LBufHeight = floor ( ( float ) BufferSize / ( float ) LBufWidth ) ;
// Change screen buffer size
LetterSpace ( LBufWidth , LBufHeight ) ;
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Redraw the text
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
ClearScreen ( true ) ;
coordScreen . Y = 0 ;
coordScreen . X = 0 ;
DWORD cCharsWritten = 0 ;
WriteConsoleOutputCharacter ( hConsole , Str , cCharsRead , coordScreen , & cCharsWritten ) ;
int BytesWritten = 0 ;
DWORD cAttrWritten = 0 ;
for ( int i = 0 ; i < Attr . size ( ) ; i + + )
{
if ( ! WriteConsoleOutputCharacter ( hConsole , Str [ i ] , ReadBufferSize , coordScreen , & cCharsWritten ) )
SLog + = StringFromFormat ( " WriteConsoleOutputCharacter error " ) ;
if ( ! WriteConsoleOutputAttribute ( hConsole , Attr [ i ] , ReadBufferSize , coordScreen , & cAttrWritten ) )
SLog + = StringFromFormat ( " WriteConsoleOutputAttribute error " ) ;
BytesWritten + = cAttrWritten ;
coordScreen = GetCoordinates ( BytesWritten , LBufWidth ) ;
}
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Update cursor
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
int OldCursor = ConInfo . dwCursorPosition . Y * ConInfo . dwSize . X + ConInfo . dwCursorPosition . X ;
COORD Coo = GetCoordinates ( OldCursor , LBufWidth ) ;
SetConsoleCursorPosition ( hConsole , Coo ) ;
// ---------------------------------------------------------------------
if ( SLog . length ( ) > 0 ) Log ( LogTypes : : LNOTICE , SLog . c_str ( ) ) ;
// Resize the window too
if ( Resize ) MoveWindow ( GetConsoleWindow ( ) , Left , Top , ( Width + 5 0) , ( Height + 50 ) , true ) ;
// Logging
//Log(LogTypes::LNOTICE, StringFromFormat("\n\n\n\nMaxBytes: %i, WxH:%ix%i, Consize: %i, Read: %i, Written: %i\n\n", MAX_BYTES, LWidth, LHeight, dwConSize, cCharsRead, cCharsWritten).c_str());
if ( Resize ) MoveWindow ( GetConsoleWindow ( ) , Left , Top , ( Width + 10 0) , Height , true ) ;
# endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -226,7 +322,7 @@ void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
}
// Clear console screen
void ConsoleListener : : ClearScreen ( )
void ConsoleListener : : ClearScreen ( bool Cursor )
{
# if defined(_WIN32)
COORD coordScreen = { 0 , 0 } ;
@ -243,7 +339,7 @@ void ConsoleListener::ClearScreen()
GetConsoleScreenBufferInfo ( hConsole , & csbi ) ;
FillConsoleOutputAttribute ( hConsole , csbi . wAttributes , dwConSize , coordScreen , & cCharsWritten ) ;
// Reset cursor
SetConsoleCursorPosition ( hConsole , coordScreen ) ;
if ( Cursor ) SetConsoleCursorPosition ( hConsole , coordScreen ) ;
# endif
}
////////////////////////////////////////////////////////////////////////////////////////////////////////