QB64 Phoenix Edition
Screen Savers - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: bplus (https://qb64phoenix.com/forum/forumdisplay.php?fid=36)
+---- Thread: Screen Savers (/showthread.php?tid=219)

Pages: 1 2 3 4 5


Screen Savers - bplus - 04-27-2022

Screen Savers - you are welcome to post your own favorites in this thread!
________________________________________________________________________________________________

Pete's post of The Bob's Mystic version of a Screen Saver brought back memories of my own version and even today I continue to Modify. I didn't want to go Full Screen on this one because the Title bar has help for keys you can press to play with screen saver a bit add or subtract triangles, draw a mirror image and not toggle, change color scheme (Plasma of Course!)

Code: (Select All)
_Title "Mystic Memories by bplus, d toggles duplicate on/off, spacebar resets color, m = more, l = less triangles"
'posted 2017-09-29 for QB64, Mystic screen saver as I remember it plus...
' 2022-04-26 fix up a few things for post
Randomize Timer
Const xmax = 1280
Const ymax = 720

Type point
    x As Integer
    y As Integer
    dx As Single
    dy As Single
End Type
Common Shared pR, pG, pB, cN
Randomize Timer
Screen _NewImage(xmax, ymax, 32)
_ScreenMove 60, 0

Dim tri(2) As point
For i = 0 To 2
    newPoint tri(i)
Next
Dim saveP1 As point
Dim saveP2 As point
Dim saveP3 As point
saveP1 = tri(0): saveP2 = tri(1): saveP3 = tri(2)
dmode = 0: nT = 50
resetPlasma
While _KeyDown(27) = 0
    Cls , 0
    cN = cN - nT
    tri(0) = saveP1: tri(1) = saveP2: tri(2) = saveP3
    For i = 0 To 2
        updatePoint tri(i)
    Next
    saveP1 = tri(0): saveP2 = tri(1): saveP3 = tri(2)
    For j = 1 To nT
        For i = 0 To 2
            updatePoint tri(i)
        Next
        changePlasma
        For i = 0 To 2
            Line (tri(i).x, tri(i).y)-(tri((i + 1) Mod 3).x, tri((i + 1) Mod 3).y)
        Next
        If dmode Then
            For i = 0 To 2
                Line (xmax - tri(i).x, ymax - tri(i).y)-(xmax - tri((i + 1) Mod 3).x, ymax - tri((i + 1) Mod 3).y)
            Next
        End If
    Next
    _Display

    'The following commented code worked (works) like a charm
    k$ = InKey$
    If k$ = " " Then
        resetPlasma
    ElseIf k$ = "d" Then
        dmode = Not dmode
    ElseIf k$ = "m" Then
        nT = nT + 1: If nT > 500 Then nT = 500
    ElseIf k$ = "l" Then
        nT = nT - 1: If nT < 1 Then nT = 1
    End If

    _Limit 10
Wend

Sub newPoint (p As point)
    p.x = Rnd * xmax
    p.y = Rnd * ymax
    p.dx = (Rnd * 10 + 1) * rdir
    p.dy = (Rnd * 6 + 1) * rdir
End Sub

Sub updatePoint (p As point)
    If p.x + p.dx < 0 Then p.dx = p.dx * -1
    If p.y + p.dy < 0 Then p.dy = p.dy * -1
    If p.x + p.dx > xmax Then p.dx = p.dx * -1
    If p.y + p.dy > ymax Then p.dy = p.dy * -1
    p.x = p.x + p.dx
    p.y = p.y + p.dy
End Sub

Sub changePlasma ()
    cN = cN + 1
    Color _RGB(127 + 127 * Sin(pR * .5 * cN), 127 + 127 * Sin(pG * .5 * cN), 127 + 127 * Sin(pB * .5 * cN))
End Sub

Sub resetPlasma ()
    pR = Rnd ^ 2: pG = Rnd ^ 2: pB = Rnd ^ 2
End Sub

Function rdir% ()
    If Rnd < .5 Then rdir% = -1 Else rdir% = 1
End Function

A similar thing with rectangles but not as elegant I think:
Code: (Select All)
_Title " *** Screen Saver #3 - Mystic Rectangles *** " ' by bplus 2018-03-01
' 2022-04-26 a couple mod before posting again use full screen and alpha coloring

' translated from
' Screen Saver #3 Mystic Rectangles.bas SmallBASIC 0.12.11 (B+=MGA) 2018-02-28
' instead of wire frame triangles try solid color rectangles
' arrays? we don't need no dang arrays!
' oh to share everything use GOSUBs instead of SUBs

'====================================================================================

'                  spacebar will switch the color scheme

'====================================================================================

Randomize Timer
Const xmax = 1024
Const ymax = 572
Screen _NewImage(xmax, ymax, 32)
'_ScreenMove 100, 20
_FullScreen
nT = 50 'number of Things per screen
GoSub newRect
savex1 = x1: savey1 = y1: savedx1 = dx1: savedy1 = dy1
savex2 = x2: savey2 = y2: savedx2 = dx2: savedy2 = dy2
cN = nT
GoSub resetPlasma
While _KeyDown(27) = 0
    Cls

    'reset color Number back to beginning + 1
    cN = cN - nT + 1

    'reset rect back to beginning and then update it once and save this for next round
    x1 = savex1: y1 = savey1: dx1 = savedx1: dy1 = savedy1
    x2 = savex2: y2 = savey2: dx2 = savedx2: dy2 = savedy2
    GoSub updateRect
    savex1 = x1: savey1 = y1: savedx1 = dx1: savedy1 = dy1
    savex2 = x2: savey2 = y2: savedx2 = dx2: savedy2 = dy2

    For j = 1 To nT
        GoSub updateRect
        GoSub changePlasma
        Line (x1 - 12, y1 - 7)-(x2, y2), , B
        'inverse image and color
        xx1 = xmax - x1: yy1 = ymax - y1
        xx2 = xmax - x2: yy2 = ymax - y2
        If xx1 > xx2 Then Swap xx1, xx2
        If yy1 > yy2 Then Swap yy1, yy2
        Line (xx1 - 12, yy1 - 7)-(xx2, yy2), invColor&&, B
    Next
    _Display
    _Limit 60
    'k$ = InKey$
    'If k$ = " " Then GoSub resetPlasma
    If _KeyDown(32) Then GoSub resetPlasma
Wend
System

newRect:
x1 = Rnd * xmax
y1 = Rnd * ymax
dx1 = (Rnd * 9 + 3) * rdir
dy1 = (Rnd * 5 + 2) * rdir
x2 = Rnd * xmax
y2 = Rnd * ymax
dx2 = (Rnd * 9 + 3) * rdir
dy2 = (Rnd * 5 + 2) * rdir
'keep x1, y1 the lesser corner and x2, y2 the greater
If x1 > x2 Then Swap x1, x2: Swap dx1, dx2
If y1 > y2 Then Swap y1, y2: Swap dy1, dy2
Return

updateRect:
If x1 + dx1 < 0 Then dx1 = -dx1
If x1 + dx1 > xmax Then dx1 = -dx1
x1 = x1 + dx1
If y1 + dy1 < 0 Then dy1 = -dy1
If y1 + dy1 > ymax Then dy1 = -dy1
y1 = y1 + dy1
If x2 + dx2 < 0 Then dx2 = -dx2
If x2 + dx2 > xmax Then dx2 = -dx2
x2 = x2 + dx2
If y2 + dy2 < 0 Then dy2 = -dy2
If y2 + dy2 > ymax Then dy2 = -dy2
y2 = y2 + dy2
'keep x1, y1 the lesser corner and x2, y2 the greater
If x1 > x2 Then Swap x1, x2: Swap dx1, dx2
If y1 > y2 Then Swap y1, y2: Swap dy1, dy2
Return

changePlasma:
cN = cN + 1
Color _RGB32(127 + 127 * Sin(pR * .5 * cN), 127 + 127 * Sin(pG * .5 * cN), 127 + 127 * Sin(pB * .5 * cN))
invColor&& = _RGB32(255 - (127 + 127 * Sin(pR * .5 * cN)), 255 - (127 + 127 * Sin(pG * .5 * cN)), 255 - (127 + 17 * Sin(pB * .5 * cN)))
Return

resetPlasma:
pR = Rnd ^ 2: pG = Rnd ^ 2: pB = Rnd ^ 2
Return

Function rdir ()
    If Rnd < .5 Then rdir = -1 Else rdir = 1
End Function



RE: Screen Savers - Dav - 04-27-2022

Here's something I found collecting dust.  Made it when I started playing around with RotoZoom3.  Generates pages of clusters of balls and spins them around in various size, speed and transparency.

- Dav

Code: (Select All)
'====================
'SWIRLINGCLUSTERS.BAS
'====================
'Swirling clusters of colored balls
'Code by Dav, FEB/2021
'(I didn't make RotoZoom3 SUB)

SCREEN _NEWIMAGE(800, 800, 32)

RANDOMIZE TIMER

NumberOfClusters = 30
DIM Cluster(NumberOfClusters) AS LONG

ballsize = 20
balls = 80
FOR d = 1 TO NumberOfClusters
    Cluster(d) = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
    _DEST Cluster(d)
    FOR i = 1 TO balls
        x = RND * _WIDTH
        IF x < ballsize * 2 THEN x = x + (ballsize * 2)
        y = RND * _HEIGHT
        IF y < ballsize * 2 THEN y = y + (ballsize * 2)
        ball x, y, RND * ballsize, RND * 128, RND * 128, 255, RND * 150
    NEXT
NEXT

_DEST 0

DIM ClusterX(NumberOfClusters), ClusterY(NumberOfClusters), ClusterSize(NumberOfClusters)
DIM ClusterRotate(NumberOfClusters), ClusterSpeed(NumberOfClusters)

