Using larger colour palettes

by Richard Russell, July 2010

By default, BBC BASIC for Windows uses a colour palette of 16 colours. It must be emphasised that this doesn't restrict the number of colours you can use in your program, any more than an artist's palette retricts the number of colours he can use in a painting. Because you can change the contents of the palette whenever you like, you can use any colour available with your current display settings (see for example the supplied example programs SPECTRUM.BBC and WHEEL.BBC). Typically this will be 16,777,216 different colours (all possible combinations of red, green and blue with values from 0 to 255).

However there may rarely be occasions when it would be convenient to have available a larger palette of colours. For example when adapting a program from a different version of BBC BASIC (some Acorn versions support a palette of 64 or more colours) or when using a display with a hardware palette or colour look-up table (which does restrict the number of different colours you can display at any one time).

It is possible to enable the use of a larger colour palette using the code below. Firstly the new palette must be created (in this example the palette has 128 colours, which is the largest size of palette that it is straightforward to use in BBC BASIC for Windows):

        ncols% = 128
        DIM lp{palVersion{l&,h&}, palNumEntries{l&,h&}, palPalEntry%(ncols%-1)}
        lp.palVersion.h& = 3
        lp.palNumEntries.l& = ncols% MOD 256
        lp.palNumEntries.h& = ncols% DIV 256
 
        SYS "CreatePalette", lp{} TO hpal%
        IF hpal% = 0 ERROR 100, "Couldn't create palette"
 
        SYS "SelectPalette", @memhdc%, hpal%, 0 TO oldpal%
        @hpal% = hpal%
        SYS "DeleteObject", oldpal%

Having created a new palette we can select a user-defined MODE to take advantage of the larger number of colours:

        VDU 23,22,640;512;8,16,ncols%,0

For the purposes of the example the window (client) dimensions have been set to 640×512 and the character size to 8×16 pixels; other values could be used instead. Note that the number of colours should always be set to a power-of-two (e.g. 32, 64 or 128).

Only the first 16 palette entries will be initialised (to the normal set of default colours) so the remaining entries need to be defined as required. This is done in the usual way with the COLOUR statement:

        FOR I% = 16 TO ncols%-1
          R% = RND(256)-1
          G% = RND(256)-1
          B% = RND(256)-1
          COLOUR I%,R%,G%,B%
        NEXT

Here the palette has been loaded with random colours; this is unlikely to be what you will want in practice!

Finally we can draw coloured text or graphics in the usual way, except that we can use colour numbers (palette indices) from zero to one less than the size of the palette. For example:

        FOR I% = 0 TO ncols%-1
          COLOUR I%
          PRINT "Colour ";I%
        NEXT

It is theoretically possible to extend this technique to use a 256-colour palette, but since BBC BASIC uses colour values 128-255 to indicate background colours it is not possible to use the regular COLOUR, GCOL or VDU statements to set the colour in this case. For example to set the text foreground colour use:

          @vdu.t.c& = col%
          SYS "SetTextColor", @memhdc%, @vdu.t.c&+(1<<24)