Generic/ANSI console: Colour Text Output

Other misc things
Post Reply
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Generic/ANSI console: Colour Text Output

Post by RobertK »

A few questions about the colour printing capabilities of the Generic Console (and the ANSI console where GenCon is unavailable):

1. Do *all* non-monochrome targets for which z88dk provides the Generic Console support printing in colour?

2. If not, what is the easiest way to find out which do and which do not? Do I have to compile ansivt52.c for each target, or is there a simpler way?

3. Can we check programmatically (at pre-processor time) whether colour printing is available?

4. For the Alphatronic PC I have noticed that ansivt52.c compiled with the current nightly looks different from the screenshot shown on the wiki:

Image

Is this a bug, or have things changed since then?

5. On both the Coleco and PV-2000 targets, I have noticed that there seems to be no way to switch back to white foreground colour. Colour 7 seems to be some yellow / ochre colour, but white seems to be unavailable. Can we still somehow switch to white?

Image

Image

6. I'm not sure whether my approach is the best for cross-platform development. I'm doing this...

Code: Select all

// Compile with:
// zcc +alphatro -create-app -o vt52colour_alphatronic vt52colour.c

#include <stdio.h>

int main()
{

        static int COLOUR_CODES_BACKGROUND[]={
        4,        // red
        2,        // green
        1,        // blue
        5,        // magenta
        3,        // cyan
        7        // white
        };

        static int COLOUR_CODES_FOREGROUND[]={
        7,        // red background -> white
        7,        // green background -> white
        7,        // blue background -> white
        7,        // magenta background -> white
        7,        // cyan background -> white
        0        // white background -> black
        };

        static char* TEXT_COLOURS[] = {
        "%cc%c%cb%cR",         // red
        "%cc%c%cb%cG",         // green
        "%cc%c%cb%cB",         // blue
        "%cc%c%cb%cM",         // magenta
        "%cc%c%cb%cC",         // cyan
        "%cc%c%cb%cW"         // white
        };

        static int COLOUR_CODE_RESET_BACKGROUND = 0;
        static int COLOUR_CODE_RESET_FOREGROUND = 7;
        static char* TEXT_COLOUR_RESET = "%cc%c%cb%c";

        // Clear the screen
        printf("%c",12);
        printf("\x0c");

        for (int i=0;i<=5;i++)
        {
                gotoxy(5+i,5);
                printf(TEXT_COLOURS[i], 27, COLOUR_CODES_BACKGROUND[i] + 32, 27, COLOUR_CODES_FOREGROUND[i] + 32);
        }
        
        gotoxy(1,7);
        printf(TEXT_COLOUR_RESET, 27, COLOUR_CODE_RESET_BACKGROUND + 32, 27, COLOUR_CODE_RESET_FOREGROUND + 32);
        printf("press any key to exit...");
        
        fgetc_cons();

        // Clear the screen
        printf("%c",12);
        printf("\x0c");        
}
...and I would probably have to redefine the colour values for most targets. But can I maybe directly access the colour e.g. RED? Are there pre-defined colour constants for each target? Or is there some other way to make such a program more cross-platform-friendly?
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I'm away at the moment, but briefly...

All targets that are capable of colour should support colour printing for the foreground at least. Some don't support support changing the background.

In terms of colour indices, there are colour names in condo.h that should be used - these should be the standard used across all targets. If there's one that isn't mapping correctly the it's a bug. Obviously not all targets support the full range of 16 colours so approximations are made.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

Thanks, now I understand. Ansivt52.c iterates through the colours, but usually we want to set a specific colour, and here we can use textcolor() and textbackground().

Here is the same colour test as above, but this code is of course much more readable.

Code: Select all

// Compile with:
// zcc +alphatro -create-app -o vt52colour2_alphatronic vt52colour2.c

#include <conio.h>

int main()
{
        // Clear the screen
        printf("%c",12);
        printf("\x0c");
        
        gotoxy(5,5);
        
        textcolor(WHITE);
        textbackground(RED);
        printf("R");
        textcolor(WHITE);
        textbackground(GREEN);
        printf("G");
        textcolor(WHITE);
        textbackground(BLUE);
        printf("B");
        textcolor(WHITE);
        textbackground(MAGENTA);
        printf("M");
        textcolor(WHITE);
        textbackground(CYAN);
        printf("C");
        textcolor(BLACK);
        textbackground(WHITE);
        printf("W");
                        
        gotoxy(1,7);

        // reset colour
        textcolor(WHITE);
        textbackground(BLACK);

        printf("press any key to exit...");
                
        fgetc_cons();

        // Clear the screen
        printf("%c",12);
        printf("\x0c");        
}
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Excellent!

Regarding feature flags, I think it is probably worthwhile doing - let me think of a simple, maintainable way of doing it.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

I don't want to start a new topic, so I'm asking here: how do I compile the ansivt52.c sample on the MSX and SVI targets using the Generic Console?

I tried this...

Code: Select all

zcc +msx -create-app -lndos -pragma-redirect:fputc_cons=fputc_cons_generic -o ansivt52msxgc ansivt52.c

zcc +svi -create-app -pragma-redirect:fputc_cons=fputc_cons_generic -o ansivt52svigc ansivt52.c
...but the result on both targets was a broken screen.

I have been using the ANSI console for H-Tron and EPB on the MSX and SVI, but now I would like to use GenCon for MastermindRK because of its colour support.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

The 'classic' ANSI console should be able to deal with colors, (-clib=ansi).
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I tried it on an MSX last night and it worked. However, you may need to switch mode initially to ensure the hardware is in sync with with what the libraries think.
User avatar
RobertK
Well known member
Posts: 347
Joined: Mon Feb 26, 2018 12:58 pm

Post by RobertK »

stefano wrote:The 'classic' ANSI console should be able to deal with colors, (-clib=ansi).
Ok, my mistake - I forgot that I need to set the capabilities manually because IOCTL_GENCON_GET_CAPS only works with GenCon.
Colour output indeed works fine with ANSI on the MSX, no screen switching is required here.
dom wrote:I tried it on an MSX last night and it worked. However, you may need to switch mode initially to ensure the hardware is in sync with with what the libraries think.
Thanks, now it works. Through trial and error I found out that I need to switch to mode 2, in modes 0 and 1 colour output does not work.
BTW, the screen modes should be documented on the wiki platform page...

However, on the SVI I still couldn't get ansivt52.c to work. I tried switching to modes 0, 1 or 2, but every time I only got a broken screen.
User avatar
dom
Well known member
Posts: 2072
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The TMS9918 modes are documented on the TMS9918 page here: https://github.com/z88dk/z88dk/wiki/Classic-TMS9918 - I think the caps should change with the screen mode.

It looks like I removed the forcing mode on startup code from the MSX crt0 - I remember it used to switch to mode 2. I'm really not sure why though.

Thanks for the SVI heads up, I'll take a look at fixing it.
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Post by stefano »

> It looks like I removed the forcing mode on startup code from the MSX crt0 - I remember it used to switch to mode 2. I'm really not sure why though.

Initially I thoght that mode 2 was all we needed, it could have been me :)
Post Reply