FOR G = 1 TO NumberOfClusters
    ClusterX(G) = RND * _WIDTH
    ClusterY(G) = RND * _HEIGHT
    ClusterSize(G) = RND * 1.3
    ClusterRotate(G) = 2
    ClusterSpeed(G) = RND * 2
NEXT

DO
    CLS , _RGB(0, 0, 64)
    FOR G = 1 TO NumberOfClusters
        RotoZoom3 ClusterX(G), ClusterY(G), Cluster(G), ClusterSize(G), ClusterSize(G), _D2R(ClusterRotate(G))
        ClusterRotate(G) = ClusterRotate(G) + ClusterSpeed(G): IF ClusterRotate(G) > 360 THEN ClusterRotate(G) = 1
    NEXT
    _DISPLAY
    _LIMIT 30
LOOP UNTIL INKEY$ <> ""

FOR d = 1 TO NumberOfClusters
    _FREEIMAGE Cluster(d)
NEXT

END

' Description:
' Started from a mod of Galleon's in Wiki that both scales and rotates an image.
' This version scales the x-axis and y-axis independently allowing rotations of image just by changing X or Y Scales
' making this tightly coded routine a very powerful and versatile image tool.
SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE)
    ' This assumes you have set your drawing location with _DEST or default to screen.
    ' X, Y - is where you want to put the middle of the image
    ' Image - is the handle assigned with _LOADIMAGE
    ' xScale, yScale - are shrinkage < 1 or magnification > 1 on the given axis, 1 just uses image size.
    ' These are multipliers so .5 will create image .5 size on given axis and 2 for twice image size.
    ' radianRotation is the Angle in Radian units to rotate the image
    ' note: Radian units for rotation because it matches angle units of other Basic Trig functions
    '       and saves a little time converting from degree.
    '       Use the _D2R() function if you prefer to work in degree units for angles.

    DIM px(3) AS SINGLE: DIM py(3) AS SINGLE ' simple arrays for x, y to hold the 4 corners of image
    DIM W&, H&, sinr!, cosr!, i&, x2&, y2& '   variables for image manipulation
    W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
    px(0) = -W& / 2: py(0) = -H& / 2 'left top corner
    px(1) = -W& / 2: py(1) = H& / 2 ' left bottom corner
    px(2) = W& / 2: py(2) = H& / 2 '  right bottom
    px(3) = W& / 2: py(3) = -H& / 2 ' right top
    sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation) ' rotation helpers
    FOR i& = 0 TO 3 ' calc new point locations with rotation and zoom
        x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
        px(i&) = x2&: py(i&) = y2&
    NEXT
    _MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB

SUB ball (BallX, BallY, size, r&, g&, b&, a&)
    FOR s = 1 TO size STEP .2
        CIRCLE (BallX, BallY), s, _RGBA(r&, g&, b&, a&)
        r& = r& - 2: g& = g& - 2: b& = b& - 2
    NEXT
END SUB



RE: Screen Savers - bplus - 04-27-2022

Cool! a little like galaxy clusters of our universe I imagine, though they might not overlap so much.

Thanks! (Allot of these screen shots don't do justice to the animation in the program.)

[Image: Swirling-Clusters-by-Dav.png]


RE: Screen Savers - bplus - 04-30-2022

Ah Curlie Borealis makes a nice screen saver!

Code: (Select All)
_Title "Curlie Borealis" 'Quick trans B+ 2019-08-29
'Curlie borealis.bas for SmallBASIC 0.12.2 [B+=MGA] 2016-04-23
' ;-) cool mods thanks to alpha

Const xmax = 1200, ymax = 700
Dim Shared qb(15)
qb(0) = &HFF000000
qb(1) = &HFF000088
qb(2) = &HFF008800
qb(3) = &HFF008888
qb(4) = &HFF88000
qb(5) = &HFF880088
qb(6) = &HFF888800
qb(7) = &HFFCCCCCC
qb(8) = &HFF888888
qb(9) = &HFF0000FF
qb(10) = &HFF00FF00
qb(11) = &HFF00FFFF
qb(12) = &HFFFF0000
qb(13) = &HFFFF00FF
qb(14) = &HFFFFFF00
qb(15) = &HFFFFFFFF

Screen _NewImage(1200, 700, 32)
_ScreenMove 100, 20
_FullScreen

Randomize Timer
ff = 2.03: maxi = 25000
Color &HFFFFFFFF, 0: Cls
x = xmax / 2: y = ymax / 2
While _KeyDown(27) = 0
    loopcnt = loopcnt + 1
    Line (0, 0)-(xmax, ymax), _RGBA(0, 0, 0, 3), BF 'Fells trick
    ff = ff + 100.431
    If Rnd < .1 Then c = 0 Else c = Int(Rnd * 16) 'need more black oh ALPHA my friend!!!
    For i = 0 To maxi
        f = f + ff
        x = min(xmax, -1 * x + Cos(f * i))
        y = min(ymax, -1 * y + Sin(f * i))
        PSet (x, y), qb(c)
    Next
    cc = cc + 1
    If loopcnt Mod 1000 = 0 Then
        Locate 1, 1: Print Space$(10)
        Locate 1, 1: Print loopcnt: _Delay 1
    End If
    If loopcnt Mod 1800 = 0 Then x = xmax / 2: y = ymax / 2: ff = 0: f = 0 'jiggle this sucker
    If Rnd < .001 Then Paint (Rnd * xmax, Rnd * ymax), _RGBA(Rnd * 255, Rnd * 255, Rnd * 255, Rnd * 255)
    _Display
    _Limit 200 'oh man my fan is hot
Wend

Function min (a, b)
    If a < b Then min = a Else min = b
End Function


[Image: Curlie-Borealis.png]

Eye Candy #9B

Code: (Select All)
_Title " Eye Candy #9B Closer" ' b+ 2022-03-09
DefDbl A-Z
xmax = _DesktopWidth: ymax = _DesktopHeight
Screen _NewImage(xmax, ymax, 32)
_ScreenMove 0, 0
xc = xmax / 2
yc = ymax / 2
diag = Sqr(xc * xc + yc * yc)
p2 = _Pi * 2
Dim colr(-100 To diag + 1000) As _Unsigned Long
Dim Shared cN, pR, pG, pB
While 1
    resetPlasma
    For i = -100 To diag + 1000
        colr(i) = Plasma~&
    Next

    ro = 950: s = 0
    While ro > -50 And _KeyDown(27) = 0
        k$ = InKey$
        If Len(k$) Then Exit While
        Cls
        For a = 0 To p2 / 64 Step p2 / (16 * 360)
            i = 50 * Sin(s) ' 2 * s or just s
            For r = 0 To diag
                PSet (xc + r * Cos(a), yc + r * Sin(a)), colr(r + i + ro)
            Next
            s = s + p2 / 180
        Next
        sx1 = xc: sy1 = yc: sx2 = xc + diag * Cos(.002): sy2 = yc + diag * Sin(.002): sx3 = xc + diag * Cos(p2 / 64 - .002): sy3 = yc + diag * Sin(p2 / 64 - .002)
        For a = p2 / 64 To p2 - p2 / 64 Step p2 / 64
            dx1 = xc: dy1 = yc: dx2 = xc + diag * Cos(a): dy2 = yc + diag * Sin(a): dx3 = xc + diag * Cos(a + p2 / 64): dy3 = yc + diag * Sin(a + p2 / 64)
            _MapTriangle (sx1, sy1)-(sx2, sy2)-(sx3, sy3), source& To(dx1, dy1)-(dx2, dy2)-(dx3, dy3), 0
        Next
        Line (0, 0)-(xc - 1.5 * yc, _Height), &HFF000000, BF
        Line (xc + 1.5 * yc, 0)-(_Width, _Height), &HFF000000, BF
        toggle = 1 - toggle
        If toggle Then _Display
        '_Limit 80
        ro = ro - 1
    Wend
    If _KeyDown(27) Then System
Wend

Function Plasma~& ()
    cN = cN + .2
    Plasma~& = _RGB32(127 + 127 * Sin(pR * cN), 127 + 127 * Sin(pG * cN), 127 + 127 * Sin(pB * cN))
End Function

Sub resetPlasma ()
    pR = Rnd ^ 2: pG = Rnd ^ 2: pB = Rnd ^ 2
End Sub

Eye Candy #9B?
[Image: Eye-Candy-9-B.png]


RE: Screen Savers - Dav - 05-01-2022

Here's another Screen Saver using RotoZoom.  Click on the mouse buttons to zoom gears in and out.  I used BASIMAGE to include the pic.  Making this I realized that .PNG images can be 16 color and still maintain transparency info, so on simple small images like this one I can lower them to 16 colors instead of 256 and reduce the pic size.  That's helpful when including images in code.

- Dav


Code: (Select All)
'================
'ROTOZOOMGEAR.BAS
'================
'Showcase speed of RotoZoom3 Function(not by me) by
'rotating a number of gears on the screen in various sizes.
'Coded by Dav

'Push Mouse Buttons for Zoom effects

SCREEN _NEWIMAGE(700, 700, 32)

gear& = BASIMAGE1& 'decode image included this BAS code

NumOfGears = 11 'number of gears shown on screen

DIM Gearx(NumOfGears), Geary(NumOfGears), GearSize(NumOfGears)
DIM GearRot(NumOfGears), GearSpeed(NumOfGears), GearDir(NumOfGears)

'assign random values for each gear
FOR G = 1 TO NumOfGears
    Gearx(G) = _WIDTH / 2
    Geary(G) = _HEIGHT / 2
    GearSize(G) = .1 + G / 2
    GearRot(G) = 1
    GearSpeed(G) = RND * 2.5
    GearDir(G) = INT(RND * 2)
NEXT

DO
    CLS , _RGB(0, 0, 64)
    FOR G = NumOfGears TO 1 STEP -1
        RotoZoom3 Gearx(G), Geary(G), gear&, GearSize(G), GearSize(G), _D2R(GearRot(G))
        IF GearDir(G) = 1 THEN
            GearRot(G) = GearRot(G) + GearSpeed(G): IF GearRot(G) > 360 THEN GearRot(G) = 1
        ELSE
            GearRot(G) = GearRot(G) - GearSpeed(G): IF GearRot(G) < 1 THEN GearRot(G) = 360
        END IF
        mi = _MOUSEINPUT
        IF _MOUSEBUTTON(1) THEN GearSize(G) = GearSize(G) + .1
        IF _MOUSEBUTTON(2) THEN GearSize(G) = GearSize(G) - .1
        IF GearSize(G) > 19 THEN GearSize(G) = .1
        IF GearSize(G) < .1 THEN GearSize(G) = 19
    NEXT
    _DISPLAY
    _LIMIT 30
LOOP UNTIL INKEY$ <> ""

_FREEIMAGE gear&

END

' Description:
' Started from a mod of Galleon's in Wiki that both scales and rotates an image.
' This version scales the x-axis and y-axis independently allowing rotations of image just by changing X or Y Scales
' making this tightly coded routine a very powerful and versatile image tool.
SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE)
    ' This assumes you have set your drawing location with _DEST or default to screen.
    ' X, Y - is where you want to put the middle of the image
    ' Image - is the handle assigned with _LOADIMAGE
    ' xScale, yScale - are shrinkage < 1 or magnification > 1 on the given axis, 1 just uses image size.
    ' These are multipliers so .5 will create image .5 size on given axis and 2 for twice image size.
    ' radianRotation is the Angle in Radian units to rotate the image
    ' note: Radian units for rotation because it matches angle units of other Basic Trig functions
    '       and saves a little time converting from degree.
    '       Use the _D2R() function if you prefer to work in degree units for angles.

    DIM px(3) AS SINGLE: DIM py(3) AS SINGLE ' simple arrays for x, y to hold the 4 corners of image
    DIM W&, H&, sinr!, cosr!, i&, x2&, y2& '   variables for image manipulation
    W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
    px(0) = -W& / 2: py(0) = -H& / 2 'left top corner
    px(1) = -W& / 2: py(1) = H& / 2 ' left bottom corner
    px(2) = W& / 2: py(2) = H& / 2 '  right bottom
    px(3) = W& / 2: py(3) = -H& / 2 ' right top
    sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation) ' rotation helpers
    FOR i& = 0 TO 3 ' calc new point locations with rotation and zoom
        x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
        px(i&) = x2&: py(i&) = y2&
    NEXT
    _MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
    _MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB


