AT THE END OF THE RAINBOW

This month we conclude our examination of the 256 colour modes with utilities by Richard Kirby and Keith McAlpine. Mike Williams sets the scene and explains the use of the palette registers to re-define colours.

This month I want to describe three useful programs all related to the 256 colour modes (modes 11, 13 and 15). We looked at this subject in some detail last month using the default palette and resulting colours. The first program, Colours2 by Richard Kirby, displays all 256 default colours on the screen in a way that makes choice of colour and corresponding GCOL and TINT parameters much simpler than either of last month's programs. Type the program in and save it to disc before you try it out. Use the mouse to select any of the 256 colours on the screen, and that colour will be displayed as a larger colour panel (allowing a better assessment of your choice) together with the GCOL and TINT numbers for reference.

10 REM >Colours2
20 REM Program Colour Identifier
30 REM Version A1.3
40 REM Author Richard Kirby
50 REM RISC User March 1988
60 REM Program Subject to Copyright
70 :
80 MODE 15:OFF:*POINTER 1
90 ON ERROR GOTO 230
100 PROCcolours:PROCsquare
110 REPEAT:REPEAT
120 MOUSE x,y,button
130 UNTILbutton>0 AND ((x>128 AND x<1152) AND (y>736 AND y<992))
140 colour=FNcolour(x,y)
150 tint=FNtint(x,y)
160 COLOUR 191 TINT 192
170 COLOUR 0 TINT 0
180 PRINTTAB(27,16)"COLOUR ";colour;" TINT ";tint;SPC3
190 GCOL colour TINT tint
200 RECTANGLEFILL128,36,1024,256
210 UNTIL FALSE
220 :
230 ON ERROR OFF:MODE 3
240 REPORT:PRINT" at line ";ERL:END
250 :
260 DEFPROCcolours
270 col%=128
280 FOR rows%=1 TO 8
290 PRINTTAB(8,rows%);
300 FOR columns%=1 TO 8
310 FOR tint%=0 TO 3
320 COLOUR col% TINT tint%*64
330 PRINT SPC2;
340 NEXT:col%=col%+1:NEXT
350 IF rows%=4 THEN col%=128
360 col%+=8
370 NEXT:GCOL 63 TINT 192
380 RECTANGLE128,736,1024,256
390 RECTANGLE126,32,1028,264
400 ENDPROC
410 :
420 DEFFNtint(x,y)=TINT(x,y)
430 :
440 DEFFNcolour(x,y)=POINT(x,y)
450 :
460 DEFPROCsquare
470 GCOL 42 TINT 0
480 RECTANGLE FILL 400,400,400,200
490 GCOL63 TINT 0:MOVE408,408
500 MOVE792,408:PLOT85,792,592
510 GCOL0 TINT 0:MOVE408,592
520 MOVE792,592:PLOT85,408,408
530 GCOL63 TINT 192
540 RECTANGLEFILL420,420,360,160
550 COLOUR128 TINT 0:COLOUR63
560 PRINTTAB(23,10)"Colour Identifier for RISC User"
570 PRINTTAB(29,11)"By Richard Kirby"
580 ENDPROC

REDEFINING THE PALETTE

The palette registers (all 16) have been set to give a reasonable range of colours by default, but by redefining one or more of the palette registers it is possible to select any of the Archimedes' 4096 colours as one of the 256 in current use. However, BE WARNED: understanding how this works is enough to make a strong man tremble, and it also destroys the colour relationship of the GCOL and TINT numbers described last month.

The reason for all the angst is that there are only 16 palette registers to control palette definitions for 256 colours. As a result, each palette register controls the appearance of 16 different shades. Changing a palette register will change ALL 16 related shades. In principle, the eight-bit byte stored in screen memory to specify the colour of a pixel is treated as two four bit nibbles. The top four bits (1 bit red, 2 bits green, 1 bit blue) are sent directly to the screen D to A converters (digital to analogue), while the bottom four bits form an index or pointer to a palette register which then supplies the remaining 8 bits of colour information needed (3 bits red, 2 green, 3 blue).

As a first demonstration of some of the detail involved, the following short program (TemPal3) uses palette register 1 to cycle through all 4096 colours. Three nested FOR loops (line 150) increment in turn the levels of blue, green and red using up to 16 parts each of these three basic colours (16*16*16 = 4096).

