Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Win32 C++ console clearing screen without blinking

I've seen some console games where the screen refreshes/clears itself without the annoying blinking. I've tried numerous solutions, here's what I got as of now:

while(true)
{
    if(screenChanged) //if something needs to be drawn on new position
    {
    COORD coordScreen = { 0, 0 };
    DWORD cCharsWritten;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD dwConSize;
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    GetConsoleScreenBufferInfo(hConsole, &csbi);
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
    FillConsoleOutputCharacter(hConsole, TEXT(' '), dwConSize, coordScreen, &cCharsWritten);
    GetConsoleScreenBufferInfo(hConsole, &csbi);
    FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
    SetConsoleCursorPosition(hConsole, coordScreen);
    } 

    ///printf all the time graphics on their right position with SetConsoleCursorPosition

    Sleep(33.3f);
}  

Still, I'm getting some minimal blinking. Anyone have any ideas?

like image 993
user1255410 Avatar asked Apr 21 '13 12:04

user1255410


2 Answers

The reason this is happening is because the display refreshes between the time you clear the console screen and actually draw to it. Usually this can happen so fast that you never see it but once in a while you do it at the right time and you experience flickering.

One great option is to create an offscreen buffer the same size and width as the console screen, do all of your text output and updating there, then send the entire buffer to the console screen using WriteConsoleOutput. Make sure you take into account that the screen buffer has to hold both text and attribute information, the same format as the console.

BOOL WINAPI WriteConsoleOutput(
  _In_     HANDLE hConsoleOutput,
  _In_     const CHAR_INFO *lpBuffer,
  _In_     COORD dwBufferSize,
  _In_     COORD dwBufferCoord,
  _Inout_  PSMALL_RECT lpWriteRegion
);
like image 127
Captain Obvlious Avatar answered Nov 19 '22 17:11

Captain Obvlious


You want to do the equivalent of double buffering. Using CreateConsoleScreenBuffer and SetConsoleActiveScreenBuffer api calls, you can modify an offscreen buffer, then switch buffers, like we used to in the bad old days :) Here's an article that explains how: http://msdn.microsoft.com/en-us/library/windows/desktop/ms685032%28v=vs.85%29.aspx

like image 44
Ben Brammer Avatar answered Nov 19 '22 19:11

Ben Brammer