REM. Flying worm


     REM
     REM  Disable the Escape key
     REM

     
*ESC OFF


     REM
     REM  Set up a simple error handler
     REM

     
ON ERROR OSCLI "REFRESH ON" : CLS : ON : REPORT : PRINT " at line ";ERL : VDU 7 : END


     
REM
     REM  Select 64-bit floating point mode (double-precision maths)
     REM

     
*FLOAT64


     REM
     REM  Make 4Mb of RAM available for use by this program
     REM

     
M% = 4
     HIMEM = LOMEM + M%*&100000


     REM
     REM  Prevent the program window from being resized by the user
     REM

     
SYS "GetWindowLong", @hwnd%, -16 TO S%
     SYS "SetWindowLong", @hwnd%, -16, S% AND NOT &50000
     SYS "SetWindowPos", @hwnd%, 0, 0, 0, 0, 0, 32+7


     REM
     REM  Setup a 640x512 display mode, and turn OFF the flashing cursor
     REM

     
MODE 8
     OFF


     
REM
     REM Install and initialise GFXLIB and required external modules
     REM

     
INSTALL @lib$ + "GFXLIB2.BBC"
     PROCInitGFXLIB

     INSTALL @lib$ + "GFXLIB_modules\RGBSwap.BBC"        : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\RGBInvert.BBC"      : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\PlotInvertRGB.BBC"  : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\MMXSubtract64.BBC"  : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\PlotBlend.BBC"      : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\MMXCopy64.BBC"      : PROCInitModule
     INSTALL @lib$ + "GFXLIB_modules\PlotShapeBlend.BBC" : PROCInitModule


     REM
     REM  Load the graphics
     REM

     
PROCLoadBMP(  @dir$ + "resources\bg0_640x512x24.BMP",     bg0Bm%,    0 )
     PROCLoadBMP(  @dir$ + "resources\sphere003_64x64x24.BMP", ballBm%,   0 )
     PROCLoadBMP(  @dir$ + "resources\bg3_640x512x8.BMP",      bg3Bm%,    0 )
     PROCLoadBMP(  @dir$ + "resources\bb4w_552x226x8.BMP",     bb4wBm%,   0 )



     REM
     REM  Swap the Red and Blue colour channels of all the pixels in bg3
     REM
     REM  Note:
     REM
     REM      SYS GFXLIB_RGBSwap, bmAddr, bmW, bmH, swapCode
     REM
     REM          swapCode 0 = swap Red and Green channels
     REM                   1 = swap Red and Blue channels
     REM                   2 = swap Green and Blue channels
     REM

     
SYS GFXLIB_RGBSwap%, bg3Bm%, 640, 512, 1

     REM
     REM  Invert the Red and Green colour channels of all pixels in bg3
     REM
     REM  Note:
     REM
     REM      SYS GFXLIB_RGBInvert, bmAddr, bmW, bmH, channelFlags
     REM
     REM          channelFlags bit 0 set = invert Red channel
     REM                       bit 1 set = invert Green channel
     REM                       bit 2 set = invert Blue channel
     REM
     REM      For this example, bits 0 and 1 are set (0^2 + 1^2 = 3)
     REM

     
SYS GFXLIB_RGBInvert%, bg3Bm%, 640, 512, 3


     REM
     REM   Here, I want to 'overlay' a semi-transparent bg0 over bg3 (by means of GFXLIB_PlotOpaque),
     REM   however, PlotOpaque's output must be redirected to bg3 (it's currently set to dibSAddr%).
     REM

     
SYS GFXLIB_SetDispVars%, dispVars{}, bg3Bm%, 640, 512, 0, 0, 640, 512, TRUE


     
REM
     REM  Now overlay bg0 on bg3 (bg0's opacity = 25%)
     REM

     
SYS GFXLIB_PlotBlend%, dispVars{}, bg0Bm%, 640, 512, 0, 0, 75


     REM
     REM  Using PlotOpaqueColour, we're going to plot the stylish (and plain white by default) BB4W graphic on top of bg3
     REM
     REM  Remember that output is currently redirected to bg3, so GFXLIB_PlotOpaqueColour will draw on the bg3 bitmap,
     REM  and not the DIB section/viewport
     REM

     REM shadow (15% opacity)
     
SYS GFXLIB_PlotShapeBlend%, dispVars{}, bb4wBm%, 552, 226, 320-552DIV2-12, 256-226DIV2-12, &000000, 45

     REM BB4W graphic coloured red-orange at 75% opacity
     
SYS GFXLIB_PlotShapeBlend%, dispVars{}, bb4wBm%, 552, 226, 320-552DIV2, 256-226DIV2, &F08060, 200


     REM
     REM   Next we're going to use GFXLIB_PlotInvertRGB to invert the green colour channel of all the
     REM   pixels in the ball bitmap.  First though, PlotInvertRGB's output is redirected to ballBm%.
     REM

     
SYS GFXLIB_SetDispVars%, dispVars{}, ballBm%, 64, 64, 0, 0, 64, 64, TRUE

     SYS
GFXLIB_PlotInvertRGB%, dispVars{}, ballBm%, 64, 64, 0, 0, 1


     REM
     REM  Now the output is restored back to dibSAddr%
     REM

     
SYS GFXLIB_SetDispVars%, dispVars{}, dibs%, 640, 512, 0, 0, 640, 512, TRUE


     
REM
     REM  Darken the rows of bg3; the extent to which the rows are darkened increases from bottom to top
     REM

     
FOR Y%=0 TO 511
       SYS GFXLIB_MMXSubtract64%, dispVars{}, bg3Bm% + 4*640*Y%, 40, Y%/4
     NEXT Y%


     *REFRESH OFF

     theta1# = 0 : dtheta1# = 2.818
     theta2# = 0 : dtheta2# = 1.233

     D% = dispVars{}
     P% = GFXLIB_PlotBlend%

     REPEAT

       
REM
       REM  Draw the background bitmap (bg3)
       REM

       
SYS GFXLIB_MMXCopy64%, dispVars{}, bg3Bm%, dibs%, 4*5120


       REM
       REM  Plot the balls
       REM

       
FOR I%=29 TO 0 STEP -1
         a# = theta1# - 2*I%*dtheta1#
         b# = 0.25*theta2# - 0.5*I%*dtheta2#
         X% = 288 + 320 * SINRADa# * COSRADb#
         Y% = 224 + 256 * COSRADa# * SINRADb#
         opacity% = 255*(29-I%)/29
         SYS P%, D%, ballBm%, 64, 64, X%, Y%, opacity%
       NEXT I%

       theta1# += dtheta1#
       theta2# += dtheta2#

       PROCdisplay

     UNTIL FALSE