Waving flag

Discussions related to graphics (2D and 3D), animation and games programming
Richard Russell
Posts: 457
Joined: Tue 18 Jun 2024, 09:32

Waving flag

Post by Richard Russell »

This is a translation into BBC BASIC of Paul Dunn's original program for SpecBAS. It will run in BBCSDL or (rather slowly) in BB4W.

Code: Select all

      REM Waving Flag
      SCRw% = 640 : SCRh% = 384
      VDU 23,22,SCRw%;SCRh%;8,16,16,0

      *REFRESH OFF
      PROCunionflag(SCRw% * 2, SCRh% * 2)

      DIM BMP{bfType{l&,h&}, bfSize%, bfReserved%, bfOffBits%, \
      \       biSize%, biWidth%, biHeight%, biPlanes{l&,h&}, biBitCount{l&,h&}, \
      \       biCompression%, biSizeImage%, biXPelsPerMeter%, biYPelsPerMeter%, \
      \       biClrUsed%, biClrImportant%, rgb&(SCRh%-1,SCRw%-1,2)}
      *HEX 64
      OSCLI "LOAD """ + @tmp$ + "unionflag.bmp"" " + STR$~BMP{} + " +" + STR$~DIM(BMP{})

      ORIGIN 128,64 : GCOL 1 : OFF
      phase=0
      REPEAT
        CLS
        phase += 0.075
        FOR Y% = 6 TO SCRh%-6 STEP 12
          FOR X% = 6 TO SCRw%-6 STEP 12
            a = phase+2*PI*(X%/SCRh%+Y%/SCRh%)
            xs = 20*SIN(a) : ys=20*COS(a)
            COLOUR 1,BMP.rgb&(Y%,X%,2),BMP.rgb&(Y%,X%,1),BMP.rgb&(Y%,X%,0)
            CIRCLE FILL X%*1.6+xs,Y%*1.6+ys,6
          NEXT
        NEXT Y%
        *REFRESH
      UNTIL FALSE

      REM Draw a Union Flag
      DEF PROCunionflag(w,h) : LOCAL d,ho,vo : d = SQR(w^2 + h^2)
      ho = 0.2 * h * w / d : vo = 0.2 * h * h / d
      GCOL 12 : RECTANGLE FILL 0,0,w,h
      GCOL 15 : REM St.Andrew's Cross:
      MOVE 0,0 : MOVE 0,vo : PLOT 85,ho,0 : PLOT 85,w-ho,h : PLOT 85,w,h-vo : PLOT 85,w,h
      MOVE 0,h : MOVE 0,h-vo : PLOT 85,ho,h : PLOT 85,w-ho,0 : PLOT 85,w,vo : PLOT 85,w,0
      GCOL 1 : REM St.Patrick's Cross:
      MOVE 0,0 : MOVE ho*2/3,0   : PLOT 85,w/2,h/2 : PLOT 85,w/2+ho*2/3,h/2
      MOVE 0,h : MOVE 0,h-vo*2/3 : PLOT 85,w/2,h/2 : PLOT 85,w/2,h/2-vo*2/3
      MOVE w,h : MOVE w-ho*2/3,h : PLOT 85,w/2,h/2 : PLOT 85,w/2-ho*2/3,h/2
      MOVE w,0 : MOVE w,vo*2/3   : PLOT 85,w/2,h/2 : PLOT 85,w/2,h/2+vo*2/3
      REM St.George's Cross:
      GCOL 15 : RECTANGLE FILL 0,h/2-h/6,w,h/3  : RECTANGLE FILL w/2-h/6,0,h/3,h
      GCOL 1  : RECTANGLE FILL 0,h/2-h/10,w,h/5 : RECTANGLE FILL w/2-h/10,0,h/5,h
      OSCLI "GSAVE """ + @tmp$ + "unionflag"""
      ENDPROC

https://youtu.be/XBER596Y3k8
Richard Russell
Posts: 457
Joined: Tue 18 Jun 2024, 09:32

Re: Waving flag

Post by Richard Russell »

Richard Russell wrote: Thu 14 Aug 2025, 12:54 This is a translation into BBC BASIC of Paul Dunn's original program for SpecBAS.
Paul achieves real-time animation in interpreted BASIC by rendering the flag at very low resolution, only about 50 x 30 pixels. By drawing those 'pixels' as circles the subjective effect is remarkably acceptable, even attractive, despite the low resolution.

But what if we want to animate the flag at full resolution? The shaderlib library comes to the rescue: we can easily do it with a tiny amount of shader code performing the same transformation as the BASIC code in the original, but thousands of times faster:

Code: Select all

      REM Fragment Shader code
      DATA "uniform float iPhase;"
      DATA "uniform vec2 iResolution;"
      DATA "uniform sampler2D iChannel0;"
      DATA "#define PI 3.141592654"

      DATA "void main()"
      DATA "{"
      DATA "vec2 pt = gl_FragCoord.xy;"
      DATA "float a = iPhase + 2.0 * PI * (pt.x + pt.y) / iResolution.y;"
      DATA "pt.x = pt.x / 0.8 + 12.0 * sin(a) - 80.0;"
      DATA "pt.y = pt.y / 0.8 + 12.0 * cos(a) - 40.0;"
      DATA "if ((pt.x >= 0.0) && (pt.x < iResolution.x) && (pt.y >= 0.0) && (pt.y < iResolution.y))"
      DATA "  gl_FragColor = texture2D(iChannel0, pt/iResolution);"
      DATA "else"
      DATA "  gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);"
      DATA "}"
      DATA ""

https://youtu.be/n1dWsBVFJDk