Lines 160 to 180 determine the top four bits of the 8 bit colour number (1 bit blue, 2 bits green, 1 bit red), and line 190 shows how the GCOL number (col%) is then determined from these three values. Line 200 uses a VDU19 call to redefine palette register 1 with the appropriate amounts of red, green and blue (you can also use COLOUR 1,r,g,b), while in line 210 GCOL selects the colour and TINT selects the palette register to be used.

Type in and save the program. When you run it, it will cycle through all 4096 colours as indicated, and the palette definition and GCOL/TINT selection is displayed on screen. Use the cursor left and cursor right keys to slow down or speed up. Holding down Shift will allow you to single-step through the colours at any point in the sequence using the space bar.

Note that the function of the TINT parameter is totally different now (the concept of a white tint is only possible with the default palette). The program is not completely general, and as written will only work correctly for the redefinition of palette registers 0 to 3.

10 REM >TemPal3
20 REM Program 4096 Colour Display
30 REM Version A1.3
40 REM Author Mike Williams
50 REM RISC User March 1988
60 REM Program Subject to Copyright
70 :
80 MODE 13:OFF:ON ERROR GOTO 330
90 PRINTTAB(4,6)"4096 COLOURS in a 256 COLOUR MODE"
100 wait=10:GCOL 63 TINT 3<<6
110 RECTANGLEFILL476,188,328,264
120 PRINTTAB(20,12)"TINT 1<<6"
130 PRINTTAB(9,28)"<- slower faster ->"
140 PRINTTAB(13,30)"Shift to Pause"
150 FOR red%=0 TO 15:FOR grn%=0TO15:FOR blu%=0TO15
160 blu3%=(blu% AND %1000)>>2
170 grn23%=(grn% AND %1100)>>2
180 red3%=(red% AND %1000)>>2
190 col%=(blu3%<<4)+(grn23%<<2)+(red3%)
200 VDU19,1,16,red%<<4,grn%<<4,blu%<<4
210 GCOL col% TINT 1<<6
220 RECTANGLEFILL480,192,320,256
230 PRINTTAB(10,10)"VDU19,1,16,";red%<<4;",";grn%<<4;",";blu%<<4;SPC6
240 PRINTTAB(10,12)"GCOL 0,";col%;SPC1
250 PRINTTAB(10,14)"Colour ";256*red%+16*grn%+blu%+1
260 IF INKEY-26 THEN wait+=1
270 IF INKEY-122 THEN wait-=1
280 TIME=0:REPEAT UNTIL TIME>wait
290 IF INKEY-1 THEN G=GET
300 NEXT:NEXT:NEXT
310 END
320 :
330 ON ERROR OFF:MODE 12
340 REPORT:PRINT" at line ";ERL:END

The final program this month, and an excellent piece of programming by Keith McAlpine, demonstrates the redefinition of all 16 palette registers, and allows you to mix any colours you wish, displaying the appropriate palette re-definition and GCOL/TINT values. Again, you should save the program to disc after typing it in, and before running it.

The 256 default colours are displayed on the screen with each row of 16 colours corresponding to a palette register running from 0 to 15 down the screen. Use the mouse to select any colour and the corresponding palette definition and GCOL/TINT numbers will be displayed for reference. The screen also shows the amounts of red (range 0 to 7), green (0 to 3) and blue (0 to 7) which are the variable colour components stored in each palette register. Moving the mouse pointer across the colours as you hold down the select button will produce a constantly changing and updated display.

Use the mouse pointer to change the mix of red, green and blue in any palette definition, and watch how the corresponding row of colours changes. You can always reset any palette register to its default value by clicking on the appropriate box. At any time you can choose to display (or print out) the current definitions of all 16 palette registers, and this information is automatically left displayed on the screen when you quit from the program.

Using the information provided by the program you should be able to redefine any colour and determine the corresponding COLOUR and GCOL/TINT statements. Remember though, the limitations. The 256 displayed colours are not all independent from each other. The best you can hope for is to define 16 really good colours, one for each palette; anything else is a bonus.

ENDPOINT

I have deliberately kept the explanations as short and as simple as possible. Attempting to explain fully how the palette registers and the rest work in the 256 colour modes would be a very substantial task requiring several pages of RISC User. What I set out to do instead, with the help of the programs from Richard Kirby and Keith McAlpine, is to provide you with the means to experiment with colour redefinition in a reasonably constructive way.

