cgraphicsasciistdiocellular-automata

Why are console graphics so slow in C?


I am trying to make s imple game using only console graphics but for some reason even when I use putc() instead of printf() it is stille extremely slow averaging 14 FPS even though all I am doing is displayinga bunch of @ sighns.

code:

#include <stdio.h>
#include <time.h>
#include <windows.h>

const int sizeX = 20;
const int sizeY = 20;

int grid[20][20];

void draw_screen() {
    system("cls");
    int y, x;
    for (y = 0; y < sizeY; y++) {
        for (x = 0; x < sizeX; x++) {
            if (grid[y][x] == 0) {
                putc('@', stdout);
            }
        }
        putc('\n', stdout);
    }
}

int main(void) {
    int x, y;
    float frameTime, FPS;

    while (1) {
        clock_t start = clock();
        draw_screen();
        clock_t stop = clock();
        frameTime = (float)(stop - start) / CLOCKS_PER_SEC;
        FPS = 1.0 / frameTime;
        printf("FPS: %f\n", FPS);
    }
}

Solution

  • There are two tricks to make console graphics fast. First don't clean the screeen every frame, just move the cursor to the top left (using SetConsoleCursorPosition). Second don't print character by character, print line by line (you can even print frame by frame). See the code below. Change the value in Sleep to have a reasonable frame rate.

    #include <stdio.h>
    #include <time.h>
    #include <windows.h>
    
    #define SIZE_X 75
    #define SIZE_Y 25
    
    int grid[SIZE_X][SIZE_Y];
    
    void draw_screen() {
     static const HANDLE std_handle = GetStdHandle(STD_OUTPUT_HANDLE);
     static const COORD top_left = {0, 0};
     SetConsoleCursorPosition(std_handle, top_left);
     
     char line[SIZE_X + 1];
     line[SIZE_X] = '\0';
     int y,x;
     for(y=0;y<SIZE_Y;y++){
      for(x=0;x<SIZE_X;x++){
       line[x] = (grid[y][x] == 0) ? '@' : ' ';
      }
      puts(line);
     }
     // Use Sleep to control frame rate, comment to get maximum frame rate
    // Sleep(33);
    }
    
    int main(void){
     int t,y,x;
     float frameTime, FPS;
     t = 0;
     while(1){
      // Simple grid update every frame
      for(y=0;y<SIZE_Y;y++){
       for(x=0;x<SIZE_X;x++){
        grid[y][x] = (t + 11*x + 7*y) & 1;
       }
      }
      ++t;
      clock_t start = clock();
      draw_screen();
      clock_t stop = clock();
      frameTime = (float)(stop - start) / CLOCKS_PER_SEC;
      FPS = 1.0 / frameTime;
      printf("FPS: %f\n",FPS);
     }
    }