FUNCTION BASIMAGE1& 'gear.png
    v& = _NEWIMAGE(200, 200, 32)
    DIM m AS _MEM: m = _MEMIMAGE(v&)
    A$ = ""
    A$ = A$ + "haIkMn[Sd4[D5OR#8Q#2T09R9m:R9kRP0N08R744iTM3F9T#2N38UDNl^Lmb"
    A$ = A$ + "LfmgLjCifc^c<fmne1e^CgCgmhZLMLm7GfmUOoU;G>YCjT>YCjT>YCjT>YCj"
    A$ = A$ + "T>YCjT>YCjT>YCjT>YCJOjjWnCo;nSf#OLEc^=NBWd<8LDGlAS^SWe`gc9MB"
    A$ = A$ + "_BR7M?GoKGnmoKo;o=_Cok_mKOWn7o]oionoToQk`6Bh\4SmaWW]<jTneP\c"
    A$ = A$ + "\Iln6]ccXM?=<#3;8lASJ7oQ=Tg6hIMmC]WEknKooM\eKooWkdO]CjUAfIT>"
    A$ = A$ + "^d5o#gDGc0?WV>moi_kgl>]1O`kJ_WeOX=d\m#\FSnOo_nWNoknhI>KIh9mc"
    A$ = A$ + "U^n9Q;nGokn[OWT^HC7okR?JdOoOiOekd=ge>?[fmkhSoWOgOk7d9nhTNjde"
    A$ = A$ + "?9<1eYYNn=gEWWC33T6c_Mnf_aX?W69L#knKgKc>TlMKHlAeg<Kin9M<X[OZ"
    A$ = A$ + "ISXYcih3AgLGMN>=mh4nXMn66YYO?bcYA^=87_emiHlVRKIcE=Kio9mjY;G6"
    A$ = A$ + "?ne[OZYo8ma6YaZ5McHoMN>dg<5kQl]JS=T>?7a3Eh\k5O8k>_WOPg2iOHfm"
    A$ = A$ + "IWdcW`AgEooU?e5KHSVM47O\[=T[OBH9VGGAb^bN?3eN4A<ZXMi][OBaDen]"
    A$ = A$ + "KaeoQm`[iOH8ic9M\9k<gM>#_n9=O5N<ek6k0>ObnA963Dbg7Uc0>nOki?4f"
    A$ = A$ + "GOjjLa8nXmLH<=OPAVMOh9mh9L4eUJSCZa:72SLmC9<AY?F5TS?8e`NoaGnc"
    A$ = A$ + "RgW[cCk7\=eXMa7h8mk:NPg[VKU^bVCjhBGoT`5BgTjXKR;]ccAnfG=nOBgl"
    A$ = A$ + "6OD^LI3N#cG1c;;7oV]efeC\Iko=lDSdigPiCl4>RfA9?LCN2ZT;WdaV^n9O"
    A$ = A$ + "n:lS75O8mB63\l9QaIc[AS9[?WbMUdm9n`WSmZLDALQXHNX4_5>?a7^=T^bU"
    A$ = A$ + "CjHCGoTZ335K=coTdS;a8h9:m`fmCMCUSE=^_WKZTO#LnldllihS:\T8Ik#f"
    A$ = A$ + "?8^L49Tl7D]?j_hmVoR=d\kk?Ym9mY[aPfdkT_<<VhgeWNKoWHJ\jNT^_Nh3"
    A$ = A$ + "J7SnFEIo#imbSUgSmQnmafQnL2W9La6la8bh4=knoCJOjbUKRm`WS06CAj9X"
    A$ = A$ + "HGjYKcH9H<3:FK>n\7?A5nXjgP]Ie65fSjfjcNk^gcg]m][NnXm2cF7hTjR?"
    A$ = A$ + "JTS?daD7Ug9aD=MZm`7liFE;:jkdL<ja19KK\^5U?P\M#O2E^MC[W47S`i:I"
    A$ = A$ + "H\AUn]M6eFZbofde3nEQ^GI?>ZW>1SQXAd?VA97O`W[n_W;F6kS_FYl[Cg?a"
    A$ = A$ + "7dV1cE6mERH]A`7kFWT5H3?75Z>W?a8_F\aG]^bgC_#HR6ieFkNjFb_5nKij"
    A$ = A$ + "gD_mNa7<66f>HldnLNZSofh3:O]ccLdEe6>a7_6L1a6]nAO<cbnP2<2a3^^N"
    A$ = A$ + "E^XXoEJnlTn4e[LmaDmJEUOhNg7eeIkbSkPaT#k>>_kfk:a71b[]5I39^N_>"
    A$ = A$ + "a7_D\QdO7:GmM`7YjOEa:CmUhjch?#L^iBj`Ejm>nPi:V[[3>gfnecliBOkB"
    A$ = A$ + "oV>^Fl^7;Vl]Dn;FEK_4;#lQ`UaNcI[;mCT^n9Uo7ON2JDI=75NR4Ohe7>[?"
    A$ = A$ + "?ZWbik#?WZaimiRVh067RN^9KE<FMVCjNn3A<Wn\SAE^1Ba<ifUHKnVj`jbW"
    A$ = A$ + "c3DjJX_SWHSG3n#H3=fVS?46YjYXh4_gh]ML07SN?lQdgBan;lAbFU^^6VPg"
    A$ = A$ + "GkHZo:NVeIRWcZT?M4_bOGg?;Gg?EgHNlhdneImaoj`7=Zeokj?nH_9L1cC;"
    A$ = A$ + "Sa]gHaNldL<hDL82gn?oOlK^aVPbEKRBnfec6AkgEGOJ]ZCl1aW9olZ8R36I"
    A$ = A$ + "^#5Fea6Kj5W]>d?I27UjcmLahh3j;07O]2K`H>CjGnmjnVX[c]_icYA:^7?n"
    A$ = A$ + "2GGDjPUeGeU?cAP?78YW?SEQn5e3?#iX\3jfF^;\a9FjQQ?LMk4n`m1>Ykig"
    A$ = A$ + "37cccmZlE`c?TomN^=ecAn3j]iA`7:fLaGS8aBe1_?7:>nPhJE[9Z=k]9b_D"
    A$ = A$ + "nBK?3[_Gm=cFWkXAFomNa=#O4Lo5BkI8^>>a#DG#O^kjefXZaT[`7T78N^[N"
    A$ = A$ + "d0H6b3]cal\ANf[GnNiPNGla0mWL_kj4Slma7=ZGnLX^MZFdmH<Z`7Ya:g<W"
    A$ = A$ + "T9meP^YS;79fWdL]=\^c0BE>GSEn8jnTVRQ9]73e]]6`6O\7`LRANXHT6YLi"
    A$ = A$ + "WV_2>><S]PhTDO>]mde>aMdNCh1On7LOlSHa7P\kbUKS?AcUQ?FRReYGMKYL"
    A$ = A$ + "UXl]]I_>R]I3K8o<9=dlmn[2M_mmhXZl3U\?dKL#?G<2CAMW_\>j>HT4nPeI"
    A$ = A$ + "nC97Y1LBko^OCdgDGVBOHYMJeWDFSR0Khadcm5VcL3_]OJ8iaPhSTO;DOX:^"
    A$ = A$ + "m^f;N0lY[SEiK8eAOJj9QcjiN`UC4gf;Gd]_[g_N:>6>_>]?o;mNW2j?TLHX"
    A$ = A$ + "a<`Aki;OJL?mkTf3BnBn#MWjQ^]<7SClaVaQObm5>U\1ki`[7n#kOSYW[`4N"
    A$ = A$ + "=Z#oe^9F_I[_n:9k<d6MGOI^N\`DdWXml7PS5Bo^Kh4^WW7oMO0TZC_f_7Sg"
    A$ = A$ + "_7n#]eWAkIDLRkSIeL=fJ[L][hceCkcJ<9gWFQidieJLiGbjn57YmI7^n[OG"
    A$ = A$ + "O]cCPeW8U_NnDji7S7GjVOWW4O[ld#lQV3MUO16?bVeAn4jS4AK_>6I_l]g^"
    A$ = A$ + ">V_aD\ojIX[iGfHd=INUl\j98M\Nh3?Gmne:OFNYm1GnLokUlZ`7ZVDHmV[J"
    A$ = A$ + "aLJnH4>;7WO_lJil9GgIL\:nlKm=3]O;mCT\c`eNAZ6BCn^BiLE<6Yh:o8nS"
    A$ = A$ + "GP_DkQ?f[NjmePhDm1_hKlh[Eo5]]klG5fA?c7J>A>Rde?YLkaaCZ`7nnUFU"
    A$ = A$ + "lfc99]OgMn4NAl>SoXBoY:O#O\GA_0mM9Rfk[lYeg?<Bcen_lid57iH4ZcWZ"
    A$ = A$ + "a_DM^f>G[NICeGTKoOfnc:lQkcA2WXhAlLM]BmORT\G7WZ[BR1JDJ=jodV[W"
    A$ = A$ + "S6QS869=NSF;?^?[JO6GcCK?lA\E<Anfi5WWin2abQ?2mQ=ReE?mgbc9R^NW"
    A$ = A$ + "_ScEb\ia5BnVb;KehZL]E8I>Sa`egF6ine?iiZCid=5?[\I^4nG]CO8k;MlA"
    A$ = A$ + ":G`\6VOoMUhXmAEOc\U7?9i[damaPBaH`mAQNaS[HJW]?E9nEf4iJ7\:g?KF"
    A$ = A$ + "[7c^?[PWHOIUm3_>A5oGFKbMnMNWnEhMCB#nfnOENOM\Q_^^eg_LH3`[L_QK"
    A$ = A$ + "_lj\9?NcV7fY?dG3<JnGInGBS[e]>J2j8J^Bf\>aV]\h9:OIlIEj;LnUYnc="
    A$ = A$ + "S3MmM3fb9c^n9FS[YJMEnI^<igm>i?F[#LN3M\1_6=nf6<285[Z?fhV[MfbQ"
    A$ = A$ + "WX\]A=o\Zfg2Mm8g_ZU5K0N<5;5_Ba?;al3n=j7KDCggGKJ4OXiQRi[d]kce"
    A$ = A$ + "bUW3OAglk>KI`G#>M?G?g36ZboQdS8nHYa6P75o`j]`eWlJNo3nJfl`GY_ob"
    A$ = A$ + "]c9BZ67LRi\cGSH^=3VS_U]_O7ic=DaeWF?0b>BJMda[Iia6P?9?VFW_ai>H"
    A$ = A$ + "ei]Md1lH6Be04a7NMIU`9D?h#R?NkB>>i2RkGXN>MY\9IOi#XoLmCYm#Z4Ni"
    A$ = A$ + "VmDng#lIcV?^GmP;Kg3P5N`7?PHTNh3BahkW=__W<1_;JhN0JileMicjZRiR"
    A$ = A$ + "BcA6U7nJlk`TS_[ORkG8Zn0hJ3Vmg2;Yiji#Q?0?cjbb]E#\RO^4N#GcQLOJ"
    A$ = A$ + "lZ\XQ?djAFma:gCl>4?CmPZmj]4nHibQk0j:9l1]Qhj;<n[S:nXANnW4oik["
    A$ = A$ + "L<WTnkF8gfB<fSEE?#O2HS4n#mmEcMAEnZHMmXHBFNIB#nTd7Zla8E;ICW?n"
    A$ = A$ + "Zj5FoXS?BihBHTDM2_De>dPb1I7Uc1VZE:?Wn<oVngUbG57;m#^7`4h5VWbD"
    A$ = A$ + "LZd_m35_fQg[Zom4n8I_YgJ3JjliNbPgnLlAGoWTZ19j?5a7:WfbVJbnjQ#V"
    A$ = A$ + "DXSDY?8O5:GO]79n]PoMo\B_c6Ck=0gDWVnCOflfXloel\:<`NiYQe]^KW=U"
    A$ = A$ + "OR=aL<KNn;XOdXmZa2I7FfD>Lj2k83HoJ:gf:_<dGlhH579i1hmfoml`j_WF"
    A$ = A$ + "Y?FYe;[S?D^Z>jh3nN`=E30o8VOh1dAXMBBN]m;IALO9HflcGTo5ec^1gW;X"
    A$ = A$ + "^0cUW_oSMXU=GU?boRD=OCNUfCO9ka?C#7ac51S==]6Z>lmo6o;:]?iaSY^R"
    A$ = A$ + "^7_ffn99KBeF7SG[JmWNXimPLPkmEZOVj3nh[KF7XgSNh\ii>]=icUf[L[bi"
    A$ = A$ + "_Wk_hh6[6_n5T;\V0DnHhk::omWc?2N_Sn1c5QT9:6D7ODV_RAnUW=O_SL#j"
    A$ = A$ + "6>?_W_6;=?n5T5<nC>fAJoB]kndi\iY7Tl#aIVV_LY34[ST>d;KO=k1:7XMR"
    A$ = A$ + "Aa7;?o=0Ok4OOd:O<hNP^bWQ\e>d_h\ig_Q<bcSO_J]ZJo3DeK2mUo`\?<Ni"
    A$ = A$ + "cJgfSib[g6Q?X=fUVg:jckAYLJjhST=fVLK_m5mYcoO1I5kSk=?aaha^D_Nj"
    A$ = A$ + "dnLmB[31IPVg#6gAkkli:FigIYi[2nd9>7HEcELkhmNo=[inQSOd]5=KiaG#"
    A$ = A$ + "oXmo4O[gWEE[AGZW`iE#fP_AFm2i[QdO1oWR;WaSai;j#Q?:nVZle]glVFmM"
    A$ = A$ + "NMFdX^fCV]Li>TML];`caa3XNRGORLNgT^3UO_DM9dn7m^dhXLO]a[W2E?[g"
    A$ = A$ + "ENlFPnFW61;Tle\2OD]>kXMX^]dI;W^3i87[_YKhkIPYLKAMa4nHckIQG1oL"
    A$ = A$ + "]FBdkEA=gfE[7:^?<cLlbHcJGG\oNfmOkdWf8Om8DU3o4nXJ=CUf?9YNR?oj"
    A$ = A$ + "M7_Jfb[1UUT7Tld7GPnIX[YMmbg;Gf[HjN9b2X?D]_7jg5gkniNoTGkZZFVG"
    A$ = A$ + "NoZ2WUiHQOViZcSk`[_KWlhFH=a[JdBS7YlPM8[mk06aUKDfin=9lQGK>BGK"
    A$ = A$ + "S?X_Hl1egCn4Xi5DS9bj:QggQ`fQM66[TjGC_oeCaFFQMTLZJ?ZGeQSnMdo5"
    A$ = A$ + "^PckhQ1WPSlgEX9\R7o:]Y:OZdl`nBiofOOkfgmO<V2j3]6_Si]don^hSIgW"
    A$ = A$ + "=0fPf1Bn1ieJXF?]YimacYEej6RcKBZ>odhCEi3MeU]N^IZlmd73`m=kUcgG"
    A$ = A$ + "oT\MXJRPh3gO0joWonABfNhnRhbjKEh\4CD57MZFM9nQW?E?_9OblW?Wk8RE"
    A$ = A$ + "icKia7#6kn8BoBXnBCGJgi3jEb_g1nPH37OThEYO]TmQ1LA:7DNmSi7C<#UO"
    A$ = A$ + "CYHAdh6nnYV7W^`8jjDlLYH2G>IL#>;Bl0U7jkT<H9h?L4e?Bco5Sm`[]XdH"
    A$ = A$ + "]_dHXnVH3U3aD=aD=>O_JXYbo1:GE\hncTWSONhHAF9IM16i;Q?VLKGSE]7n"
    A$ = A$ + "#h2i3BelL]4lg>mEZ_Ah3go9U?UdjoQce5cAAE=U`lNhH\FKQaVkHVd_OG>M"
    A$ = A$ + "fbiM`7nL[CkaKNg8<KnYX]ke56a64O`JGemoH9h_1`7^^HjHON?96b[?g:lA"
    A$ = A$ + ":GP4Ohi]ba7N=dCnHYdY:TiZmghC=gjN<JKVKSEPG:n6gGLOo9am1QcC`BaO"
    A$ = A$ + "5H36_QWGgkUnH?Am:ekkCcmjV[?`5EhShm=KiM#fkj8N^:hH8[>_hDC7:ik#"
    A$ = A$ + "ZoIifWg`A:G42C`en7maoEP?hnJDlIJLR?g8>]TS;IboZlOkidKIa76o8Bkk"
    A$ = A$ + "EglN2cjgX?d;Eo4>Bn;ja<EZg?kfnERfL4^>U_P=gi2dfiAEH2U_>Y?E>O7k"
    A$ = A$ + "ACD_J?l1?n3nKQjK4Od;_DKVCZIgn_BDnfK^IVZnb0m1ZM:N#a_jkU7>_hf="
    A$ = A$ + ";[?`G<_aLZXlj:lQbQ;Kk;gL2Jm=Ea9Wb9dkbnIgn_BD?8Q=DnPGbHeaALN?"
    A$ = A$ + "mJ=Y:F4F3_jiDV_d9aGL>?DK:UocS0n`e[D\jnM_Jh3F7HLN4InAHLQ[HOPK"
    A$ = A$ + "SXGNnlg?Um`7CaO5LD5nPf5EkNEm]:=gN9oZnPNK1hQ[TKSfca\C;cj]a>Sh"
    A$ = A$ + "SfWkE[c2OXH5C[c`:oROD]kmbW89Q?8?iSOe^^Ubn1>bmYBl?7KbUc[VmSDn"
    A$ = A$ + "ZjYG=mn0L4mmVn3i[Ak4e;?G?5l1Jc>nX2[XhbI]hkca\d3_iNWYNee?YnUT"
    A$ = A$ + "mRDmEeh[?RmKV]O#>nP]E_fPdlh?]nQR_QcoQ>7W3JR9Bc_F:_ML>\NHljU?"
    A$ = A$ + "c1_deIkCe[]\9`lFi[7:7W_I_4L1`7DgWnXW6;JEa7l8^GGWbkSdgflD6#7n"
    A$ = A$ + "ICN^dY_j9l1S1Qn0XaUikRm7V>gEI<OgMkeL5_3mNaaGKeYec#\fBW\nTb]S"
    A$ = A$ + "jCHNAJOObGUE6O#o2Un6[5HRoOh]Tg^MnOINFml]bJWAnDieGV7C5[ES:O\h"
    A$ = A$ + "maHPOdh3F7E>^M?lAZ];kMahMWT^T`7<nR=e_`U?O?U[nUgkWo_Oa]k1i9VO"
    A$ = A$ + "1jcBSla\ZZ55oLlkLMFigF:^CO=VBm8=F9a2N=m[mj77Od;6T=f;Nd_OU^\M"
    A$ = A$ + "_4>5oZ8OMN\7E=O2gS>mSRf8;_LICNYei^I?0Ee3b\a55h37S8R_oEX>WoN3"
    A$ = A$ + "Vk?QdG7JWMTa4MoC9n8Z3PnT:lAjgRgOggQb?:ImKGjR?hi8nPnQi[W8okF0"
    A$ = A$ + "]Z=n;jaib[k8R?lHc[Nofe^_Dmc`L?jjN^oJNl023A\ZWo0n\dWY=06WMJLf"
    A$ = A$ + "QT>?3ImKS]_>9lAJ=QD]nAeef[E\9?Z_mikB3fgj_3LmnD]?laaaHM:aLL`j"
    A$ = A$ + "BPj7N]loNKOa`7LlNO=l:M\ZgoMDVki][:onljBS5Zn2?>2gGfDoMRZdmN9h"
    A$ = A$ + "Q0nXgkEAGGO_ecPC:OGD?dWcjmVK8Z_CkAncRmKnLRkGCJlCO\h?jGFDl1U7"
    A$ = A$ + "Ye3<m]amce]KZldUR7QSOh_3CD>?mHOL\Fb?X:\HU^g;5GHh39SZFcPnHZEh"
    A$ = A$ + "4jCKjlLLJON#CncjmakQ?HLM9<Yb_PW71nK\jh3Ecl>OO?hSkUT^<cU\?oGN"
    A$ = A$ + "l<lnMOf[J?Eh3YG<3lA5e[V5ZRmPh0ojBgK2O#OHiihJ3?Q?dgU\Wcg[^\O="
    A$ = A$ + "IWbaZZ?OjhR[TKcSS;Tl5AmA]a6BjUki_CSlecH3Sjaig3O8lZWCf4n8=?DK"
    A$ = A$ + "h[GY<O0ISK?8YSWl[YW]Xk1OXeQ9o>7K`_ci1^NGMLQ\9BnHea7j8J7^7nPf"
    A$ = A$ + "lih;YOQD>iCn=in5`lfVNVdf6_7ojX_J^N`D`73PGBh3YWiiRN?Ocf3OT8OO"
    A$ = A$ + ";Dm3jnXl<eg:mS4nXGkIea7EnjFQ?fDC369IX?754Gd6WbgcCk]7Xba]hl`B"
    A$ = A$ + "\TWC;?_bkjOh2PGlnRk5OdC?\b>C:_n\O8USB_?Bo6oD`7njSZ:ORTZ\[V`7"
    A$ = A$ + "N<KlH^>OdHVNOSok#K2lL9kDZobm_Zge?Ml2j;ljfU[?EAkiCU;C79gEDfai"
    A$ = A$ + "UWb=M]LoTR?3Q?jQABme[>n8ic[`8^N6a1>^`c9^KCP?3VC7nKAiVkkKZ^SC"
    A$ = A$ + "LXO_YLSi]mbi9l5R?DL^\?#kEZnL7]W_ENNkkQ?XME?>5jg;eUCaT#RcoGb7"
    A$ = A$ + "?JCoSm?Q50KT`7lK[TOYaeK4eoMKcYmO;eG#lB?km^=Xm`7doiDl7n_SKSL3"
    A$ = A$ + "Ni5S?hHBnn[K:g?jJk=FM_L:Wl1Vi0dWgeDoYG7BNK:QO4Olb7;j9Q?TLFa>"
    A$ = A$ + "hSgjig^B?gc?BU^[WoI=NVSGL\ZNV]f9ecmOSZlb#O8NZmIQcbidVk_kEea#"
    A$ = A$ + "BG<YSgcO<R?XLem_>Q;HoS?>CUmkS0n`S?WO;g3;ijFPnTjko92ODm;Bk>Ya"
    A$ = A$ + "QhmbabLL8k;BH4JCboNYSim]^_ObgPW2nHW[#ahbm>A?gXm\O`mnORIZZiAn"
    A$ = A$ + "kjagE53J_LnF=6D_HR^aGP50Khh3?_R:nIO\4a_c_eOi3LYS?Lo0dokIg8=^"
    A$ = A$ + "FCOjQR?\chi3RjGL?MgSW8Uo:N]]oW\O8MCNo\>UU^_S?h_K?OV7=_1R7mj:"
    A$ = A$ + "J5a7EbAGGCl_\[ldKM3XO9M\diLm=g7>>V[?OddgV76n0HJOM4VdQZZk=G7["
    A$ = A$ + "bgYNh3:SLMK_6:lajYMfZlRd3OhfOhg]JaWGQ?dkK<Vg2Z[M3nH6]ML4gCoM"
    A$ = A$ + "MLg?0gWMbGEhS76ORSj=f:YZg=Qnhf4O`n^4V\gh:?BJ?lAbG\E[n[lj:S]k"
    A$ = A$ + "dlG\DaB5>[6C\mIY7aJ[VmKEh3N=g4;e3ZmN?cIVGWi^M?enY_ECCKbjCJ]5"
    A$ = A$ + "^FRmgKL9Je\O\YFX^B^lWHUKliHA`74GhfoeWIn[XOE4O`h5U_4?<nlbne<9"
    A$ = A$ + "UeboZZJkSf4ii:eMOam9=bWW`NnB^Zco1e]T>5[3[dh[_Lin0m7]f>GcP>n#"
    A$ = A$ + "]M?nc69i#b?T75_VR5PTkcTonL^Wm3A?jflg]?aOWG]gjoOUa7Ylo#oCdaCG"
    A$ = A$ + "nGdGTRYdS_ZG<UMY7#Kec1HbnQ?W#EiS=M]?Sflg]?9USi:lAC^\JhSD<6mX"
    A$ = A$ + "UY?8dG8Ra_ji?]4Ol:K[_mI]^aifPf[Ym4O_5=Y_]I=O=kn6LTS9hnhUWoTg"
    A$ = A$ + "kKF8l1?Z2S4SEMfbo#kG4UidW`YKokjWdl<YHZ9n`]9Di7B<g?[DOCX?acoI"
    A$ = A$ + "J>6GMl1m5VSknaL9]Bm1Xmkf4LNXM>IGIZl`UL^F[XDn#CHS=f5WMoRYKUVO"
    A$ = A$ + "PNiGOj]mPnU?F;mkJ9]MH]OG_BbLVcQYc7giMT\O#m<n^IMUa7BW:E3GRGFA"
    A$ = A$ + "lQ7o:cSUWOTYZG]SlWj6Ec]O<oK[2_D`KZnIhh]J_mRhS=iGLf]o#ODSZZ;6"
    A$ = A$ + "7OTZm^?RMo]]kWF>i_G2C_K2C4o]BOO:?^Kb7j\Ui5bNfNCaJDR?8=KN:`KN"
    A$ = A$ + ">NBjF;I<8Qn8^NYlh\X?;^nYSA^7lA?mmm8GgamoPe^aB9g3bNb;9okmi4\k"
    A$ = A$ + "COflVaOL<:^NmlmemUS7<nPi[fS19=?#k=WA\?UaYU^FJ[EoVYO;nMDWRHVb"
    A$ = A$ + "aIW]\>8cCeOU_73`n2_NZ;oEF8NLSoiPgI<8;7?HlQ8^G1Xn9m>S<=o^<>HY"
    A$ = A$ + "_cm#7=NA?l1c=0WoKg6Uokjfajb]cFF7TidF#2Ohi#dc5WTm;3o6>KKLGJo#"
    A$ = A$ + "mC4OXnjYgn7TWLojMlQdOIo\R]?UOH93j]_\Bk7NleBg8Eg57:Oc=iMJNbYL"
    A$ = A$ + "gcSXW_1iGY6kHZlLagXm>DM\_Gf:MYUe7[2NSm;LmYcakIoDBWfa8E[U<_>F"
    A$ = A$ + "hjj;=?<mR7I3=KIK7iL_hjT\deUhh#N]dLC\9C4CdJ7:GEboJO=[Ujk?BmMB"
    A$ = A$ + "_Gh3QaYo?NmehS9T\5hb4WlHfmib?5?OI<[cFVF8Sel#C\#Jl5?oKneb[iUS"
    A$ = A$ + "?:dGlnjKF_OG^\1_Co3FFO\j`c=b[SObW^_BkEWl^OBnHVEaTWJG<oiKnnI;"
    A$ = A$ + ";k8OmiE^Z^HlHGY<RHRhh__8m4=6f8aKjj=\fAOil`34S`m3?VW89KXNOb>Q"
    A$ = A$ + "kk<73aa7D7`GO#>YnQ=Og\UQk8G[`7D>8n[AbGUT=dIR?Lk5L?4QnIhDU?a;"
    A$ = A$ + "MLjM`8dnAB^hSGT`59MI:?[`:m`7amKTI;kfAVj[CDj7Z[[Wb[>a7niOIb1X"
    A$ = A$ + "?kc_GbGPk1O\daY7T1EDZoI_HdMIBE\gN^Jg=oD78IYdUhN_X7Se8l;cYg;g"
    A$ = A$ + "_T[OBiVRh3_oWnP;\B:_:jc76lQe_jT_n_M\A5nQ?3oniLM#I6]a<em#c_YL"
    A$ = A$ + "Dj:lKMiUnLI>7<:>Fl[B_0_cedijI7d]O#OdIOmA\_]RBHPT<X:FKj7=mO`_"
    A$ = A$ + "Vbf`\U?gQlSif\:GLUf#6\ohU8CdW\g9QLnMIoXh7>7bnnfVWWk3Gol>m=Ei"
    A$ = A$ + "MdegmjRbSEODo;V^\h;8cXNBE>lXLIYiEe6Okb7[C`dLIal=d8O>QehYki;n"
    A$ = A$ + "dig_HO>k?mh=CS5#o9LK\NL8UhTIcoOAiDbFK5nHiiGL4[_R6?5[=d[TW[C?"
    A$ = A$ + "O`d>b6oYW=?o=ko9alAVfk7XM3OoXm`XSL7b7gORDmb8M]Vlj#`kGb_C]fSl"
    A$ = A$ + "lLba;hJULC^JV=onPd54AkXb^RKc`eG>4j5gYl`S_Rf:YOU][mSgWfnCLflc"
    A$ = A$ + "PmiU]KL>gV1]UF5SjB;7nRb\DN;4oba=mJ#hWVL#eWWhGO>?LlQfW=;ee>ZT"
    A$ = A$ + "YKhh3nIGOiWXL#kc5RdimLe#Ie?2IPM6bG=nVh5V?gfH4BFYg;^aOQIcO?0i"
    A$ = A$ + "RkgPGoUdGkObh3i_PS?hhSlmea7bRIc3?0M0Y7`J8PjnRhjbfSAKS?W7EM4k"
    A$ = A$ + "<N=\FEG[Uaf<Kni18;JlWo>RGSA#lA\>3W=?l0d3lnFZk;BbQ4n`mmh`ZWHb"
    A$ = A$ + "TfoM\P6W`a7\n2flTW=Om=U7=ncg7_CigVfJ?dl^M6?g>nh4<oV>Ub]cQYnm"
    A$ = A$ + "2b3GFheTW?6BEMXLHhm1T;=nR_[Dhk68O\1moGjkDbWT^P8egCK3:_g^nOej"
    A$ = A$ + "1`ckUN6;_>Bh\YeI7eELKX3UghIcWOAIS`62Oh__]lgg;\6Y?LlMh\<O3J_I"
    A$ = A$ + "WnA`i7Z93hk0IQOdH:nN_dbk7:>ZeOVFgX\Nldl8cm`NFGoL?ZOc_f\ie_Yl"
    A$ = A$ + "YjMkKZ6hoYP?BeSfNf:lkA_obB_3oFJm3LD_gibR7[Z_277eKM>\TbQ1TAdN"
    A$ = A$ + "I?l1_k3In[\cTR[`iK_^G5ic7TC;_>1>:Ec#\^[X=T6E5O6_o^ojcVg_CI4e"
    A$ = A$ + "3LlQ;ODnI>Lf?\c`iiZb6YT1YW8SOUb_ShLZCO6CeRYj_ekkcD>9XMVAfG\W"
    A$ = A$ + ">oO7b8_o=UO6i_`7S?XgI_cV7^3m0A>^WmgNmFM?oJ=k`glnfLUU?Go4]ET`"
    A$ = A$ + "hN=Zf[FNE<GnJ_l`VG[[OB_7EMITZgCbSZ66ikdjYc7k`OTBkATEf<;kCkl["
    A$ = A$ + "N4c[[oNYWh3JoPg]_WC`aFJSC`J>XMm7bi51j<4Oh_;jhMYc_le[IagXaiH\"
    A$ = A$ + "34OXh]7f?YN]RI;36D69OWlnndLPABfNhnKB:F6Zk\YNeV]<H0i3SAe7;eeC"
    A$ = A$ + "XMUUU7kl]LO]Cm[EnGNgmS7Unm#KFf3DNn7m98mM>nR`F]cWbkElI=Ki#7IC"
    A$ = A$ + "?O=lmh6>fbBbK5O3co87_CSiinGMHRcn9:c:io`gi[5RV<LcjSiBnMkkb:OA"
    A$ = A$ + "K>Q?hNSdQ0ODl=Yh8kQ?:c3e:a[_0iF9?KOOJ\5jWZG_:g<oI[\l5j?J^cCh"
    A$ = A$ + "3gfiVj#Kfla>maEf=BnEVbMgBg7n\TOgae[lJYl4WfciXN4]e4OjcFFHl8[M"
    A$ = A$ + "RDnMmjBMcl3_8laN4GgKN^MIMRTjCGfn`5#N;k2YeWM:>FZ7En[<KN4l9G_?"
    A$ = A$ + "DW`G_7;7nXhKH]0imS<_:m`6kR?FUn`5#^;IIc74^7gBo>LO>RjA[VlehadL"
    A$ = A$ + "2[aJE>`I<HCU?6hZ:GGKG9O^NBf>ig_I^^VMogRXcXa?Em=ZgaIYll`eJFGk"
    A$ = A$ + "7TF0N=iC^8_F3T?VCYmgiKmibTi#8QAZZM:]f1IO;U5;AOgTeGT<UhSfomaI"
    A$ = A$ + "ljD#jG=l1c_Eila>Ci\YKieST_WiE6GeTjO4YaQlfODO6T_VZiJ`_egUNO0`"
    A$ = A$ + "g3IC[OKRj:TgC[U:e7Xn5RAHLOgK]k<5i=>Z:WE^ogR?OY]i>O[JcEe;Xl;<"
    A$ = A$ + "E7ZETRc<Q?>DcokC#nCmJFGlZ_`UaNLNneTZ?[UYnOAk9E_NDG[Kko5eghTW"
    A$ = A$ + "gidLKFU?gmnUeH0Dfl;eL6FXWhSEje4?eQBH3mLH\Q9lAI>ANUbNdNDKbm?I"
    A$ = A$ + "cL1VhYWHKc9n^bSi59=7oZ?Rff_WFQ\E\I?ojEeo\:4>RaSbLg8iDeC9IcPh"
    A$ = A$ + "[ZaVWJ]bSSligXZFTXoV?Ufg>GQTQ\n2MLROLZ>;S]mROc3ekgWGPN2O_\ZS"
    A$ = A$ + "k>OOk#2[alUNga[lTiKRSIn>min8iSi3Ym=`EiSahiHgmgBdM?n_egmbj?FE"
    A$ = A$ + ":LFomS`G>Nk;gj;[k[O:o#kn<O2l=mQThHoM4FIkl19gC4mSecSf8hS_DKnE"
    A$ = A$ + "8o?BTM6fGdM]b<#o\6kjN`7?M\RYoaO;JK;m>`9f^n6bj4UlCbOWBg;W2do["
    A$ = A$ + "^SmL_]eI[W>C:LfQUYMNbnh^N>ELlQfoDhL_l#a:fIL<PgnLiAih6gY\]RBi"
    A$ = A$ + "=GiYeg[=65ODfO>KM^S6mEe1]cTRaga6\_VSciao`jDYgkdT_Bk<AKVOl0O]"
    A$ = A$ + "K]cL7TkcTS=H<P^LUb9?7Fnn]MSna\g<=CjKXciSechIMBS;Z[Sh3GOa[CXW"
    A$ = A$ + "5gC<<eYX^9g7;N4]5?7DYm6LGnVZK1]^WE>6ZVkVO9WS_7=M?b?CncSI];Xm"
    A$ = A$ + "Y`dL:hnIiSIbm>5=VimV?o:ZbO5okim`h2^WO;6o<g[6In#LK\NKEWSkSO^_"
    A$ = A$ + "GZFTMlAkLo8OWM\ZD#Gck?hLFABk;SJ>_ZlO85c2eUhLU=B^fZlmCo>ZfljU"
    A$ = A$ + "G]f_Sd_mJc\g_;]?hiP=QCk=o#ml_Sf?HMTif]?a8_FlABWPH1jo^_VTT>SG"
    A$ = A$ + "G4DGf?_7K:eAImfekjBj`L^WCG[[Oci:Qj_L_#`WGD]WIT6?O?Lb8f>inFS?"
    A$ = A$ + "_Cd>d9nhiS?XO6L<OV3ZdC#n8Xgm^L>_ljHY2ODU[9Mo^N<]c#L[7O[k[U?n"
    A$ = A$ + "^G?:NK9Eo7TWTOSEjfSJ7I?BlRcSKl=LfjBod8L4ggmhig3O#Rjb^?#TXNN_"
    A$ = A$ + "L5ClAJ]TWbkC:?Ylm<V[SAlQGGDNM3BIBElglJ8O`Hgg]nj3??777k3V]nd?"
    A$ = A$ + "=2mUmRGMhLbNicggbJlBZ?Bl1o?a19lQ_gkka`T`JBGT]=7kT`:^m3jKSk_6"
    A$ = A$ + "mKc?WS5mfg^je1IK:_8WHSW?nXA]n?i[b#gMAoHJ<JOll:L0eACa;DAnNk1e"
    A$ = A$ + "WmfVkk8_7JWdSga7g`cS=Kglg`cae#f?:T]Um=cF?jW:ImgnHXaL9>`cQjH9"
    A$ = A$ + "OZZZGUNn]hnPa_;Q?dcb_>7o>2nXkhfGfFgQ\]VFGhKF373f75YI[3mCW2W]"
    A$ = A$ + "L=h<`c`7GUWWaWhi\dmm:Q?X^WNVjkLoRBhSDL>d7=NnTOFJ>PhlLZkUo>4["
    A$ = A$ + "V\O`LP=TNNeg<KMWOEX`I7N=3HWAj\YhHlW_?VKbnU^>YGE]_g#MJ6SR`[Ea"
    A$ = A$ + "oGU31_=8<1a<kaS4O`HXdck^fS\g[OhTNnD__MWkAjIZ?gcgcNojDGaecY>E"
    A$ = A$ + "eJMbSiY:NIgnFbW8VS8?6TNi\bYfeaj>85?fQkmdc_jDj\3LmUiVibMD[kG9"
    A$ = A$ + "6WRK;PcGVS5l[gSiQcaMkgQaGhTSGHn5f=>I`gnl?joN3;W?YS9MifmLOg76"
    A$ = A$ + "Z[\AG8l4majmgMFncBOGjmnP>FkgGJ<LM_Yil`eUYm[ZlOWT9TBhSD]i>mnb"
    A$ = A$ + "CjaBjC_]=OXM]IDmL^TmI:QgB4aVYjGoN\QE=_83GOifIJH1]glikA^MO>Wd"
    A$ = A$ + "aU^nYV>S6oN_HFSj1Q[aa7SdRZRMo[`MYi#\<fS>b6A2OdfOGeNlj#?WCjhB"
    A$ = A$ + "h8nn=Seek#j0Godm6WRg6dcXgagccBg?W?5e6_Qg6#n`j3XKKhTni#5OCIlW"
    A$ = A$ + "Ej0fIjUkYbWCWFZbIElk7hi8mjZiWl[8S6B^LB7KZhKD\83[3LmCNll<NlMe"
    A$ = A$ + "9kdBKgKilEdii`JH_G]_lETA3M_Wd?3JT[JPkWi6NGoRjlLhloYHBH\4MO>f"
    A$ = A$ + "CUi5>EG0kbKEbWIgWMB_NZgg>`mYi:_j:gMnVacam;Sege^][ROK??f3cOWd"
    A$ = A$ + "9i4?J`[E[kYD=N<dckb]_ggme=k^a`4JCdnSWcgkR7?YCj[BGn\VnhNgP_W5"
    A$ = A$ + "laMdiid8FgD9JXJj07Al1GSagL7cF6NBoLY[Ob[1;>78OLe3nLhlNciCoVi<"
    A$ = A$ + "LPWESH\7a[Nfb_CjW=eiKoZi:ReFRVG^fo7JN;6XM=dmOBWdSVfk:n^goGmI"
    A$ = A$ + "=Kib9MB?2jN^jIgF?YCjT>YCjT>YCjT>YCjT>YCjT>YCjT>YCjT>YCjT>Y3;"
    A$ = A$ + "moa[%%L2"
    btemp$ = ""
    FOR i& = 1 TO LEN(A$) STEP 4: B$ = MID$(A$, i&, 4)
        IF INSTR(1, B$, "%") THEN
            FOR C% = 1 TO LEN(B$): F$ = MID$(B$, C%, 1)
                IF F$ <> "%" THEN C$ = C$ + F$
            NEXT: B$ = C$: END IF: FOR j = 1 TO LEN(B$)
            IF MID$(B$, j, 1) = "#" THEN
        MID$(B$, j) = "@": END IF: NEXT
        FOR t% = LEN(B$) TO 1 STEP -1
            B& = B& * 64 + ASC(MID$(B$, t%)) - 48
            NEXT: X$ = "": FOR t% = 1 TO LEN(B$) - 1
            X$ = X$ + CHR$(B& AND 255): B& = B& \ 256
    NEXT: btemp$ = btemp$ + X$: NEXT
    btemp$ = _INFLATE$(btemp$,m.SIZE)
    _MEMPUT m, m.OFFSET, btemp$: _MEMFREE m
    BASIMAGE1& = _COPYIMAGE(v&): _FREEIMAGE v&
