REM Vector balls 5
REM. Disable the Escape key
*ESC OFF
REM. Select 64-bit floating point mode (double-precision maths)
*FLOAT 64
REM. Set up a simple error handler
ON ERROR OSCLI "REFRESH ON" : REPORT : PRINT " at line ";ERL : VDU 7 : END
REM. Make 2 MB of RAM available for this program
M% = 2
HIMEM = LOMEM + M%*&100000
REM. Prevent the program window from being resized by the user
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. Setup a 640x512 display mode, and turn OFF the flashing cursor
MODE 8
OFF
REM. Install and initialise GFXLIB and required external modules
INSTALL @lib$ + "GFXLIB2.BBC" : PROCInitGFXLIB
INSTALL @lib$ + "GFXLIB_modules\PlotAND3.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\DrawBmFont4.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\PlotScaleTint.BBC" : PROCInitModule
INSTALL @lib$ + "GFXLIB_modules\MMXSubtract64.BBC" : PROCInitModule
REM. Get addresses of frequently called Windows API routines
GetTickCount% = FNSYS_NameToAddress( "GetTickCount" )
InvalidateRect% = FNSYS_NameToAddress( "InvalidateRect" )
REM. Declare a string array to contain the lines of text
RESTORE : numStrings%=-1 : REPEAT : READ S$ : numStrings%+=1 : UNTIL S$="*"
DIM string$( numStrings%-1 )
REM. Fill the string array (read the text from DATA statements into the array)
RESTORE : FOR I%=0 TO numStrings%-1 : READ string$(I%) : NEXT I%
REM. Install and initialise SORTLIB (which will be used to depth-sort the
REM. 'vector balls' according to their Z coordinate)
INSTALL @lib$+"SORTLIB"
sort% = FN_sortinit(1, 0)
REM. Load graphics
PROCLoadBMP( @dir$ + "blueball_128x128x24.BMP", bmAddr%, FALSE )
REM. Load the bitmap font data
PROCLoadData( @dir$ + "bm14.DAT", font%, 0 )
REM. Set up a 640*512-pixel 'bitmap buffer' to which the rotating pattern of
REM. ball sprites will be written
DIM bmBuff% 4*640*512+4 : bmBuff%=(bmBuff%+3) AND -4
REM. Number of ball sprites to display
N% = 25
REM. Arrays holding the ball's position in 3D space, colour, and the strength of which
REM. the colour is blended with the 'natural' colour of the ball sprite
DIM x%(N%-1), y%(N%-1), z%(N%-1), colour%(N%-1), strength%(N%-1)
REM. Arrays holding the ball's depth-sorted position in 3D space *after* it's been rotated
DIM x2%(N%-1), y2%(N%-1), z2%(N%-1), colour2%(N%-1), strength2%(N%-1)
REM. 'Randomize' BASIC's random number generator (using the current value of TIME as the seed)
R% = RND( -TIME )
REM. Specify the minimum distance that any one ball can be from any other
minDist% = 100
REM. Choose random positions such that no ball is within minDist% units of another ball
FOR I%=0 TO N%-1
REPEAT
valid% = TRUE
x% = -300 + RND(2*300 - 1)
y% = -300 + RND(2*300 - 1)
z% = -300 + RND(2*300 - 1)
IF I%=0 THEN
x%(0) = x%
y%(0) = y%
z%(0) = z%
ELSE
FOR J%=0 TO I%
d% = SQR( (x%-x%(J%))^2 + (y%-y%(J%))^2 + (z%-z%(J%))^2 )
IF d% < minDist% THEN
valid% = FALSE
J% = I%
ENDIF
NEXT J%
ENDIF
UNTIL valid%
x%(I%) = x%
y%(I%) = y%
z%(I%) = z%
colour%(I%) = &10000*RND(&FF) + &100*RND(&FF) + RND(&FF)
strength%(I%) = 128 + RND(127)
NEXT I%
REM. Set up random initial rotation angles (in radians)
a# = 2.0 * PI * RND(1)
b# = 2.0 * PI * RND(1)
c# = 2.0 * PI * RND(1)
REM. Copy frequently accessed variables into BASIC's static variables for faster access
A% = GFXLIB_DrawBmFont4%
D% = dispVars{}
P% = GFXLIB_PlotScaleTint%
scrollerYPxlO% = -40
scrollerDataO% = 13
*REFRESH OFF
REPEAT
REM. Display the bitmap buffer
SYS GFXLIB_BPlot%, dispVars{}, bmBuff%, 640, 512, 0, 0
REM. Redirect GFXLIB's output to the 640x512-pixel bitmap buffer pointed to by bmBuff%
SYS GFXLIB_QuickSetDispVars%, dispVars{}, bmBuff%
REM. Darken all the pixels in the bitmap buffer
REM. (i.e., Subtract 4 from the Red, Green and Blue values of each pixel)
SYS GFXLIB_MMXSubtract64%, dispVars{}, bmBuff%, 4*(640*512 DIV 64), 4
REM. Rotate the 3D positions of the balls
cosa# = COSa#
cosb# = COSb#
cosc# = COSc#
sina# = SINa#
sinb# = SINb#
sinc# = SINc#
FOR I%=0 TO N%-1
x# = x%(I%)
y# = y%(I%)
z# = z%(I%)
x1# = x#*cosa# - y#*sina#
y1# = x#*sina# + y#*cosa#
z1# = z#
y2# = y1#*cosb# - z1#*sinb#
z2# = y1#*sinb# + z1#*cosb#
x2# = x1#
z3# = z2#*cosc# - x2#*sinc#
x3# = z2#*sinc# + x2#*cosc#
y3# = y2#
x2%(I%) = x3#
y2%(I%) = y3#
z2%(I%) = z3#
NEXT I%
REM. Sort the rotated X, Y, Z coordinate arrays according to the Z coordinate
colour2%() = colour%()
strength2%() = strength%()
C%=N% : CALL sort%, z2%(0), x2%(0), y2%(0), colour2%(0), strength2%(0)
REM. Draw the actual ball bitmaps
REM. Reminder: P%=GFXLIB_PlotScaleColourBlend, D%=dispVars{}
FOR I%=0 TO N%-1
d# = 1/(&3E8+z2%(I%))
X% = &140 + &2A8 * x2%(I%) * d#
Y% = &100 + &2A8 * y2%(I%) * d#
Z% = &80*(&3E8-(z2%(I%)+&2F4))/&3E8
SYS P%, D%, bmAddr%, 128, 128, Z%, Z%, X%-Z%/2, Y%-Z%/2, colour2%(I%), strength2%(I%)
NEXT
REM. Reset the bmBuffAddr member of the dispVars struct to dibSectionAddr%
SYS GFXLIB_QuickSetDispVars%, dispVars{}, dibs%
REM. Draw the scrolling lines of text
REM. Reminder: A%=GFXLIB_DrawBmFont4, D%=dispVars{}
FOR Y%=13 TO 0 STEP -1
V% = 40*Y% + scrollerYPxlO%
C% = &10000*INT(255*(1-(V%+40)/552)) + &100*INT(128+127*(V%+40)/552) + INT(255*(V%+40)/552)
REM. SYS GFXLIB_DrawBmFont4, dispVars{}, bmFontAddr, string, x, y, colour
SYS A%, D%, font%, string$(scrollerDataO% - Y%), 0, V%, C%
NEXT Y%
scrollerYPxlO% += 1
IF scrollerYPxlO% >= 0 THEN
scrollerYPxlO% = -40
scrollerDataO% += 1
ENDIF
IF scrollerDataO% >= numStrings%-8 THEN
scrollerDataO% = 13
ENDIF
REM. Bump then check the rotation angles
a# += 0.029151 + 0.01*SINb#*COSc#
b# += 0.026316 - 0.01*COSc#
c# += 0.022194 + 0.01*SINa#*COSb#
IF a# > 2*PI THEN a# -= 2*PI
IF b# > 2*PI THEN b# -= 2*PI
IF c# > 2*PI THEN c# -= 2*PI
REM. Update the program output window
PROCdisplay
UNTIL FALSE
REM Some random verses from the New Testament :-)
DATA "","","","","","","","","","","","","","","",
DATA "Examine yourselves to see"
DATA "whether you are in the faith;"
DATA "test yourselves."
DATA "Do you not realize that"
DATA "Christ Jesus is in you -"
DATA "unless, of course, you fail"
DATA "the test?"
DATA "And I trust that you will"
DATA "discover that we have not"
DATA "failed the test."
DATA "", "", "", ""
DATA "", "", "", ""
DATA "Now we pray to God that"
DATA "you will not do anything"
DATA "wrong. Not that people will"
DATA "see that we have stood the"
DATA "test but that you will do"
DATA "what is right even though we"
DATA "may seem to have failed."
DATA "", "", "", ""
DATA "", "", "", ""
DATA "For we cannot do anything"
DATA "against the truth, but"
DATA "only for the truth."
DATA "We are glad whenever we"
DATA "are weak but you are strong;"
DATA "and our prayer is for your"
DATA "perfection. This is why I"
DATA "write these things when I am"
DATA "absent, that when I come"
DATA "I may not have to be harsh"
DATA "in my use of authority -"
DATA "the authority the Lord gave"
DATA "me for building you up,"
DATA "not for tearing you down."
DATA "","","","","","","","","","","","","","","",
DATA "","","","","","","","","","","","","","","",
DATA "*"