cansi-escapeconemu

ANSI using C and Visual Studio 2015


i have a school project where we are to code a game using c onto a Zilog Z8 encore board. This is to be written using ANSI, where the board has a console output, which is read using putty over a serial interface. However, using my windows 10 computer, i would like to be able to simulate the program so i can test code without having the hardware around. The problem is, that i tried using VS 2015 where i used stdio instead of the hardware controller, and then send it to a console. But the windows command prompt does not show ANSI escape sequences. I therefore tried installing conemu, which can handle ANSI, but it does not change background color, only foreground. Here is the code i am trying to simulate:

#include <string.h>
#include <stdio.h>

#define ESC 0x1B

void fgcolor(int foreground) {
    /*  Value      foreground     Value     foreground
    ------------------------------------------------
    0        Black            8       Dark Gray
    1        Red              9       Light Red
    2        Green           10       Light Green
    3        Brown           11       Yellow
    4        Blue            12       Light Blue
    5        Purple          13       Light Purple
    6        Cyan            14       Light Cyan
    7        Light Gray      15       White
    */
    int type = 22;             // normal text
    if (foreground > 7) {
        type = 1;                // bold text
        foreground -= 8;
    }
    printf("%c[%d;%dm", ESC, type, foreground + 30);
}

void bgcolor(int background) {
    /* IMPORTANT:   When you first use this function you cannot get back to true white background in HyperTerminal.
    Why is that? Because ANSI does not support true white background (ANSI white is gray to most human eyes).
    The designers of HyperTerminal, however, preferred black text on white background, which is why
    the colors are initially like that, but when the background color is first changed there is no
    way comming back.
    Hint:        Use resetbgcolor(); clrscr(); to force HyperTerminal into gray text on black background.

    Value      Color
    ------------------
    0        Black
    1        Red
    2        Green
    3        Brown
    4        Blue
    5        Purple
    6        Cyan
    7        Gray
    */
    printf("%c[%dm", ESC, background + 40);
}

void color(int foreground, int background) {
    // combination of fgcolor() and bgcolor() - uses less bandwidth
    int type = 22;             // normal text
    if (foreground > 7) {
        type = 1;                // bold text
        foreground -= 8;
    }
    printf("%c[%d;%d;%dm", ESC, type, foreground + 30, background + 40);
}

void resetbgcolor() {
    // gray on black text, no underline, no blink, no reverse
    printf("%c[m", ESC);
}

void clrscr() {
    printf("%c[2J", ESC);
}

void clreol() {
    printf("%c[K", ESC);
}
void gotoxy(int x, int y) {
    printf("%c[%d;%dH", ESC, y, x);
}

void underline(char on) {
    if (on == 'y') {
        printf("%c[4m", ESC);
    }
    else if (on == 'n') {
        printf("%c[24m", ESC);
    }
}

void blink(char on) {
    if (on == 'y') {
        printf("%c[5m", ESC);
    }
    else if (on == 'n') {
        printf("%c[25m", ESC);
    }
}

void reverse(char on) {
    if (on == 'y') {
        printf("%c[7m", ESC);
    }
    else if (on == 'n') {
        printf("%c[27m", ESC);
    }
}
void normal() {
    printf("%c[0;22m", ESC);
}


void window(int x1, int y1, int x2, int y2, char * c, int stil) {
    int length = strlen(c);
    int i = 0;
    char kanter[2][9] = { { 218,180,195,191,179,192,196,217 },{ 201,185,204,187,186,200,205,188 } };

    if (stil != 1) {
        stil = 0;
    }


    //color(2,5);
    gotoxy(x1, y1);
    printf("%c%c", kanter[stil][0], kanter[stil][1]);
    reverse('y');
    printf("  %s", c);
    gotoxy(x1 + 4 + length, y1);
    for (i = 0; i < x2 - (x1 + 5 + length); i++) {
        printf(" ");
    }
    reverse('n');
    printf("%c%c", kanter[stil][2], kanter[stil][3]);

    for (i = y1 + 1; i < y2; i++) {
        gotoxy(x1, i);
        printf("%c", kanter[stil][4]);
        gotoxy(x2, i);
        printf("%c", kanter[stil][4]);
    }

    gotoxy(x1, y2);
    printf("%c", kanter[stil][5]);
    for (i = 0; i < x2 - x1 - 1; i++) {
        printf("%c", kanter[stil][6]);
    }
    printf("%c\n", kanter[stil][7]);

    normal();
}
void up(int x) {
    printf("%c[%dA", ESC, x);
}

void down(int x) {
    printf("%c[%dB", ESC, x);
}

void right(int x) {
    printf("%c[%dC", ESC, x);
}
void left(int x) {
    printf("%c[%dD", ESC, x);
}
void main() {
    printf("hej");
    color(2, 0);
    clrscr();
    printf("\n");
    window(3, 4, 20, 15, "hej", 1);

    up(5);
    right(5);

    //  window(21, 12, 35, 30, "Farvel", 0);


    while (1 != 2) {};

}

This code creates a window inside the console, with different background and foreground color.

Any help is appreciated.


Solution

  • Windows 10 does support ANSI sequences! Just start your .exe from a separate command prompt, rather than from within Visual Studio! The console window that Visual Studio opens does not support ANSI, but the normal cmd.exe (the standard command prompt) does.

    A useful trick when doing this is to navigate to your .exe, than type cmd into the address bar of the file explorer window (then hit enter). It will open a console that already has the current directory set to the same directory you had open in the file explorer, which is quite handy.