END FUNCTION



RE: Screen Savers - bplus - 05-01-2022

Hi @Steffan-68, sorry without the zip and proper loads of those files your posts don't work. How about just a clean pure code effort?

Everyone be careful with copy righted material, be sure to give credit if license requires it.

Honestly didn't expect Screen Savers to come with Image, Sound and Font files, but OK some people can really get into it! Smile

______________________________________________________________________________________________

Hi @Dav

Yeah, I like self contained single file, your gear image contained within. Looks like zooming out or zooming in lead to same? I luv gears.



[Image: image-2022-05-01-162627447.png]


RE: Screen Savers - bplus - 05-02-2022

Don't Attempt to Adjust Your Screen
Code: (Select All)
_Title "Scrolling Plasma Lines Mod 1" 'B+ 2019-10-09
Randomize Timer
xmax = _DesktopWidth - 1
ymax = _DesktopHeight - 1
Screen _NewImage(xmax, ymax, 32)
_FullScreen
Dim ln(0 To ymax) As _Unsigned Long
r = Rnd ^ 2: g = Rnd ^ 2: b = Rnd ^ 2
f = xmax / ymax
While _KeyDown(27) = 0
    If Rnd < .05 Then r = Rnd ^ 2: g = Rnd ^ 2: b = Rnd ^ 2
    For i = UBound(ln) - 1 To 0 Step -1
        ln(i + 1) = ln(i)
        Line (0, i)-Step(xmax, 0), ln(i + 1)
        Line (xmax - i * f, 0)-Step(0, ymax), ln(i + 1)
        Line (i * f, 0)-Step(f, ymax), ln(i + 1)
        Line (0, ymax - i)-Step(xmax, 0), ln(i + 1)
    Next
    ln(0) = _RGB32(127 + 127 * Sin(r * c), 127 + 127 * Sin(g * c), 127 + 127 * Sin(b * c), 40)
    c = c + 1
    _Display
    _Limit 60
