10 REM > Graphics
   20 REM Test various VDU driver graphics operations
   30 :
   40 bbfw%=(INKEY-256 AND &DB)=&53
   50 :       :gap$=CHR$3+CHR$6+CHR$7+CHR$11+CHR$14+CHR$17
   60 IF bbfw%:gap$=CHR$3+CHR$6+CHR$7+CHR$20+CHR$21+CHR$28+CHR$29
   70 FOR M%=0 TO 31
   80   IF M%=3 OR M%=6:M%=M%+1
   90   IF M%=7:M%=M%+1
  100   RESTORE
  110   FOR R%=0 TO 7
  120     MODE M%:PRINT:VDU8:txW%=POS+1
  130     REPEAT:txH%=VPOS+1:PRINT:UNTILtxH%=VPOS+1:CLS
  140     VDU23,1,0;0;0;0;
  150     gap%=INSTR(gap$,CHR$M%)<>0 AND txH%<30:IF bbfw%:gap%=INSTR(gap$,CHR$M%)<>0
  160     gfH%=txH%*(8-2*gap%):gfW%=txW%*8
  170     gfY%=gfH%:REPEAT:gfY%=gfY%*2:UNTIL gfY%>=&300
  180     gfX%=gfW%:REPEAT:gfX%=gfX%*2:UNTIL gfX%>=&400
  190     REM Doesn't work for MODE 22
  200     IF bbfw%:gfY%=gfH%*4:gfX%=gfW%:REPEAT:gfX%=gfX%*2:UNTIL gfX%>=gfY%
  210     :
  220     PRINTTAB(txW%/2-3+(M%>99),1);"MODE ";M%
  230     PRINTTAB(txW%/2-9,2);txW%;" x ";txH%;" characters"
  240     PRINTTAB(txW%/2-9-LENSTR$gfW%,3);gfW%;" x ";gfH%;" physical ";LEFT$("pixels",txW%>20)
  250     PRINTTAB(txW%/2-9-LENSTR$gfX%,4);gfX%;" x ";gfY%;" logical ";LEFT$("pixels",txW%>20)
  260     READ A$:PRINTTAB((txW%-LENA$)/2+0,5);A$
  270     MOVE 0,0:GCOL 0,7:FOR A%=1 TO 7
  280       x%=VALMID$("1100101",A%,1)*(gfX%-1)
  290       y%=VALMID$("0110110",A%,1)*(gfY%-1)
  300     DRAW x%,y%:NEXT A%
  310     FOR K%=1 TO 10
  320       GCOL 0,RND(7):x%=RND(1280):y%=RND(1024):w%=RND(256):h%=RND(320)
  330       IF R%=0:MOVE x%,y%:MOVE RND(1280),RND(1024):PLOT 85,w%,h%
  340       IF R%=1:PROCcircle(x%,y%,w%,1)
  350       IF R%=2:MOVE x%,y%:PLOT 153,w%,0
  360       IF R%=3:PROCcircle(x%,y%,w%,0)
  370       IF R%=4:MOVE x%,y%:PLOT 145,w%,0
  380       IF R%=5:MOVE x%,y%:MOVE x%+w%,y%:PLOT 85,x%,y%+h%:PLOT 85,x%+w%,y%+h%
  390       IF R%=6:MOVE x%,y%:PLOT 101,x%+w%,y%+h%
  400       IF R%=7:MOVE x%,y%:PLOT 13,x%+w%,y%:PLOT 13,x%+w%,y%+h%:PLOT 13,x%,y%+h%:PLOT 13,x%,y%
  410       IF INKEY(50)>-1:K%=10
  420     NEXT K%
  430   NEXT R%
  440 NEXT M%
  450 END
  460 DATA Native Triangles
  470 DATA Manual filled circles,Native filled circles
  480 DATA Manual outline circles,Native outline circles
  490 DATA Manual filled rectangles,Native filled rectangles
  500 DATA Outline rectangles
  510 :
  520 REM > BLib.Graphic.Circle 1.01 22May1986
  530 REM v1.00 15Apr1985 Code from Econet front end
  540 REM v1.01 22May1986 Optimised MOVE/PLOTs
  550 :
  560 DEFPROCcircle(x%,y%,r%,f%):REM X posn, Y posn, Radius, Filled
  570 LOCAL step,s,c,xp,yp,xr,s%,k%
  580 k%=13+72*(f%AND1)      :REM PLOT action 13 (line) or 85 (triangle)
  590 step=(2*PI/90)+50      :REM Length of each arc
  600 s=-0.194423088762 :REM s=SINstep    :REM Precalculate sin of step
  610 c=0.9809177653    :REM c=COSstep    :REM Precalculate cosine of step
  620 xp=r%:yp=0             :REM Set initial position
  630 MOVE x%+r%,y%          :REM Move to initial point on edge
  640 FOR s%=1 TO 31         :REM We'll do 31 segments here
  650   xr=xp*c-yp*s           :REM Calculate next point on edge
  660   yp=xp*s+yp*c
  670   xp=xr
  680   IF f%:MOVE x%,y%       :REM If filled, extra point at centre
  690   PLOT k%,x%+xp,y%+yp    :REM Draw a line or a segment
  700 NEXT                   :REM And again
  710 IF f%:MOVE x%,y%       :REM Do final segment back to start
  720 PLOT k%,x%+r%,y%
  730 ENDPROC