Console image flickering in windows 10

308 views Asked by At

The following code works as expected in windows xp, but in windows 10 the image starts flickering. How do I make it work in windows 10?

#include <windows.h>
#include <ctime>
#include <vector>

#define xMax 180
#define yMax 45
#define Fps 250

class dbconsole
{
private:
    int width, height, FPS, delay;
    HANDLE h0, h1;
    std::vector<CHAR_INFO> chiBuffer;
    bool curBuffer;
    int drawingTimer;

    void preparebuffer(HANDLE &h)
    {
        CONSOLE_CURSOR_INFO cursor = {false, 1};
        SMALL_RECT windowRectangle = {0,0,width-1,height-1};
        h = CreateConsoleScreenBuffer(
                GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL,
                CONSOLE_TEXTMODE_BUFFER,
                NULL);
        SetConsoleCursorInfo(h, &cursor);
        SetConsoleScreenBufferSize (h, {width,height});
        SetConsoleWindowInfo(h,true,&windowRectangle);
    }

public:

    dbconsole(int Width, int Height, int fps)
    {
        chiBuffer.reserve(Width*Height);
        width = Width;
        height = Height;
        FPS = fps;
        preparebuffer(h0);
        preparebuffer(h1);
        curBuffer = 0;
        drawingTimer = clock();
        for (int i = 0; i < xMax; i++) for (int j = 0; j < yMax; j++) chiBuffer[i+width*j] = {'t',16};
    }

    void depict()
    {
        SMALL_RECT srctWriteRect;
        srctWriteRect.Top = 0;
        srctWriteRect.Left = 0;
        srctWriteRect.Bottom = height-1;
        srctWriteRect.Right = width-1;
        if ((clock()-drawingTimer)*FPS>CLOCKS_PER_SEC)
        {
            if (curBuffer)
            {
                WriteConsoleOutput(h0, &chiBuffer[0], {width,height}, {0,0}, &srctWriteRect);
                SetConsoleActiveScreenBuffer(h0);
            }
            else
            {
                WriteConsoleOutput(h1, &chiBuffer[0], {width,height}, {0,0}, &srctWriteRect);
                SetConsoleActiveScreenBuffer(h1);
            }
            curBuffer=!curBuffer;
            drawingTimer = clock();
        }
    }

};

int main(void)
{
    dbconsole myConsole = dbconsole(xMax,yMax,Fps);
    while (true) myConsole.depict();
}

I want the program to show black letters 't' on blue background, but with no flickering and with double buffering

1

There are 1 answers

1
grek40 On

Ok, after looking into the problem anyway, here is an answer.

CONSOLE_CURSOR_INFO is defined as first DWORD dwSize and second BOOL bVisible but you use it as if first and second member where the other way round. Consequently, SetConsoleCursorInfo fails with return value 0 and GetLastError returns 87, which is ERROR_INVALID_PARAMETER (See error codes)

Correctly disabling the cursor should solve the problem, though I don't have windows 10 available for testing.