Wend



RE: Screen Savers - Coolman - 05-02-2022

nice effect


RE: Screen Savers - bplus - 05-03-2022

Underwater Meditation
   

   

+ for more fish
- for less fish
Hope the swaying kelp doesn't make you seasick, I tried to make it subtle. Smile


RE: Screen Savers - bplus - 05-09-2022

Tanks Battle - The Movie
Code: (Select All)
_Title "Tanks Battle - The Movie" 'from  bplus 2018-02-03"
'from: Tanks Battle.sdlbas (B+=MGA) 2016-10-29
' let the projectiles fly!
' 2022-05-? fix color const for Sky
' 2022-05-09 Make a Movie / Screen Saver
Randomize Timer

'tank stuff
Const tN = 15 'number of tanks
Const tNm1 = tN - 1 ' for loops and arrays
Const tW = 20 'width of tank
Const tH = 8 'height of tank
Type tank
    x As Single
    y As Single
    da As Single
    v As Single 'velocity
    c As _Integer64 'color
    bx As Single 'barrel
    by As Single
    f As _Byte 'finished
End Type

'hole stuff
Const hR = tW + 3
Const topHole = 1000
Type hole
    x As Integer
    y As Integer
End Type

'projectile stuff
Const rightA = -10
Const leftA = -170
Const lVel = 7
Const hVel = 22
Const SkyC = &HFF848888~& ' try this for Rho
Const pC = &HFFFFFF00~&
Const gravity = .35