10 REM >PalDef256
20 REM Program 256 Colour palette definer
30 REM Version A1.2
40 REM Author Keith McAlpine
50 REM RISC User March 1988
60 REM Program Subject to Copyright
70 :
80 ON ERROR GOTO 370
90 DIM reset$(15),redef$(15)
100 PROCinit
110 PROCdraw_screen
120 PROCselect(current%)
130 PROCupdate_screen
140 *POINTER 1
150 :
160 REPEAT
170 PROCupdate_screen
180 REPEAT
190 MOUSE mx%,my%,button%
200 UNTIL button%<>0
210 CASE TRUE OF
220 WHEN FNin_area(224,415,479,447):PROCchange(red%)
230 WHEN FNin_area(224,319,351,351):PROCchange(grn%)
240 WHEN FNin_area(224,223,479,255):PROCchange(blu%)
250 WHEN FNin_area(0,567,1279,951):PROCnew_colour
260 WHEN FNin_area(956,382,1152,486):PROCreset_colour
270 WHEN FNin_area(956,254,1184,326):PROCshow_vdus
280 WHEN FNin_area(956,126,1248,200):PROCprint_vdus
290 WHEN FNin_area(956,30,1088,70):finished%=TRUE
300 ENDCASE
310 UNTIL finished%
320 MODE 12
330 PRINT'"The colour codes are:-"'
340 PROCdisplay_vdus
350 END
360 :
370 MODE 12:ON ERROR OFF
380 REPORT:PRINT" at line ";ERL:END
390 :
400 DEFPROCinit
410 MODE 13:OFF
420 current%=0:finished%=FALSE
430 gcol%=0:tint%=0
440 FOR lp%=0 TO 15
450 SYS "OS_ReadPalette",lp%,16 TO r0,r1,r2,r3
460 col1$=FNbinary(r2,32)
470 reset$(lp%)=col1$:redef$(lp%)=col1$
480 NEXT lp%
490 ENDPROC
500 :
510 DEFPROCdraw_screen
520 VDU23,224,255,129,129,129,129,129,129,255
530 VDU23,225,255,255,255,255,255,255,255,255
540 PRINTTAB(4,0)"256 Colour Mode Palette Definer"
550 PRINTTAB(11,1)"By Keith McAlpine"
560 FOR y1%=0 TO 16 STEP 16
570 FORy2%=0TO1STEP1
580 FOR t%=0 TO 3 STEP 1
590 FOR x1%=0 TO 32 STEP 32
600 FOR x2%=0 TO 14 STEP 2
610 c%=x1%+x2%+y1%+y2%
620 x_position%=35*x1%/2+40*x2%
630 y_position%=927-(24*t%+12*y1%+96*y2%)
640 GCOL c% TINT t%*64
650 RECTANGLE FILL x_position%,y_position%,80,24
660 NEXTx2%,x1%,t%,y2%,y1%
670 PRINTTAB(3,18)"RED"'''" GREEN"'''" BLUE"
680 GCOL 16 TINT 255
690 RECTANGLE FILL 956,382,196,104
700 RECTANGLE FILL 956,254,228,72
710 RECTANGLE FILL 956,126,292,72
720 RECTANGLE FILL 956,30,132,40
730 COLOUR 144 TINT 255
740 PRINTTAB(30,17)"RESET"TAB(30,18)"COLOUR"TAB(30,19);current%
750 PRINTTAB(30,22)"DISPLAY"TAB(30,23)"COLOURs"
760 PRINTTAB(30,26)"PRINT OUT"TAB(30,27)"COLOURs"
770 PRINTTAB(30,30);"QUIT"
780 GCOL 15 TINT 255
790 RECTANGLE 956,382,196,104
800 RECTANGLE 956,254,228,72
810 RECTANGLE 956,126,292,72
820 RECTANGLE 956,30,132,40
830 COLOUR 128 TINT 0
840 ENDPROC
850 :
860 DEFFNbinary(num%,bytenum%)
870 bin$=""
880 REPEAT
890 bin$=STR$(num% MOD 2)+bin$
900 num%=num% DIV 2
910 UNTIL num%=0
920 bin$=STRING$(bytenum%-LEN(bin$),"0")+bin$
930 =bin$
940 :
950 DEFPROCupdate_screen
960 COLOUR 15 TINT 255
970 PRINTTAB(9,15)"PALETTE ";current%;",";red%;",";grn%;",";blu%;SPC6
980 PRINTTAB(9,16)"GCOL ";gcol%;" TINT ";tint%;SPC3
990 COLOUR 3 TINT 255
1000 PRINTTAB(8,18);STRING$(red%>>4,CHR$225);STRING$(7-(red%>>4),CHR$224)
1010 COLOUR 12 TINT 255
1020 PRINTTAB(8,21);STRING$(grn%>>4,CHR$225);STRING$(3-(grn%>>4),CHR$224)
1030 COLOUR 48 TINT 255
1040 PRINTTAB(8,24);STRING$(blu%>>4,CHR$225);STRING$(7-(blu%>>4),CHR$224)
1050 COLOUR current%,red%,grn%,blu%
1060 PROCdecode(redef$(current%),red%,grn%,blu%)
1070 ENDPROC
1080 :
1090 DEFPROCcode(str$,RETURN r%,RETURN g%,RETURN b%)
1100 r$=MID$(str$,17,8):g$=MID$(str$,9,8)
1110 b$=LEFT$(str$,8):r%=EVAL("%"+r$)
1120 g%=EVAL("%"+g$):b%=EVAL("%"+b$)
1130 ENDPROC
1140 :
1150 DEFPROCdecode(RETURN str$,r%,g%,b%)
1160 r$=FNbinary(r%,8):g$=FNbinary(g%,8)
1170 b$=FNbinary(b%,8):str$=b$+g$+r$+"00010000"
1180 ENDPROC
1190
1200 DEFPROCselect(current%)
1210 PROCcode(redef$(current%),red%,grn%,blu%)
1220 COLOUR 144 TINT 255
1230 COLOUR 63 TINT 255
1240 PRINTTAB(30,19);current%;SPC2
1250 COLOUR 128 TINT 0
1260 ENDPROC
1270
1280 DEFFNin_area(lx%,by%,rx%,ty%)
1290 IF mx%>=lx% AND mx%<=rx% AND my%>=by% AND my%<=ty% THEN =-1
1300 =0
1310 :
1320 DEFPROCchange(RETURN col%)
1330 IF mx%<=256 THEN col%=0:ENDPROC
1340 col%=(((mx%-224) DIV 32)*16)
1350 ENDPROC
1360
1370 DEFPROCnew_colour
1380 current%=(951-my%)DIV24
1390 gcol%=POINT(mx%,my%)
1400 tint%=TINT(mx%,my%)
1410 PROCselect(current%)
1420 ENDPROC
1430 :
1440 DEFPROCreset_colour
1450 redef$(current%)=reset$(current%)
1460 PROCcode(redef$(current%),red%,grn%,blu%)
1470 ENDPROC
1480 :
1490 DEFPROCshow_vdus
1500 COLOUR 63 TINT 255
1510 PRINTTAB(0,18)"Press Shift to scroll."
1520 COLOUR 15 TINT 255
1530 VDU 28,0,31,28,20,12,14
1540 PROCdisplay_vdus
1550 VDU 26:COLOUR 63 TINT 255
1560 PRINTTAB(0,18)"Press any key to continue."
1570 key=GET
1580 VDU 28,0,31,28,18,12,13,26
1590 PRINTTAB(3,18)"RED"'''" GREEN"'''" BLUE"
1600 PROCupdate_screen
1610 ENDPROC
1620 :
1630 DEFPROCdisplay_vdus
1640 FOR lp%=0 TO 15
1650 PROCcode(redef$(lp%),r%,g%,b%)
1660 PRINT"COLOUR ";lp%;",";r%;",";g%;",";b%
1670 NEXT lp%
1680 ENDPROC
1690 :
1700 DEFPROCprint_vdus
1710 LOCAL ERROR
1720 ON ERROR LOCAL OFF:GOTO1800
1730 COLOUR 63 TINT 255
1740 PRINTTAB(0,23)"Press Escape to abort."
1750 VDU 28,0,31,28,24,12,14
1760 COLOUR 15 TINT 255
1770 VDU 2
1780 PRINT"256 colour palette COLOUR definitions"
1790 PROCdisplay_vdus
1800 VDU 3,28,0,31,28,23,12,13,26
1810 RESTORE ERROR
1820 ENDPROC