The simple Basic procedure given here will convert a screen image from any mode (other than modes 3, 6 or 7), to any other mode. It is primarily designed to convert to a mode superior to the current one, that is one with at least as high a resolution, and at least as many colours. It will however perform any conversion. There are numerous uses for such a conversion. For example, you might want to edit, say, a mode 13 screen in an art package which only supports mode 15. Or, you may need to convert a screen to a different mode before it can be printed using a particular dump program.
The listing given here contains both the conversion procedure, and also a short sample program to demonstrate it. This will load a saved screen of any mode, and convert it to mode 15. You must have a saved screen with the filename 'Screen' available before running this.
To use the routine in your own code, you merely need to include the definition of PROCconvert, and with the screen to be converted displayed, execute:
PROCconvert(mode)
where mode is the resulting mode. The conversion takes just a couple of seconds.
Each time the procedure is called it will claim a block of equal to the size of the source screen mode. This will not normally cause problems because it is likely that the conversion will be performed once only. However, it is possible to move the DIM statements to outside the procedure, and dimension the block screen to the size of the largest screen size that will be converted. The procedure can then be called without it reclaiming memory. PROCconvert also requires the RISC OS Colour Trans module to be installed. If this is not present, the procedure attempts to load it from the !System application (where it normally resides). This will only work if the !System application has been 'seen' in a Desktop directory viewer since the last hard reset. You may wish to make a copy of the module onto your working disc, and change the pathname at the end of line 1010 (after the RMLOAD) to reflect this.
The way in which colours are translated depends on whether the screen is being converted to a mode with more or less colours than the current mode. In the case where the conversion is to a mode with less colours, each colour from the current palette will be mapped to the closest colour in the new mode's palette. No attempt is made to redefine the palette. This means that the colours used in a picture may be changed considerably. On the other hand, if the new mode offers more colours (or the same number) then its palette is set to the same values as the source mode. Therefore, the colours will be retained exactly. The only exception to this is when the new mode has 256 colours. In this case the palette is not changed, although the large number of available colours mean that the conversion can be performed with no noticeable change of colour.
The procedure starts by grabbing the source screen into a user sprite area. It then calculates the size of the source and destination screens, and uses the Colour Trans module to perform the palette mapping. The screen mode is then changed and the sprite replotted using the appropriate scaling and colour translation.
10 REM >Convert
20 REM Program Mode Converter
30 REM Version A1.00
40 REM Author David Spencer
50 REM RISC User May 1989
60 REM Program Subject to Copyright
70 :
80 *SCREENLOAD "Screen"
90 PRINT TAB(0,0);MODE
100 PROCconvert(15)
110 PRINT TAB(0,1);MODE
120 END
130 :
1000 DEF PROCconvert(dmode)
1010 *RMENSURE ColourTrans 0 RMLOAD <System$Path>Modules.Colours
1020 SYS "OS_Byte",135 TO ,,smode
1030 SYS "OS_ReadModeVariable",smode,3 TO ,,scols
1040 SYS "OS_ReadModeVariable",smode,4 TO ,,sxeig
1050 SYS "OS_ReadModeVariable",smode,5 TO ,,syeig
1060 SYS "OS_ReadModeVariable",smode,7 TO ,,size
1070 SYS "OS_ReadModeVariable",smode,11
TO ,,sx
1080 SYS "OS_ReadModeVariable",smode,12
TO ,,sy
1090 SYS "OS_ReadModeVariable",dmode,3 TO ,,dcols
1100 SYS "OS_ReadModeVariable",dmode,4 TO ,,dxeig
1110 SYS "OS_ReadModeVariable",dmode,5 TO ,,dyeig
1120 SYS "OS_ReadModeVariable",dmode,11
TO ,,dx
1130 SYS "OS_ReadModeVariable",dmode,12
TO ,,dy
1140 DIM map 256, screen size+64, scale
15, pal 64
1150 !scale=dx:scale!4=dy:scale!8=sx:scale!12=sy
1160 !screen=size+64:screen!4=0
1170 screen!8=16:screen!12=16
1180 SYS "OS_SpriteOp",&110,screen,"sprite",0,0,0,sx<<sxeig,sy<<syeig
1190 IF dcols>=scols AND dcols<63 THEN
1200 dp=pal
1210 FOR loop=0 TO scols
1220 SYS "OS_ReadPalette",loop,16 TO ,,col
1230 pal!(loop*4)=col
1240 NEXT
1250 ELSE
1260 dp=0
1270 ENDIF
1280 SYS "ColourTrans_InvalidateCache"
1290 SYS "ColourTrans_SelectTable",-1,-1,dmode,dp,map
1300 MODE dmode
1310 IF dp THEN
1320 FOR loop=0 TO scols
1330 col=pal!(loop*4)
1340 VDU 19,loop,16,col>>8,col>>16,col>>24
1350 NEXT
1360 ENDIF
1370 SYS "OS_SpriteOp",&134,screen,"sprite",0,0,0,scale,map
1380 SYS "OS_SpriteOp",&109,screen
1390 ENDPROC