Dim Shared SW, SH
SW = _DesktopWidth
SH = _DesktopHeight

Screen _NewImage(SW, SH, 32)
_FullScreen

Dim Shared rad ' yeah don't need these with _D2R and _R2D but this was 4 years ago
rad = _Pi / 180

restart:
ReDim Shared tanks(tNm1) As tank, holes(topHole) As hole

'get holes set up
holeIndex = -1

land& = _NewImage(SW, SH, 32)
_Dest land&
drawLandscape
_Dest 0

initializeTanks
hotTank = tNm1

change = 1
While change 'get tanks landed before start shooting
    change = 0
    Cls
    _PutImage , land&, 0 'land the tanks and reland the tanks if the dirt is shot out under them
    For i = 0 To tNm1
        If Point(tanks(i).x + tW / 2, tanks(i).y + tH + 1) = SkyC Then
            tanks(i).y = tanks(i).y + 2
            change = 1
        End If
        drawTank i
    Next
    _Display
Wend

While _KeyDown(27) = 0 '< main loop start
    Cls
    _PutImage , land&, 0

    'the land with holes
    If holeIndex > -1 Then
        For ii = 0 To holeIndex
            drawHole holes(ii).x, holes(ii).y
        Next
    End If

    'reland the tanks if the dirt is shot out under them
    For i = 0 To tNm1
        If tanks(i).f = 0 Then
            While Point(tanks(i).x + tW / 2, tanks(i).y + tH + 1) = SkyC
                tanks(i).y = tanks(i).y + 2
            Wend

            'repoint barrels and reset velocitys
            If Rnd < .5 Then 'avoid straight up and down  suicide shots
                tanks(i).da = rand(leftA, -92)
            Else
                tanks(i).da = rand(rightA, -88)
            End If
            tanks(i).v = rand(lVel, hVel) 'velocity
            drawTank i
        End If
    Next
    _Display
    _Delay .1


    ''whose turn to shoot
    lastMan = hotTank
    hotTank = hotTank + 1
    hotTank = hotTank Mod tN
    While tanks(hotTank).f = 1 'look for a tank still alive
        hotTank = hotTank + 1 'whose turn to shoot
        hotTank = hotTank Mod tN
        'did we cycle through all the dead tanks?
        If hotTank = lastMan Then 'game over, last man standing
            _Display
            _Delay 5
            GoTo restart
        End If
    Wend

    'setup hotTank's shot
    rAngle = tanks(hotTank).da * rad 'convert here to radians for SIN and COS
    pX = tanks(hotTank).bx
    pY = tanks(hotTank).by
    pX_change = tanks(hotTank).v * Cos(rAngle) 'this is the cuurent  X vector of the projectile
    pY_change = tanks(hotTank).v * Sin(rAngle) ' this is the current Y vector of the projectile
    pActive = 0 ' do not Activate until projectile sees the skyC

    While 1
        pY_change = pY_change + gravity ' pY starts in upward direction but will eventually fall due to gravity
        pX = pX + pX_change
        pY = pY + pY_change

        'show projectile progress, hit or air
        If pX >= 0 And pX <= SW And pY <= SH Then ' still active
            'check for tank hit
            For iTank = 0 To tNm1
                If tanks(iTank).f <> 1 And pActive Then 'tanks can blow up themselves
                    If dist(pX, pY, tanks(iTank).x + tW / 2, tanks(iTank).y + tH / 2) < hR Then
                        tanks(iTank).f = 1
                        Color _RGB32(255, 0, 0)
                        For rr = 1 To hR
                            fcirc pX, pY, rr
                            _Display
                            _Delay .01
                            If rr Mod 2 Then
                                Color _RGB32(128, 255, 0)
                            Else
                                Color _RGB32(255, 0, 0)
                            End If
                        Next
                        If holeIndex < topHole Then
                            holeIndex = holeIndex + 1
                            holes(holeIndex).x = pX
                            holes(holeIndex).y = pY
                            drawHole pX, pY
                            _Display
                        End If
                        pX = SW + 10
                        pY = SH + 10
                        Exit While
                    End If
                End If
            Next

            If Point(pX, pY) = SkyC Then
                pActive = 1
                Color pC
                fcirc pX, pY, 2 ' <<<<<<<<<<<<<<<< to see round projectiles that could be replaced by image
            ElseIf pY < 0 Then
                'still hot but cant see
            ElseIf Point(pX, pY) <> SkyC And Point(pX, pY) <> pC And pActive Then 'hit ground?
                Color _RGB(255, 0, 0)
                For rr = 1 To hR
                    fcirc pX, pY, rr
                    _Display
                    _Delay .01
                    If rr Mod 2 Then
                        Color _RGB32(128, 255, 0)
                    Else
                        Color _RGB32(255, 0, 0)
                    End If
                Next
                If holeIndex < topHole Then
                    holeIndex = holeIndex + 1
                    holes(holeIndex).x = pX
                    holes(holeIndex).y = pY
                    drawHole pX, pY
                    _Display
                End If
                pX = SW + 10
                pY = SH + 10
                Exit While
            End If
        Else 'not active
            Exit While
        End If
        _Display
        _Delay .03
    Wend
Wend

Sub drawHole (xx, yy)
    Color SkyC
    For i = yy To 300 Step -1
        fcirc xx, i, hR
    Next
End Sub

Sub drawLandscape
    'the sky
    Line (0, 0)-(SW, SH), SkyC, BF

    'the land
    startH = SH - 100
    rr = 70: gg = 70: bb = 90
    For mountain = 1 To 6
        Xright = 0
        y = startH
        While Xright < SW
            ' upDown = local up / down over range, change along Y
            ' range = how far up / down, along X
            upDown = (Rnd * (.8) - .35) * (mountain * .5)
            range = Xright + rand%(15, 25) * 2.5 / mountain
            For x = Xright - 1 To range
                y = y + upDown
                Line (x, y)-(x + 1, SH), _RGB32(rr, gg, bb), BF
            Next
            Xright = range
        Wend
        rr = rand(rr - 15, rr): gg = rand(gg - 15, gg): bb = rand(bb - 25, bb)
        If rr < 0 Then rr = 0
        If gg < 0 Then gg = 0
        If bb < 0 Then bb = 0
        startH = startH + rand(5, 20)
    Next
End Sub

Sub initializeTanks ' x, y, barrel angle,  velocity, color
    tl = (SW - tW) / tN: tl2 = tl / 2: tl4 = .8 * tl2
    For i = 0 To tNm1
        tanks(i).x = rand%(tl2 + tl * i - tl4 - tW, tl2 + tl * i + tl4 - tW)
        tanks(i).y = 300 '<<<<<<<<<<<<<<<<<<<<<<<<<< for testing
        tanks(i).da = rand%(-180, 0) 'degree Angle
        tanks(i).v = rand%(10, 20) 'velocity
        If tanks(i).da < -90 Then 'barrel  is pointed left
            tanks(i).v = -1 * tanks(i).v
        End If
        tc = i * Int(200 / (3 * tN)) 'maximize color difference between tanks
        tanks(i).c = _RGB32(55 + 2 * tc, 13 + tc, 23 + tc) ' first tank is darkest
    Next
    'shuffle color order
    For i = tNm1 To 1 Step -1
        r = rand%(0, i)
        Swap tanks(i).x, tanks(r).x
    Next
End Sub

Sub drawTank (i)
    'ink(tanks(i, "c"))
    Color tanks(i).c
    'turret
    fEllipse tanks(i).x + tW / 2, tanks(i).y + tH / 3, tW / 4 + 1, tH / 4 + 1
    bX = tW / 2 * Cos(rad * tanks(i).da)
    bY = tW / 2 * Sin(rad * tanks(i).da)
    Line (tanks(i).x + tW / 2, tanks(i).y + tH / 3)-(tanks(i).x + tW / 2 + bX, tanks(i).y + tH / 4 + bY)
    Line (tanks(i).x + tW / 2 + 1, tanks(i).y + tH / 3 + 1)-(tanks(i).x + tW / 2 + bX + 1, tanks(i).y + tH / 4 + bY + 1)
    tanks(i).bx = tanks(i).x + tW / 2 + bX
    tanks(i).by = tanks(i).y + tH / 4 + bY
    fEllipse tanks(i).x + tW / 2, tanks(i).y + .75 * tH, tW / 2, tH / 4
    Color _RGB32(0, 0, 0)
    ellipse tanks(i).x + tW / 2, tanks(i).y + .75 * tH, tW / 2 + 1, tH / 4 + 1
    ellipse tanks(i).x + tW / 2 + 1, tanks(i).y + .75 * tH, tW / 2 + 1, tH / 4 + 1
End Sub

Function rand% (lo%, hi%)
    rand% = (Rnd * (hi% - lo% + 1)) \ 1 + lo%
End Function

Function rdir% ()
    If Rnd < .5 Then rdir% = -1 Else rdir% = 1
End Function

Function dist# (x1%, y1%, x2%, y2%)
    dist# = ((x1% - x2%) ^ 2 + (y1% - y2%) ^ 2) ^ .5
End Function

'Steve McNeil's  copied from his forum   note: Radius is too common a name
Sub fcirc (CX As Long, CY As Long, R As Long)
    Dim subRadius As Long, RadiusError As Long
    Dim X As Long, Y As Long

    subRadius = Abs(R)
    RadiusError = -subRadius
    X = subRadius
    Y = 0

    If subRadius = 0 Then PSet (CX, CY): Exit Sub

    ' Draw the middle span here so we don't draw it twice in the main loop,
    ' which would be a problem with blending turned on.
    Line (CX - X, CY)-(CX + X, CY), , BF

    While X > Y
        RadiusError = RadiusError + Y * 2 + 1
        If RadiusError >= 0 Then
            If X <> Y + 1 Then
                Line (CX - Y, CY - X)-(CX + Y, CY - X), , BF
                Line (CX - Y, CY + X)-(CX + Y, CY + X), , BF
            End If
            X = X - 1
            RadiusError = RadiusError - X * 2
        End If
        Y = Y + 1
        Line (CX - X, CY - Y)-(CX + X, CY - Y), , BF
        Line (CX - X, CY + Y)-(CX + X, CY + Y), , BF
    Wend
End Sub

Sub fEllipse (CX As Long, CY As Long, xRadius As Long, yRadius As Long)
    Dim scale As Single, x As Long, y As Long
    scale = yRadius / xRadius
    Line (CX, CY - yRadius)-(CX, CY + yRadius), , BF
    For x = 1 To xRadius
        y = scale * Sqr(xRadius * xRadius - x * x)
        Line (CX + x, CY - y)-(CX + x, CY + y), , BF
        Line (CX - x, CY - y)-(CX - x, CY + y), , BF
    Next
End Sub

Sub ellipse (CX As Long, CY As Long, xRadius As Long, yRadius As Long)
    Dim scale As Single, xs As Long, x As Long, y As Long
    Dim lastx As Long, lasty As Long
    scale = yRadius / xRadius: xs = xRadius * xRadius
    PSet (CX, CY - yRadius): PSet (CX, CY + yRadius)
    lastx = 0: lasty = yRadius
    For x = 1 To xRadius
        y = scale * Sqr(xs - x * x)
        Line (CX + lastx, CY - lasty)-(CX + x, CY - y)
        Line (CX + lastx, CY + lasty)-(CX + x, CY + y)
        Line (CX - lastx, CY - lasty)-(CX - x, CY - y)
        Line (CX - lastx, CY + lasty)-(CX - x, CY + y)
        lastx = x: lasty = y
    Next
End Sub