Welcome, Guest
You have to register before you can post on our site.

Username/Email:
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 308
» Latest member: Donaldvem
» Forum threads: 1,741
» Forum posts: 17,901

Full Statistics

Latest Threads
The QB64 IDE shell
Forum: Utilities
Last Post: JasonPag
09-16-2024, 05:37 PM
» Replies: 9
» Views: 762
Importance regarding Ches...
Forum: Utilities
Last Post: JasonPag
09-01-2024, 06:34 PM
» Replies: 0
» Views: 31
Chess and Analysis and En...
Forum: Utilities
Last Post: JasonPag
08-28-2024, 02:37 PM
» Replies: 0
» Views: 32
DAY 009:_PutImage
Forum: Keyword of the Day!
Last Post: grymmjack
09-02-2023, 02:57 PM
» Replies: 54
» Views: 2,034
Fall Banner Contest?
Forum: Site Suggestions
Last Post: grymmjack
08-31-2023, 11:50 PM
» Replies: 36
» Views: 1,261
ColorPicker - Function th...
Forum: Dav
Last Post: Dav
08-31-2023, 11:04 PM
» Replies: 3
» Views: 315
Goals(1) = New Tile()
Forum: Works in Progress
Last Post: RhoSigma
08-31-2023, 09:45 PM
» Replies: 3
» Views: 127
micro(A)v11
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:14 PM
» Replies: 90
» Views: 3,589
Updating The Single Most ...
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 09:13 PM
» Replies: 7
» Views: 254
QBJS Image Question
Forum: QBJS, BAM, and Other BASICs
Last Post: bplus
08-31-2023, 05:49 PM
» Replies: 5
» Views: 155

 
  Star Trek X The Search for The BOB's White Cake
Posted by: Pete - 12-05-2022, 01:29 AM - Forum: Programs - Replies (16)

With all the Trekkie stuff of late, I'd thought I'd repost this spoof. For those of you who didn't know TheBOB, he was a frequent contributor to the QBasic Forum and a professional graphic artist and programmer in the 1980's. He got the nick, Batman. When we needed graphics help, back in the day, we'd post the bat signal... ^^0^^ and Bob would come to the rescue.

Well one day he posted his white cake recipe program, and something went terribly wrong...

Code: (Select All)
DEFINT A-Y
TYPE RockTYPE 'establish data TYPE for meteors
    Mx AS INTEGER 'meteor x coordinate
    My AS INTEGER 'meteor y coordinate
    Mr AS INTEGER 'meteor radius (fixed)
    Ms AS INTEGER 'meteor speed (fixed)
END TYPE

SCREEN 12, 0, 0, 0
_FULLSCREEN

FOR n = 1 TO 9
    READ Attribute: OUT &H3C8, Attribute
    FOR Reps = 1 TO 3
        READ Intensity: OUT &H3C9, Intensity
    NEXT Reps
NEXT n

PRINT
PRINT
COLOR 15
PRINT SPACE$(4); "W H I T E"; SPACE$(3); "C A K E"; SPACE$(3); "R E C I P E"
LINE (16, 60)-(620, 60), 9
LINE (16, 62)-(620, 62), 9
LINE (418, 60)-(542, 62), 0, BF
PRINT
PRINT
COLOR 12
PRINT SPACE$(4); "Heat oven to 350 degrees"
PRINT SPACE$(4); "Grease and flour 2 circular pans (8-9 inches)"
PRINT
COLOR 15
PRINT SPACE$(4); "CAKE:";
COLOR 11
PRINT SPACE$(9); "Flour: 2-1/4 cups"
PRINT SPACE$(18); "Sugar: 1-2/3 cups"
PRINT SPACE$(13); "Shortening: 2/3 cup"
PRINT SPACE$(19); "Milk: 1-1/4 cups"
PRINT SPACE$(10); "Baking powder: 3-1/2 tsps"
PRINT SPACE$(19); "Salt: 1 tsp"
PRINT SPACE$(16); "Vanilla: 1 tsp"
PRINT SPACE$(13); "Egg whites: 5 (reserve yolks for icing)"
PRINT
COLOR 12
PRINT SPACE$(4);
PRINT "Combine all ingredients except the egg whites in a bowl. Beat for 1/2"
PRINT SPACE$(4);
PRINT "minute at low speed, scraping bowl constantly, then 2 minutes at high"
PRINT SPACE$(4);
PRINT "speed, scraping bowl occasionally. Beat in egg whites, 2 minutes at"
PRINT SPACE$(4);
PRINT "high speed. Pour into pans. Bake until a toothpick inserted comes out"
PRINT SPACE$(4);
PRINT "clean or cake springs back when touched lightly (30 - 35 minutes)."
PRINT
COLOR 15
PRINT SPACE$(4); "ICING:";
COLOR 11
PRINT SPACE$(3); "Shortening: 2/3 cup"
PRINT SPACE$(17); "Butter: 2/3 cup"
PRINT SPACE$(14); "Egg yolks: 5"
PRINT SPACE$(16); "Vanilla: 1-1/2 tsps"
PRINT SPACE$(12); "Icing sugar: 3/4 cup or to taste"

CIRCLE (480, 86), 74, 1, , , .4
PAINT STEP(0, 0), 1
CIRCLE (480, 80), 72, 15, , , .4
PAINT STEP(0, 0), 15
CIRCLE (480, 79), 67, 9, , , .4
PAINT STEP(0, 0), 9
CIRCLE (480, 80), 72, 14, , , .4
CIRCLE (480, 78), 48, 15, , , .4
CIRCLE (480, 40), 60, 7, -4.5, -3.5, .4
PSET (423, 46), 7: DRAW "F2"
PAINT STEP(0, -10), 7
CIRCLE (480, 80), 60, 7, -4.5, -3.5, .4
PSET (423, 86), 7: DRAW "F2"
PAINT STEP(0, -10), 7
LINE (540, 40)-STEP(0, 40), 7
LINE (420, 40)-STEP(0, 40), 7
PAINT (430, 60), 7
PAINT (530, 60), 7
LINE (420, 40)-STEP(0, 40), 7
LINE STEP(4, -33)-STEP(0, 40), 7
LINE STEP(43, -24)-STEP(0, 40), 7
PAINT STEP(8, -18), 7
CIRCLE (480, 40), 60, 15, -4.5, -3.5, .4
LINE (540, 40)-STEP(0, 40), 15
LINE (420, 40)-STEP(0, 40), 15
LINE (420, 40)-STEP(0, 40), 15
LINE STEP(4, -33)-STEP(0, 40), 15
LINE STEP(43, -24)-STEP(0, 40), 15
PSET (430, 52), 4
DRAW "M+47,-7 M-9,+14 M-38,+6 U12 BR12 P4,4 BL13 D12 LU13Ld13"
PSET (427, 70), 4
DRAW "M+40,-7 D19 M-40,+7 U19 BF8 P4,4"
DIM Box(1000)
GET (427, 53)-(467, 78), Box()
PUT (427, 55), Box(), PSET
PSET (481, 40), 15
DRAW "M-13,+21"
PAINT (470, 30), 13, 15
FOR Reps = 1 TO 1200
    X = FIX(RND * 60) + 420
    y = FIX(RND * 54) + 40
    IF POINT(X, y) = 4 THEN PSET (X, y), 15
NEXT Reps
PSET (427, 70), 2
DRAW "bM+40,-7 bD19 M-40,+7"
PSET (427, 70), 2
DRAW "bM+40,-7 bD20 M-30,+5"
CIRCLE (480, 80), 60, 2, 4.5, 6, .4
LINE (4, 4)-(635, 475), 9, B
FOR X = 524 TO 525
    FOR y = 30 TO 100
        IF POINT(X, y) = 7 THEN PSET (X, y), 13
    NEXT y
NEXT X
FOR X = 528 TO 540
    FOR y = 30 TO 100
        IF POINT(X, y) = 7 THEN PSET (X, y), 13
    NEXT y
NEXT X

CALL BSU
CALL SPACE
SYSTEM

PaletteDATA:
DATA 0,0,0,36,1,0,0,24,2,48,36,44,4,54,54,63,7,63,48,48,8
DATA 54,54,54,9,60,48,63,12,42,42,42,13,63,52,52,14,63,42,24

DEFSNG Z
SUB BSU

    LOCATE 27, 60: PRINT CHR$(24);
    LOCATE 28, 60: PRINT CHR$(219);: FIREPIN = 1
    _DELAY 1

    DO
        b$ = INKEY$
        _LIMIT 30
        LOCATE 28, 62
        PRINT "Press arrow up.";
        LOCATE 28, 62
        IF b$ = CHR$(0) + "H" THEN EXIT DO
        _DELAY .45
        PRINT "              ";
        IF b$ = CHR$(0) + "H" THEN EXIT DO
        _DELAY .45
        IF b$ = CHR$(27) THEN SYSTEM
    LOOP UNTIL b$ = CHR$(0) + "H"
    b$ = CHR$(13)
    LOCATE 28, 60: PRINT "                ";

    FIREMISSILE:
    FOR I = 1 TO 25
        LOCATE 28 - I, 60: PRINT " ";
        LOCATE CSRLIN - 1, 60: PRINT CHR$(24);
        Z = TIMER
        DO
        LOOP UNTIL ABS(Z - TIMER) >= .02: 'DELAY LOOP
    NEXT
    FOR I = 1 TO 5
        SOUND 2000, 2: SOUND 500, 2

        WAIT &H3DA, 8
        WAIT &H3DA, 8, 8

        OUT &H3C8, 12
        IF I >= 3 THEN
            IF I / 2 <> I \ 2 THEN OUT &H3C8, 33 ELSE OUT &H3C8, 0
        ELSE
            OUT &H3C8, 0
            OUT &H3C9, 63 'set background (briefly) to bright red
            OUT &H3C9, 0
            OUT &H3C9, 0
        END IF
    NEXT I
    Z = TIMER
    DO
    LOOP UNTIL ABS(Z - TIMER) >= 1.5: 'DELAY LOOP

END SUB

SUB SPACE
    SCREEN 9

    'Set all attributes to black to hide draw/GET process
    FOR n = 1 TO 15
        PALETTE n, 0
    NEXT n

    'Ships differ in that the ship 2 rocket blasts are slightly larger
    'Draw and GET ship 1 and mask
    X = 0: Y = 0
    MaxWIDTH = 83
    MaxDEPTH = 60

    DIM Rocks(1 TO 100) AS RockTYPE 'holds the location, size
    'and speed of 100 meteors

    IF X < 326 THEN
        FOR n = 1 TO 100 'loop to initialize meteor array

            Rocks(n).Mx = FIX(RND * 640) 'initial x coordinates
            Rocks(n).My = FIX(RND * 350) 'initial y coordinates
            Rocks(n).Mr = FIX(RND * 5) + 2 'permanent radius (2-6 pixels)

            SELECT CASE n 'speed variations create perspective
                CASE 1 TO 30: Rocks(n).Ms = 12 'background meteors
                CASE 31 TO 65: Rocks(n).Ms = 18 'midground meteors
                CASE 66 TO 100: Rocks(n).Ms = 24 'foreground meteors
            END SELECT

        NEXT n
        Rocks(50).Mr = 10 'meteor 50 specially sized (large)
        Rocks(100).Mr = 16 'meteor 100 specially sized (larger)
    ELSE
        Z = TIMER: DO: IF ABS(Z - TIMER) > .1 THEN EXIT DO
        LOOP
    END IF

    ActivePAGE = 0: VisualPAGE = 1 'establish page variables for SWAP

    SCREEN 9, , ActivePAGE, VisualPAGE 'page 0 active, page 1 visual

    PALETTE
    PALETTE 10, 0 'set palette values for attributes
    PALETTE 12, 35 'which do not respond to OUT

    'set palette values for attributes
    'that respond to OUT
    OUT &H3C8, 0
    OUT &H3C9, 0
    OUT &H3C9, 0 'background: midnight blue
    OUT &H3C9, 12

    OUT &H3C8, 1
    OUT &H3C9, 16
    OUT &H3C9, 8 'meteor: dark brown
    OUT &H3C9, 2

    OUT &H3C8, 2
    OUT &H3C9, 32
    OUT &H3C9, 32 'medium ship gray
    OUT &H3C9, 32

    OUT &H3C8, 3
    OUT &H3C9, 22
    OUT &H3C9, 12 'meteor highlight brown
    OUT &H3C9, 5

    OUT &H3C8, 4
    OUT &H3C9, 63
    OUT &H3C9, 0 'bright red
    OUT &H3C9, 0

    OUT &H3C8, 5
    OUT &H3C9, 52
    OUT &H3C9, 52 'ship light gray
    OUT &H3C9, 52

    'MAIN LOOP BEGINS -------------------------------

    Count = 0

    FOR X = 6 TO 546 STEP 2 'main loop wherein ship will
        _DELAY .115 ' Reading speed
        'travel 540 pixels in steps
        'of two

        CLS 'active screen cleared

        OUT &H3C8, 0 'background color reestablished
        OUT &H3C9, 0 'in case "space lightning" has
        OUT &H3C9, 0 'flashed
        OUT &H3C9, 12

        'The following loop draws/updates x/y's of first 80 meteors
        IF X < 326 THEN
            FOR n = 1 TO 80
                GOSUB DrawMETEORS 'see DrawMETEORS subroutine
            NEXT n

            'Second meteor-drawing loop draws last 20 meteors so that they *may*
            'overdraw the ship (creating sense of its 'involvement' in meteor storm)
            FOR n = 81 TO 100
                GOSUB DrawMETEORS 'see DrawMETEORS subroutine
            NEXT n
        ELSE
            ''Z = TIMER: DO: IF ABS(Z - TIMER) > .1 THEN EXIT DO
            ''LOOP
        END IF

        Z = TIMER: DO: IF ABS(Z - TIMER) > .05 THEN EXIT DO
        LOOP

        'PRINT section -------------------------------------
        'Blurbs are printed (with gaps) based on the ship's x location
        COLOR 13: A1 = 30
        SELECT CASE X
            CASE 10 + A1 TO 100 + A1
                LOCATE 21, 19: PRINT "Kirk to Spock. What are those strange looking"
                LOCATE 22, 31: PRINT "blobs on the screen?"
            CASE 101 + A1 TO 170 + A1
                LOCATE 21, 21: PRINT "Sensors indicate they are the remains of"
                LOCATE 22, 23: PRINT "TheBob's White Cake Recipe, Captain."
            CASE 171 + A1 TO 240 + A1
                LOCATE 21, 16: PRINT "Kirk to Scottie. Beam those pieces of cake onboard!"
            CASE 241 + A1 TO 317 + A1
                LOCATE 21, 19: PRINT "Aye Captain, I'll get right on it, as soon as"
                LOCATE 22, 28: PRINT "I finish my Dunkin Donuts."
            CASE 336 + A1 TO 435 + A1
                LOCATE 21, 15: PRINT "Kirk to Sick Bay. Bones, MEDICAL EMERGENCY! Report to"
                LOCATE 22, 13: PRINT "the Transporter Room and put TheBob's cake back together!"
            CASE IS > 440 + A1
                LOCATE 21, 19: PRINT "Dammit Jim. I'm a doctor, not Martha Stewart!"
                LOCATE 21, 19: PRINT "Dammit Jim. I'm a doctor, not a confectioner!"
        END SELECT
        '-----------------------------------------------------

        'Border line
        LINE (0, 0)-(639, 349), 8, B

        '"Space lightning" flash (1 chance in 25)
        'Flash = FIX(RND * 25)
        IF X = 326 THEN
            SOUND 1000, .5: SOUND 2000, .5: SOUND 3000, .5: SOUND 4000, .5: SOUND 5000, .5: SOUND 6000, .5
            SOUND 6000, .5: SOUND 7000, .5: SOUND 8000, .5: SOUND 4000, .5: SOUND 9000, .5
            OUT &H3C8, 0
            OUT &H3C9, 63 'set background (briefly) to bright red
            OUT &H3C9, 0
            OUT &H3C9, 0
        END IF

        'PAGING SECTION --------------------------------
        SWAP ActivePAGE, VisualPAGE 'SWAP values of page variables...
        SCREEN 9, , ActivePAGE, VisualPAGE 'which toggles active/visual page
        '-----------------------------------------------

        WAIT &H3DA, 8
        WAIT &H3DA, 8, 8

    NEXT X 'main loop ends

    SCREEN 9, 0, 0, 0
    LOCATE 21, 5: PRINT SPACE$(70);
    LOCATE 22, 5: PRINT SPACE$(70);
    _DELAY 1
    LEVEL1 = 10
    A1$ = " [Sometimes The Joker Wins!]"
    REDIM BAT$(3)
    BAT$(3) = "^^o^^"
    BAT$(2) = "--o--"
    BAT$(1) = "vvovv"
    LOCATE LEVEL1, 2
    _DELAY 1
    FOR I = 1 TO 12
        FOR J = 1 TO 3
            IF I = 1 AND J = 1 THEN LOCATE , 3 ELSE PRINT " ";
            PRINT BAT$(J);
            LOCATE , POS(1) - 5
            Z = TIMER
            DO: IF ABS(Z - TIMER) > .1 THEN EXIT DO
            LOOP
        NEXT J
    NEXT I
    _DELAY 1
    FOR I = 2 TO LEVEL1
        IF I = LEVEL1 - 1 THEN SOUND 3000, .7: SOUND 358, 1.5: SOUND 5000, 1
        IF I <> 2 THEN LOCATE I - 1, 27: PRINT SPACE$(28);
        LOCATE I, 27: PRINT A1$;
        Z = TIMER
        DO: IF ABS(Z - TIMER) > .1 THEN EXIT DO
        LOOP
    NEXT

    _DELAY 4
    SYSTEM

    '- SUBROUTINE SECTION BEGINS -------------------------

    DrawMETEORS:

    'If the meteor's x coordinate has moved off-screen to the left, it is as-
    'signed a new random y coordinate, then reset to the right of the screen
    IF Rocks(n).Mx < 0 THEN
        Rocks(n).My = FIX(RND * 350)
        Rocks(n).Mx = 642
    END IF

    'Meteors are drawn with lighter highlight circle offset +1/-1 pixel
    CIRCLE (Rocks(n).Mx, Rocks(n).My), Rocks(n).Mr, 1
    PAINT STEP(0, 0), 1
    CIRCLE (Rocks(n).Mx + 1, Rocks(n).My - 1), Rocks(n).Mr - 2, 3
    PAINT STEP(0, 0), 3

    'Establish new location for each meteor by subtracting their
    'individual speed (Ms) from their current x coordinate (Mx) ...
    Rocks(n).Mx = Rocks(n).Mx - Rocks(n).Ms

    RETURN

    Mask:
    FOR xx = 0 TO 83
        FOR yy = 0 TO 60
            IF POINT(xx, yy) = 0 THEN PSET (xx, yy), 15 ELSE PSET (xx, yy), 0
        NEXT yy
    NEXT xx
    RETURN

END SUB

Pete

Print this item

  Trekn-mixer 0.2
Posted by: James D Jarvis - 12-05-2022, 01:03 AM - Forum: Programs - Replies (15)

Trekn-mixer generates a sprite sheet of trekish spacecraft.  It's a version 0.1 for now. Still need to tweak the color schemes and likely to add some more ship parts.


[Image: image.png]

Code: (Select All)
'Trekn-Mixer v0.1
'By James D. Jarvis December 2022
'This program uses BASIMAGE coded by Dav for QB64GL 1.4, MAY/2020
'
'generate a sprite sheet of spacecraft for trek games
'each is 64 by 96 pixels but code here can be modified to change that
'
'press c or s to save a sprite sheet to the clipboard so you can paste it into a paint program
'and save is whatever format you desire
'pres <esc> to quit
'
'License: Share sprite sheets as long as they include generated credit bar in image
'any programs using original code or graphics from source or generated by program
' please include the following (or equivalent) line somwhere in comments and documentation:
'Includes Art and/or Code from Trekn-Mixer v0.1 created by James D. Jarvis
'
Randomize Timer
Dim Shared ms&
ms& = _NewImage(512, 416, 32)
Screen ms&
_Title "Mini-Trekn-Mixer V0.1"
Dim Shared part&
Dim Shared kk1 As _Unsigned Long
Dim Shared kk2 As _Unsigned Long
Dim Shared kk3 As _Unsigned Long
Dim Shared kk4 As _Unsigned Long
Dim Shared kk5 As _Unsigned Long
Dim Shared kk6 As _Unsigned Long

Dim Shared clr~&
part& = BASIMAGE1&

Type craft_type
    hull As Integer
    saucer As Integer
    drive As Integer
    cannon As Integer
    turret As Integer
    extension As Integer
    kscheme As _Unsigned Long
End Type
Type colorscheme_type
    k1 As _Unsigned Long
    k2 As _Unsigned Long
    k3 As _Unsigned Long
    k4 As _Unsigned Long
    k5 As _Unsigned Long
    k6 As _Unsigned Long
End Type
Dim Shared klrs(10) As colorscheme_type
buildklrs
Dim Shared craft_limit
craft_limit = 32
Dim Shared clook(craft_limit) As craft_type
_Source part&
'read the colors from the color reference bar whichever color is in the top left corner will be transparent
clr~& = Point(0, 0) 'find background color of image
kk1 = Point(0, 1): kk2 = Point(0, 2): kk3 = Point(0, 3): kk4 = Point(0, 4): kk5 = Point(0, 4): kk5 = Point(0, 4)
_Dest part&
Line (0, 0)-(0, 8), clr~& 'erase the color reference bar from the bit map
_ClearColor clr~&, ms& 'set background color as transparent
_ClearColor clr~&, part&
_Source ms&
_Dest ms&
Do
    Cls
    mmx = 0: mmy = 0
    For m = 1 To craft_limit
        'create a new set of weapon sprites
        clook(m).hull = Int(1 + Rnd * 15)
        '1- small saucer and drive
        '2- small saucer, drive and cannon
        '3- large saucer and drive
        '4- large saucer,drive and cannon
        '5- large saucer,drive,cannon  and turret
        '6- large saucer,drive and turret
        '7- large saucer and turret
        '8- small saucer,extension, and drive
        '9- small saucer,extnsion, drive and cannon
        '10- large saucer,extension,and drive
        '11- large saucer,extension,drive and cannon
        '12- large saucer,extension,drive,cannon  and turret
        '13- large saucer,extension,drive and turret
        '14 - mid suacer,extenstion and drive
        '15 - mid saucer, extension, cannon and drive
        Select Case clook(m).hull
            Case 1
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(1 + Rnd * 8)
                clook(m).cannon = 0
                clook(m).turret = 0
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 2
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(1 + Rnd * 8)
                clook(m).cannon = Int(1 + Rnd * 8)
                clook(m).turret = 0
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 3
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = 0
                clook(m).turret = 0
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 4
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = Int(1 + Rnd * 10)
                clook(m).turret = 0
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 5
                clook(m).saucer = Int(11 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = Int(1 + Rnd * 10)
                clook(m).turret = Int(1 + Rnd * 20)
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 6
                clook(m).saucer = Int(11 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = 0
                clook(m).turret = Int(1 + Rnd * 20)
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 7
                clook(m).saucer = Int(11 + Rnd * 10)
                clook(m).drive = 0
                clook(m).cannon = 0
                clook(m).turret = Int(1 + Rnd * 20)
                clook(m).extension = 0
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 8
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 12)
                clook(m).cannon = 0
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 6)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 9
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 12)
                clook(m).cannon = Int(1 + Rnd * 8)
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 6)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 10
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = 0
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 11
                clook(m).saucer = Int(1 + Rnd * 20)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = Int(1 + Rnd * 10)
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 12
                clook(m).saucer = Int(11 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = Int(1 + Rnd * 10)
                clook(m).turret = Int(1 + Rnd * 20)
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 13
                clook(m).saucer = Int(11 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 18)
                clook(m).cannon = 0
                clook(m).turret = Int(1 + Rnd * 20)
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 14
                clook(m).saucer = Int(1 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 15)
                clook(m).cannon = 0
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
            Case 15
                clook(m).saucer = Int(1 + Rnd * 10)
                clook(m).drive = Int(3 + Rnd * 15)
                clook(m).cannon = Int(1 + Rnd * 10)
                clook(m).turret = 0
                clook(m).extension = Int(1 + Rnd * 5)
                clook(m).kscheme = Int(1 + Rnd * 10)
        End Select


        draw_craft mmx, mmy, m, 1
        mmx = mmx + 64
        If mmx >= _Width Then
            mmx = 0
            mmy = mmy + 96
        End If
    Next m
    md$ = "Spacecraft Sprite Sheet generated " + Date$ + " at " + Time$
    md2$ = "Mini-Trekn-Mixer V0.1 by James D. Jarvis"
    _PrintString (0, 385), md$
    _PrintString (0, 401), md2$
    Do
        _Limit 60
        kk$ = InKey$
    Loop Until kk$ <> ""
    If kk$ = "C" Or kk$ = "c" Or kk$ = "S" Or kk$ = "s" Then
        _ClipboardImage = ms&
        _Delay 0.3
        Locate 1, 1: Print "Sprite Sheet Saved to Clipboard"
        Sleep 3
    End If
Loop Until kk$ = Chr$(27)
_FreeImage part&
System
Sub buildklrs
    'lt grey
    tk = Int(200 + Rnd * 50)
    klrs(1).k1 = _RGB32(tk, tk, tk)
    tk = Int(tk * .8)
    klrs(1).k2 = _RGB32(tk, tk, tk)
    tk = Int(tk * .8)
    klrs(1).k3 = _RGB32(tk, tk, tk)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(1).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .7): tg = Int(tg * .7): tb = Int(tb * .7)
    klrs(1).k5 = _RGB32(tr, tg, tb)
    klrs(1).k6 = _RGB32(Int(20 + Rnd * 200), Int(20 + Rnd * 200), Int(20 + Rnd * 200))

    'dk grey
    tk = Int(100 + Rnd * 50)
    klrs(2).k1 = _RGB32(tk, tk, tk)
    tk = Int(tk * .6)
    klrs(2).k2 = _RGB32(tk, tk, tk)
    tk = Int(tk * .6)
    klrs(2).k3 = _RGB32(tk, tk, tk)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(2).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(2).k5 = _RGB32(tr, tg, tb)
    klrs(2).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))

    'red
    tr = Int(100 + Rnd * 155): tg = Int(tr / Int(5 + Rnd * 10)): tb = tg
    klrs(3).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(3).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(3).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(3).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(3).k5 = _RGB32(tr, tg, tb)
    klrs(3).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))

    'green
    tg = Int(100 + Rnd * 155): tr = Int(tg / Int(5 + Rnd * 10)): tb = tg
    klrs(4).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(4).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(4).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(4).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(4).k5 = _RGB32(tr, tg, tb)
    klrs(4).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))

    'blue
    tb = Int(100 + Rnd * 155): tr = Int(tb / Int(5 + Rnd * 10)): tg = tr
    klrs(5).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(5).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(5).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(5).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(5).k5 = _RGB32(tr, tg, tb)
    klrs(5).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))

    'purple
    tb = Int(100 + Rnd * 155): tr = tb: tg = Int(tb / Int(5 + Rnd * 10))
    klrs(6).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(6).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(6).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(6).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(6).k5 = _RGB32(tr, tg, tb)
    klrs(6).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))
    'yellow
    tg = Int(100 + Rnd * 155): tr = tg: tb = Int(tg / Int(5 + Rnd * 10))
    klrs(7).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(7).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(7).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(7).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(7).k5 = _RGB32(tr, tg, tb)
    klrs(7).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))
    'orange
    tr = Int(100 + Rnd * 155): tg = Int(tr * .5): tb = Int(tg / Int(5 + Rnd * 10))
    klrs(8).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(8).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(8).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(8).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(8).k5 = _RGB32(tr, tg, tb)
    klrs(8).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))
    'brown
    tr = Int(155 + Rnd * 100): tg = Int(tr * .6): tb = Int(tg * .6)
    klrs(9).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(9).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(9).k3 = _RGB32(tr, tg, tb)
    tr = Int(150 + Rnd * 80): tg = tg + Int(Rnd * 20) - Int(Rnd * 24): tb = tb + Int(Rnd * 20) - Int(Rnd * 24)
    klrs(9).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(9).k5 = _RGB32(tr, tg, tb)
    klrs(9).k6 = _RGB32(Int(150 + Rnd * 100), Int(150 + Rnd * 100), Int(150 + Rnd * 100))
    'random
    tr = Int(10 + Rnd * 240): tg = Int(10 + Rnd * 240): tb = Int(10 + Rnd * 240)
    klrs(10).k1 = _RGB32(tr, tb, tg)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(10).k2 = _RGB32(tr, tg, tb)
    tr = Int(tr * .8): tg = Int(tg * .8): tb = Int(tb * .8)
    klrs(10).k3 = _RGB32(tr, tg, tb)
    tr = Int(10 + Rnd * 240): tg = Int(10 + Rnd * 240): tb = Int(10 + Rnd * 240)
    klrs(10).k4 = _RGB32(tr, tg, tb)
    tr = Int(tr * .5): tg = Int(tg * .5): tb = Int(tb * .5)
    klrs(10).k5 = _RGB32(tr, tg, tb)
    klrs(10).k6 = _RGB32(Int(10 + Rnd * 240), Int(10 + Rnd * 240), Int(10 + Rnd * 240))
End Sub

Sub draw_craft (Mx, my, mid, scale)
    'generate a monster image from source sprite sheet part& and render to the programs main screen ms&
    tempi& = _NewImage(64, 96, 32)
    'tempi& creates a temporary one sprite image for rendering
    _ClearColor clr~&, tempi&
    _Dest tempi&
    Cls
    'Locate 1, 1: Print clook(mid).style
    Select Case clook(mid).hull
        Case 1, 2
            _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).drive - 1) * 64, 128)-((clook(mid).drive - 1) * 64 + 63, 128 + 63)
            If clook(mid).cannon > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).cannon - 1) * 64, 192)-((clook(mid).cannon - 1) * 64 + 63, 192 + 63)
            _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).saucer - 1) * 64, 0)-((clook(mid).saucer - 1) * 64 + 63, 63)
        Case 3 To 7
            If clook(mid).drive > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).drive - 1) * 64, 128)-((clook(mid).drive - 1) * 64 + 63, 128 + 63)
            If clook(mid).cannon > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).cannon - 1) * 64, 192)-((clook(mid).cannon - 1) * 64 + 63, 192 + 63)
            _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).saucer - 1) * 64, 64)-((clook(mid).saucer - 1) * 64 + 63, 64 + 63)
            If clook(mid).turret > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).turret - 1) * 64, 256)-((clook(mid).turret - 1) * 64 + 63, 256 + 63)
        Case 8, 9
            lm = Int(Rnd * 5)
            _PutImage (0, 0 + 18 - lm)-(63, 63 + 18 - lm), part&, tempi&, ((clook(mid).drive - 1) * 64, 128)-((clook(mid).drive - 1) * 64 + 63, 128 + 63)
            _PutImage (0, 0 + 12 - lm)-(63, 63 + 12 - lm), part&, tempi&, ((clook(mid).extension + 10) * 64, 192)-((clook(mid).extension + 10) * 64 + 63, 192 + 63)
            If clook(mid).cannon > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).cannon - 1) * 64, 192)-((clook(mid).cannon - 1) * 64 + 63, 192 + 63)
            _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).saucer - 1) * 64, 0)-((clook(mid).saucer - 1) * 64 + 63, 63)

        Case 10 To 15
            lm = Int(Rnd * 10)
            If clook(mid).drive > 0 Then _PutImage (0, 0 + 32 - lm)-(63, 63 + 32 - lm), part&, tempi&, ((clook(mid).drive - 1) * 64, 128)-((clook(mid).drive - 1) * 64 + 63, 128 + 63)
            If clook(mid).cannon > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).cannon - 1) * 64, 192)-((clook(mid).cannon - 1) * 64 + 63, 192 + 63)
            _PutImage (0, 0 + 28 - lm)-(63, 63 + 28 - lm), part&, tempi&, ((clook(mid).extension + 14) * 64, 192)-((clook(mid).extension + 14) * 64 + 63, 192 + 63)
            _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).saucer - 1) * 64, 64)-((clook(mid).saucer - 1) * 64 + 63, 64 + 63)
            If clook(mid).turret > 0 Then _PutImage (0, 0)-(63, 63), part&, tempi&, ((clook(mid).turret - 1) * 64, 256)-((clook(mid).turret - 1) * 64 + 63, 256 + 63)

    End Select


    _Source tempi&
    'repaint source image with generate color values for new monster sprite

    For y = 0 To 95
        For x = 0 To 63
            Select Case Point(x, y)
                Case kk1
                    PSet (x, y), klrs(clook(mid).kscheme).k1
                Case kk2
                    PSet (x, y), klrs(clook(mid).kscheme).k2
                Case kk3
                    PSet (x, y), klrs(clook(mid).kscheme).k3
                Case kk4
                    PSet (x, y), klrs(clook(mid).kscheme).k4
                Case kk5
                    PSet (x, y), klrs(clook(mid).kscheme).k5
                Case kk6
                    PSet (x, y), klrs(clook(mid).kscheme).k6

            End Select
        Next x
    Next y

    'generated image in tempi& is rendered to ms& as a 32 by 64 sprite

    _PutImage (Mx, my)-(Mx + 63, my + 95), tempi&, ms&
    _Source ms&
    _Dest ms&
    _FreeImage tempi&
End Sub



'================================
'PNG file saved using BASIMAGE1&
'================================
Function BASIMAGE1& 'trekkin_ship_parts.png
    v& = _NewImage(1280, 320, 32)
    Dim m As _MEM: m = _MemImage(v&)
    A$ = ""
    A$ = A$ + "haIkM_PNMR[U60m>9mT<CBg][Z86SU09#_#JMnjEGghL<\o5L0YM`9o_ogok"
    A$ = A$ + "co7000000CY_NekJ000000Pjh?oi?M_6000000X>nhS?jN=000000#MlQOnO"
    A$ = A$ + "100000VFOlQno100000<[nDoo00000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "000000000PUg7Ola?dkjAn100000N^]nMmWolWOHEj3fZWO00000HN]__GWm"
    A$ = A$ + "o^geYl3#m\j?ocb_l_bi70FC[nmoTOiOebOXWk]#?7Lm^>UOJai2[fWoUOf>"
    A$ = A$ + "NOle\ON`acgSUoIML#nGkl30[YEonOboJWoSS3[h?oW[No_Fmlcjfo3iW#7g"
    A$ = A$ + "3MN#_[cJ8gGm^NUOi70h^R=Oo[N=3[7h\nMUJnOcS1[Nn3=N\bmoAnGkl_jF"
    A$ = A$ + "inO8o[]LV3`\M>`n\oeehSmJo_g<=6\Uo]kaMFngnmUoi9o0odZll^8o[Kn?"
    A$ = A$ + ">W_L^ogKON#gYWGaNm673Fml7JlhZNo<cm0BnGkl7K<IEbjFN?NM]#O]NGWe"
    A$ = A$ + ":kQ^gNXi8<[S1Q6CFQ\^_o7YLlOfnL#\i2MfOfXcBn?KNPGmW=l<<6\jioZa"
    A$ = A$ + "VI?Sb_l7:gkoInJUVcSl_6i?eo\nWaW9PDkmE>?KL_YaPE?oQ6?ReWWcnmjM"
    A$ = A$ + "M;obO;6CVm\^?ck_Nfnl?3GWkZLOliK:DnWano4K<IE>oOe?n7J>>abo\MMP"
    A$ = A$ + "cjmK\l?CW3\jio\aUEijOb_l7:g[fLnUoe9o7WCG^gokhL5kMN^KfSmjZio5"
    A$ = A$ + "jmgkL9ogOl8dWe3=F<[G;#nGglWjhA_[[FTkc>Nof_>gEiNojJSUoEK]_[`i"
    A$ = A$ + "o[naoSc_iZk7<;i?fljB9oc`h`ZWomS3Kfnea^ngagk<#nUocncjohhPl;o_"
    A$ = A$ + "il7j??gkLo_gH?0c]gGcF?`Fml7Jl8U\>[[9DnGklOfhaWO=<laWCMNUoh?g"
    A$ = A$ + "SQboKnJmIOlooNihoLOlOEcoEgWk\l?3S3[Nng63R]FgSGoK6WoSl;ob_l_B"
    A$ = A$ + "io\noUcmofomnF6;^Z?FiNooSO_m>ObOnS7AkmcoUo#S=_i?o;obO:S7[Bo_"
    A$ = A$ + "Fml_ZmohZSo7oc4NVcl:OlOEcoZgo;iolWgUDNVHTOi_gi#nUOi?_L_mjO^?"
    A$ = A$ + "g=_ogn_ggbh`Zgo[E?oQ6?>nii_3dWCOoOToe>oY<V<cIEnoi?gcGUoS_gIb"
    A$ = A$ + "EceKF??He?nOLN=aboKO^>GUkLbo<<>8oYo_iIche3UOiGnUoE;oWeo_L^og"
    A$ = A$ + "n_ggbh`EI?gkoof63^Z7NiVoSOOm>OgIl8U\>[m4#nGklWbhb<WCi?lo>oMF"
    A$ = A$ + "n3mnOk2eKo#o_Wac7FmSoKiiXmi?TNGge<kYToIH<8UN0>SmnK;kWM=^Domj"
    A$ = A$ + "M>TOiGnUOi?_\OE_LB]g?_]aP]l\_gMkoOOEn3mmmV63b]7PcJ_of?NLlcfk"
    A$ = A$ + "cln_fKocmb_lWchb:TCiGn3=7_#m2IEn\oZMlGnGclOlnlYHfVcK\ehNfeoN"
    A$ = A$ + "kG?DnUOiGnGil7[?>YL__gL_O>[oOYToEXoOk7;BmmfkLmTaSHmfo\O_NGgb"
    A$ = A$ + "_l3lL1WogWogO50<1cg38\]ihVbW[cim>bBJm_WLm_gne3UOiGn_ZoGOnOTo"
    A$ = A$ + "I;oKS1id7WLOoS\SI9Unh5ZoO_eaPDk[G:_NSi?dhAX?K7jcmc#NUoOj\[_7"
    A$ = A$ + "j[ekj5XLbMnOm^N1:WDW7kflVkMmnD[njOUOiGnGcnONlijX4io]=6LL\8UN"
    A$ = A$ + "iLlmmFcla\oTloV732UoLjigK?oQ6?Rek[gjejTodLFon2=^dkj5X\f?_`#c"
    A$ = A$ + "oKf^O7`o:e?K?CG3hhjPCmjOc`jN3UoDGo_loncoE[e9UloVGCdZVoDFSK^i"
    A$ = A$ + "o=>>4JLiZ???SmlAnoMf2e?`Sonm^N[mh`<M_>ioJjo7`GnnnLOoWoo<O]?P"
    A$ = A$ + "eea[_MeeoV][76K^^7co\>7`E<oWm<MMEn3mmfkl8og;gU8o_aa1h<[BonTO"
    A$ = A$ + "io;a^G#\_F_[G00Pk;hcehfcnCPW1XIK>a[Jn?^6WLcoKOL8DfC9o773jM>N"
    A$ = A$ + "balBTogjH10XoO00`:jW[Uoc3Voeh;o[Knc]oWm^NUO0X4f^nN\W]kmoN^n?"
    A$ = A$ + "000lV]O]=WeocIMm?oniklgiGoo0H>MF_oL]O000HFlSnoMlIO;`o>0ekjEn"
    A$ = A$ + "1PB:dOO#<CoMN2000`Zgo[E?o0`obO_^2000cZOncokaOfGoi?3\chjQFml3"
    A$ = A$ + "00000c_[NF7VmW5RE?o00000000000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "00000000000000000000000000o_?ohS?bB_[Gi7000008^Lkge\e?\E?o00"
    A$ = A$ + "000`L:Fo[ncOnCFN[m1Kec?00000[ZInimZ4mkj>m3[giFn10000HM]:olOF"
    A$ = A$ + "[nMUJO`TonO>000000OIFjgeMci\mcoiMbFZ7k_cfCnkoi400000[UBnc3iX"
    A$ = A$ + "gOSEkWocLbhnj=eGi<>fSaSE?o00000Q=k?oK]^oGm>_7cMYckX>>TKOYNj["
    A$ = A$ + "LgObOoo<10000\:F]Wo]kdkZWlcoH_oInLdnio\5m4<Uj[Dmmj>m1Cne3#00"
    A$ = A$ + "00j;?oK_kWk[cbLZeM^mjHTjgaCjCI]boIm1\G7[[m[NM>aZWO000084?oKe"
    A$ = A$ + "mioZWS9]liPJ4j3hM>7^Ui_fS7SB__f?V8oj180000]WWo][[kLFOo8dg[WT"
    A$ = A$ + "gJdcSN<NTkicm<oeH\XdmnjZNOWcfAn7W[=0000`lccoFmj3d8d7`Se#\jY5"
    A$ = A$ + "?3DW]_kA_O6UlGSc;6]Wk]L7;TOm0400XOfV;J\em_om<KfW[cbo\>6lFcO9"
    A$ = A$ + "kU#;cO[FkGZ[1m^?S<SD?0KIOoR=VdjekOLO^U]HOmFl:WJZV7[7UlGSc96m"
    A$ = A$ + "NOUjHQl[7P00#?MecnB_[_JWm_n_Kc;MoLDojo^om<KfW[cbo\>6l6conn:l"
    A$ = A$ + "fbO9[m[f?e\?HW]>lFMNBZm2Z5m38ejXDS=Yd[]kfKg#^ch#_koG_cO?joe8"
    A$ = A$ + "dk[]GGEWboHLoD00H5]=G]#[oOVWWfaL7;ochh`nLMEnWaaPgJn;E?djAn;M"
    A$ = A$ + "_;?C=jkGXeh6KO5C9?gM4jmgnaRD[YBVmmILoiYmjEXJX4m0<UNo<Ji_Tm0Z"
    A$ = A$ + "fmnjYmnl\a2iG?010PAAXel7joM_[cJVk[bo\=>4KNiGUoII<h]VoSmDh]Uo"
    A$ = A$ + "JGomZ7HiF?ejlgkVk[jII977:iamSeF]jcK^_2E7?Y7PYfkWA<oUX7#e^gGe"
    A$ = A$ + "lUl[7P00`X8dJBR]noALNJgMnSi\NmB\neJ=?gk\MOBf_kH#YcoCfNm8oUJL"
    A$ = A$ + "HKMN?]6jInojkOKMQe^nKijRKE?0;M_ojah#Y>f7Z7KSb[Feo_SmDODNM\^N"
    A$ = A$ + "bi2YVoAmUlo\l300ebaWkQNG?e>[]JMoeZngVKI9cN:oI]gbJ]dKc[>^OEn_"
    A$ = A$ + "cH#9coCgFm8oUjLf]GU\7:]>oOmm_OMQ?Yf?NmjSoiGdjG7goaZ]WLMT[bo8"
    A$ = A$ + "d?PHeE=boamkXlZ5moKTbkE_>[oEb_lgKa^VE_[;0Z=GoSEnHOXe?>cS1W=O"
    A$ = A$ + "\AO^JKeofl:;If[alEO;mo;Ul?cmo[Fi_DWcne[Be3^NUo]]A^S3GekWmelM"
    A$ = A$ + "FGLYjUfIe`Ck1D:io^_:M_4UobToFekWBWoHkSHcg#nUoFKO>?kNMcnJ10VO"
    A$ = A$ + "a^FF>cege3WC[Fo_>Vm]<_?oSF?_ZAVcImoSbHaajl>Ooa^VG:oN]^N;if;e"
    A$ = A$ + "ikNe_O?bO9f>m8o?]ngomERN`ecl__oOY>>TjjOcM=[i^n_Lg^QnjgiJZiTo"
    A$ = A$ + "LNE[l7[FTolcoIg;jY_ZInS]obmj9boJWoJ8dJM>;om\F1h92Mm^SonWMm_H"
    A$ = A$ + "_ggde3;M]nVbnEekfad#gCl\_WA?oYDSaV7`IONIT7;B]FR=__[njUJood<n"
    A$ = A$ + "e[DGohE7gCeCgGKc1^gio>Io9S1U:okG3bCg>]<o?]ngOl^DeA_bon]EZS37"
    A$ = A$ + "onR]FdDGSjE[imZe2Wjn8fG?gaCiO=coIg;n9_JAn?KO7Kk:obO]5KoOFV3m"
    A$ = A$ + "eJA]2`CTbe_^KooN;G?lZNI]om]G9fVSPcZekfo[A?oYDOi<7XDf>mN\8gjX"
    A$ = A$ + "Di_US5kWoiCf?kW3L:cok9cAMOo_fV3L?coa\OEnOjH#9boaeMlda`FVoWTQ"
    A$ = A$ + "S7_;amLkIng_]CMLXTmoi>[k=dHB:kWDfoYN>Pl_Ni_6moYEi?WmO;koUloN"
    A$ = A$ + "bOYUjlmBMnPe^N1h^RMm^mGk:d_G^_oAojQYf;XmIkZk9m6bmEejCjocXWo["
    A$ = A$ + "Z_k<?X[fFmN\8gjhZijLWiWEkaR]iNNeaTLbonog7MlmmTS;OIK>`m>o7cdI"
    A$ = A$ + "ioYS1U8o7GcaC?oZUio9IHogcIgC>gj[fi?ffHO6BMLhhmU?K]Ui^fc#GW;U"
    A$ = A$ + "[;Vbn:Uj8ec1Toe;oQZS[f_SBncY>RM]5iO]cOY]]OS]o3EWQN_YNM;NGR=g"
    A$ = A$ + "WEQl?Gio\[g5:_a^ngnaSgfe3CI^FQ6W^:Gi>7fA;oGMomHgco=ToL>V7K>="
    A$ = A$ + "anm7ec5^K=LlchaDkj8e]mf[B_?bihmCffk?oBnc?g?Il[Gio^iHomUCiJa?"
    A$ = A$ + "YN;Mn3ECQf7kWWA:efI[klZeT6kNNi\n_DGokEeI>SaboJVo#ko[f_SBncY>"
    A$ = A$ + "RmiOiO]cO]_oNZih\_gJFcd>]HnOS\SOF_5OVLT<KioZ[eOW[O_okm]Lm`[V"
    A$ = A$ + "[eaOoHo_cMk>:REWa^NgIgc;fgoXUoDZ]HW7OeGo^k_A8cYnmGZ]CY7;f>o\"
    A$ = A$ + "6GcYVgoohfNkcGbONinhmR:miFennIiVSm_oD^FlCZgBWo#eDXmaES3Y^ngD"
    A$ = A$ + "j7C=FogEOOY\m^jL0iOmboIc3i>_jAncIkMLnEboJWoBkYSU]Hn1mfneg?KI"
    A$ = A$ + ";Uc=2]noEHLHVcO:W?Ogl?bOFYTgkh]Nm`[VWE\k[5kNMi\]71WESW=oRDWO"
    A$ = A$ + "b8VoW\fRL>n?BW;DRmOYnlL]6;Re;TB^m[eec>^]gO=Di?mLOln?UXfJAn_K"
    A$ = A$ + "FRM<OoeS?>WUA9o7[[HgG9UaP[VobMG3K9FoG:OOG]mBmN;bojTo#ONi9cO_"
    A$ = A$ + "Gi?e]GXiG:o[Kn;]D7;gZSD[iJE_]fFffONg<U_D>_h\ogm^>UobT_BUoAOl"
    A$ = A$ + "i^gkh\[omf^NhIeGXkWMUcnn7]\WB=VcH`EO_SBncY^R]Vd#I?eeXdSaRB\o"
    A$ = A$ + ";ejo[eHafeT:A=FclWjfNkjWbOJi>dmNfoNNjj7:Mn3ECYTUHI?D]Ejj]5K_"
    A$ = A$ + "#W7LeH`EcQ9en`TblQbMmOY\O_JKUjmFToe9oQVKb\Vo#caBnGklGBa^GdIe"
    A$ = A$ + "dEonUN>BmdI[1J6bgMbm:<>\2io\kcnTlWjlGjMVcmJegmm?JS5GEKG=6Mg_"
    A$ = A$ + "oNWkLZ_#ca8finYlIWNWokDCKIkhHaa_NYg_m<c_Q]CXSAOmZFScelHHX]mf"
    A$ = A$ + "eHBIO\ZioZeRLLkoTj]di?D=]me2UUHm0HkEXJ[TcC[Tio\J;di17?N6KKMg"
    A$ = A$ + "eoFkeoMennZJjZ?38o[Gn3=g\DcOXOM[boEojHK[SG3DnGklGBWMOWL7S:iL"
    A$ = A$ + "4jY]akHg[>daVgJFCmLRD67jMM;og?WQV;nMcOZcOYgI>fek^keoN3G?<fee"
    A$ = A$ + "^jn[k_FG\_nISaS#fc]nfO]mSWCOfem7alodJj^OV^WS5UJO?JKW[fVgmhD\"
    A$ = A$ + "gO>eM^c5jYeoZVoHgo9fmR_ZVJIn3ECkg7Q^oK\l7KLk>SW]8oWEKQnjaboa"
    A$ = A$ + "]EZ[omZifLfJKol[O[?nlbgGZcA:UeoVjHYl_>i?dl#C=oQne]:oGm[?KkLl"
    A$ = A$ + "JUbojVoB:UJn_g;JGn_jmVbL>6AWMoiHil=WGioWIoYio==6Lln\U:oY>oUN"
    A$ = A$ + "WiDWSBZGo;U[S?Ji?UiI5jkIo_gCf7SLn?kc:eHO<JIn^iO46;:in=fiom\V"
    A$ = A$ + "^JKNgSCYniicNOUhlSDg>[Jn3M_WWLOhFVoDVgaakS6;oa6gbM<]5ioZj:dG"
    A$ = A$ + "?Fn3=>6K>8i>7U#onKcmi\e0OWiFME=MeW1Toe;oQ^NAZi?gJ^TioZOmIKWm"
    A$ = A$ + "S3boJWoB:el_O<8UgK:c3HdLfmWgOLhZgC_cQlol\7K>Oanj_aaPSgW]TiOD"
    A$ = A$ + "7;^cLDBmjOYLMlA;o7?f6kN=Y>W\c^6Ql?^mo[di?WmM_bL:eO\]EXgcISOe"
    A$ = A$ + "J\h\k7WcfMKkLean[>7h^kgkFoYnmOefZUi?U?OLefihmNBiNgSDn_J>4ocm"
    A$ = A$ + "KgMOdHi?fhF^SY]8oGEGQnjaboa]G\iRLWiX4jgOTjoSl_fi?dL\B=oiFcU<"
    A$ = A$ + "oGm[?Kk4J^JboJVoBj\kk6[NR=NWjmJ7EWMoiDmfb\lOncmgM73N3S37_?K9"
    A$ = A$ + "coXNn#:G_k^Gok=Lm`H7W?N<kXHWS7jmLfnXgI_gi_eS1GUiHG;hYi?UcgZi"
    A$ = A$ + "LJbmL`JUoDo\gM7;>kjf7?>TjfYFi?D]TJmOgl__f>^mf?^GSl7jhjnJiZiM"
    A$ = A$ + "LFngOoWc^FfIK_NVoD[i]ko6;oa6kBmc4]<oWM\>VHi?D=7K^;i<gV#_o]gc"
    A$ = A$ + "XlcoYl_fi?dW9C=oQne]:oGm[?Kk4jjFboJVoB?GiSgomZ\Ub_oEGkJ45:3Y"
    A$ = A$ + ">WRD^NmXK5cOXcoOBnOCWoOfakBToAL<8e[gUkeoN;G?<faeJMlohGO4cN[b"
    A$ = A$ + "O?63B]F:MncMogS<OfgCYboC[[WTe]]K\[o\ONUe8oQVgjnJ9UJoYi?dHaNa"
    A$ = A$ + "ZUWVoSKkSkcDg^WUk_NUBml6bO\_nfmBc9oiL>#[cO^eK\lOlLoHc9iZiZ4Z"
    A$ = A$ + "V2mmLen:e]C:eFZcODnGcl7kc[Y\?2m[KEn_jG7KKMlnXboJWoJ?OicZ[LZi"
    A$ = A$ + "JE_]J<8f_>UgK_cSlWGV;MnO3S5[JnCmjMiLm_gbe3S]6TJMlOT63REG]:om"
    A$ = A$ + "H<8eJYFGo_7S5gIOfRkoESaRcfVQf775kleWTomO]HkcD[gBVoLldlGZJh\L"
    A$ = A$ + "oe[DZmg#nS]=f^GJ>i_67o;ek=GaboacmCMm_Y>GULWocMVCE:K[[n<Pl_Ni"
    A$ = A$ + "?dmAVel_]]>>W:iOMcO;V_L:eO\jmZ[K=RBI>maV3KZcoOT]Ri?WidVKnO3S"
    A$ = A$ + "5[JnOjekNkG?<FmESSoSDn3EG]:omJLhZJ9W<ERgK;6;B9c7Ooe8oG]?:aHa"
    A$ = A$ + "IKcWh9i_TePl7?gOm:UJo=ToHKS]kWVCn[aaoBmNcE\lOlLoW<oUJ]n_BD?G"
    A$ = A$ + "mI0iOmbO\[1ERmgXUomGkEnUoF<Oi]OM:IHokmhfXV[[YES1ohH`Wog?2h9l"
    A$ = A$ + "NkMNTolcLYboKI\HEcoIG_KcM^Vmnk;=bOV8Ue[DZSoSDnObJjNJnkeh`MGK"
    A$ = A$ + "J]bO;6;Bmla#cS\TioZmA96;bmL_SZmaoLfWgI<IEcofmXbmcK_YloU]k]FR"
    A$ = A$ + "lWkHE=N_i:Fn3M^oMGciIGoZVO_Y\m^jc0bojUoHG7I6coffJohPl_fi_fcI"
    A$ = A$ + "nhok#IihaPSo_KiJLJaJ6>Kn?QN_m>?bocclMcoKI\HUcoEGkjhJFRMm_mGK"
    A$ = A$ + "n=Mm`LGcbM?n?Bio9[Ck9i_WS5UJ]YU:o]H\X6[7_6i_4S5?iJamhjoUnN7["
    A$ = A$ + "Jn_Co_NKio;Kg[]5O6O45;oQ67^kJ>S]^coNL?QeoMlkY4eA^OnGnGWl7Jo?"
    A$ = A$ + "KiOonGnUoJj\e^N\FBimEkj]Vi?F^oj`jo:nhPloNboIcQl9io]<F\bi?e[M"
    A$ = A$ + "Meeo^cfLD\J7ocI=SU:omNl8WJ[5i_5S5g]NJMn;aHaC>g[7On_dOFIEcofJ"
    A$ = A$ + "<NbiHSNnobfJRZaWa_J\Z6_gkF;YLnO9GgIXJH_[N_UX>bmcobojTo#ea\Uo"
    A$ = A$ + "mkGiGn[]]mMXk]WcG[5eJ]bO\c[nkOfWKRLLBnO?io\<lTlOl[gkL:oWWocV"
    A$ = A$ + "cA>G[k]Mm`ElhoEgknhajLbO:KgA=c]8o]L\8gjYei_TS5Y^_?kjEe:oY^?O"
    A$ = A$ + "bHbZVoWnI^A>oY<>lT?cMen\5O?UhlPF^6hD[gB]o_cW1Toe8oQV[i\Uo]]G"
    A$ = A$ + "Xa1iO]cO=WgL\eaNeGKdF[gC63neaP?_Nn?m^^UolcI<g9oadkL:oG?64klh"
    A$ = A$ + "[^nG\?gl6bnIW3DZSom>OQbK:g3o>i?U]kXViFToF>FlTibeRlGbaRDggWMm"
    A$ = A$ + "ZJUoDgW?I<IEcoCo<g8WoD67:ajeB9ooM<8bm7?;oUXFbiLP_ne?iE\lUBMF"
    A$ = A$ + "RmmCo<Pl_6io\?7>;iOofEnUoFjhmjfGKkoJSjjlNJfomaP??hmgo;iGnUo_"
    A$ = A$ + "cLX[UMeeoBIKlf<k7o_jnkg=oG]=7i<GklgSaRk^VlJWoB?FTjnnH?<>[W=U"
    A$ = A$ + ":oY^?ObhbZVoL?Wk=UoD67^kWibE:i_VkkL?78fj#cI=ZYLlJok9W]I>[mm>"
    A$ = A$ + "O6hY[3_FioZmWlolcmW]lOW[o9o[AnKU#g3O4Z[JVgOLLhc?3:g[EoF\?ooc"
    A$ = A$ + "aj8iohk[ge]l;oeJlHE_ng<NloZe^MgloTeaec<OfJi_Kn_Jo=2I>fLl:EnC"
    A$ = A$ + "M>TenliLESco_C=8o]=gSDnCILHKOniWQok1aHOmLgoYTokjZJ_Dm0jhaZLN"
    A$ = A$ + "5Kn?i^=BYfbiloLboCNERlOefGn_geoZI?PfGOe<oKkSPGkiR[o9o[KnY>ne"
    A$ = A$ + "LioDooVYeo;ob?[mao[j9cMboIK_NWgHIN[fRUUkTo#KcN=FTJ=DSlOWjX6W"
    A$ = A$ + "?OLnTkEkcoCMOnTaUDfViXdOno^e#[cm8UoD67ffWK_>nm6j[MWmO[kognll"
    A$ = A$ + "Tc3f_6eO]VV<Goj?67^agKZeE>WoWCnOj[WTo[f^bomcoEckZTeI=boff>he"
    A$ = A$ + "MNhm0Toi?oDNonnEO6dM_NmXkGco;BnOc[oGnUOFkSoQj=aaNDTCnSYgil\<"
    A$ = A$ + "7kgk9i?emg8TiJWoF=FLWnZ5:_K__kTo#cO=dn<gj\Ti?fWc;MncMONglWbf"
    A$ = A$ + "k]UoL67>^F\mOo7oegAZio^2EckGGhC?7h\am[F7k_>fmig[oM_k^ff[ZkBl"
    A$ = A$ + "IPD[cJUo[f^bocboEO6LdcoC73B9ogmE]boamaI7gToj<WHBoLZPoIomi2eo"
    A$ = A$ + "_8iohk[ge]l;ohh_l;o[Hn_J]fiTikToD7;>K]?gMLlZe14JK7[>NJn?KLo>"
    A$ = A$ + "eiCcmK;oi<>LLmGOmm5koN7YVoLMF]^O]QehlPS7S2mjdL7HL8jfhVeE]nlO"
    A$ = A$ + "Z[M_4iOoH#:mkAn_geoBmL\gBngG[U8oWEOe>oG]?ToWUO:_O=GV87gOje\7"
    A$ = A$ + "E_eeo8ob?>n;oboZVoS[eh^O_g9o?MOnda`#cW>e]ma\LWlWji2W]F`B]fo#"
    A$ = A$ + "[kL4coC77bI]Gg]G4YToBdcQ#ekC>?8ej;nHeW9:nf8UmOYF7UlO_N]fclGZ"
    A$ = A$ + "[oMWme8VomGcXTi?gNDERlOefGn;CnY\nmeT3OL_DGgNdlkie7olNiGnW]l_"
    A$ = A$ + "jFmSob_l;o_clWC?_>kkm>ioYkcW^foW^MjAnOJmoTnYUBO0C=oaF3GXmiM["
    A$ = A$ + "gkmIg[kcJXmkGOe\4IkLfhBXce:aWog_m>^_7Ql7kGGjlWJ_VJIn_ZFJE^7a"
    A$ = A$ + "loTaQDfGQn\GXGU:ooMKU`eQ>FSe:oYlZTi?ff_diWb:UiRDRi]=ZTOiOUco"
    A$ = A$ + "ZKe?n;ob_l;obohWoX[QoP[f6AG?f9[ik>[O?UeQGRNQLLK<:mo:UJmYW?lf"
    A$ = A$ + "joG=boKZoG?=oGeGYA?oUXoGbOIj1HYbO\]M=b?000`Z8WNm5kk?[No]KMOU"
    A$ = A$ + "XG6?]nS]m>KOLF_7oj;WWdj1K\JZfW?LVWWm`S1iD3e8ogYo?U>o]XgOa>Vo"
    A$ = A$ + "VbO9>Gh>m0L4bOYjmE9j1H9cOX]]No1000dGQN^\BK]PoN=W_Ye`EkWoWNW_"
    A$ = A$ + "Lbo]bm9S3m>oif;TJToFek_#Io]ToB>6TK?0kMn;mh`Cj1HYcoa]]No1000d"
    A$ = A$ + "O1koG6[iKFjogOkki=FgKX]E_cG>iOfjoGXc[7YnoDkaWDj5D_cO]Nf?_cco"
    A$ = A$ + "H_joG_j1J`[mE`lgkc30000hgFmnomcO64olfol_]_?P_QaQOVokVkO?><Bi"
    A$ = A$ + "oh?OY7EclOVFVm[j1D]bO_jiC^m0[eiODj1J=c_No1000<N2fo_<F_gK^oOe"
    A$ = A$ + "ji_i=<>Dkn?dkl9oWo_cggniM=Qo<1>MoePaVLj1F[boXf3dI<o0000lK7G["
    A$ = A$ + "F^Oo_eno1[PHm0\Umo[7m5?in#EQl?2mnJec?0000odCoIC\7o\=2TWSm3ji"
    A$ = A$ + "o<_7ChmC?cli??Re=oS#?#Gel30000`ZYEmZOTnc4h\WoaJ^?7UNO]Z?oW00"
    A$ = A$ + "000`JiH?9KIo?7QnN5ZVZIoo6]l300000c_FfCZA\gGQk=GMnioM4c?00000"
    A$ = A$ + "`ZXH??PNNo0000006FAk3h=ekl000000#Ljg700000000000000000000000"
    A$ = A$ + "000000000000000`Kf<o_m^cLf000000^bGm7k?oi?CIObVi\100000LU]nS"
    A$ = A$ + "]IVjCf<W=00000P[\_oHOnaWCEObVi\100000iKVk;D\\MliSKVjAf<W=000"
    A$ = A$ + "008?clO7aMFffgS\So_kMMGZL?SI300000Bg<ogALGU]I^7IcLf00000Pd<c"
    A$ = A$ + "oM4G:IKVoITMVc600000TVI^7AYT]E?o00000\BVinRTbonG<Ko<RVBfFmWo"
    A$ = A$ + "A00000F5ngo2moKfN6iVi\10000#>l_o5cI?RlcoklV=00000Be<oc8Yom_#"
    A$ = A$ + "ooVe\10000#ZViNTTKo_docekh?0000[WINMQYT=iOmb_on_KNkATWo_i=K0"
    A$ = A$ + "000L?[jon78o[Mneo_i]7AjoglV=0000bg:o_o1boJWoI^79joUl?[I3000P"
    A$ = A$ + "lh_o_TOiO>kARnOUFf2mnVeloeGK6b6000`C<c[;:Uon?K5Fo[nO8ob_lOek"
    A$ = A$ + "KFco<T;000PW`OoWi_ocToe>ocFOBdo_aXoOK?cMYZViO6>^2000LGnko<mo"
    A$ = A$ + "AnUoIkJ0joGKkoG\ni5Z6>CYj;Xno1000l]m[AbOoW=G[CDo?ToAhioJTbOX"
    A$ = A$ + "N99oiUoBeW_JgG`Imh:000`M\jmo#nUoE>oaNOcJn3U;i?NO2kAOn:EO1WeS"
    A$ = A$ + "[000`c=c[=8FflcohJgo7iO]cO\gg\VoNdo_cj?E9niL]TiOTkcgCj;H?>_n"
    A$ = A$ + "9k[glWo:mi`m>?000cW]e8<Scgl\\YoO[MoOToe>oaNOcJn[Ioo:ec;GYj;h"
    A$ = A$ + "Cbo\ZEWG_=VNg_ogjW1;ilXViiT100d?7Goc<=Oc[bfZgo3iGnGil7km=[i_"
    A$ = A$ + "4mo[Dmik>m^:Wn2ZoOmicek7?_kfh=ni`BoWOh\mW7900#o]O>VngoRiOmoj"
    A$ = A$ + "oQom?#nGklWchD?jcgMjYEZeZnoe^noMfaUDlfnLHYbmKNLhZj<gNhWbfl=i"
    A$ = A$ + ">iOV8ob_l;ob_l;om?oaFkC=ZY[VWK?bfagCYWknXh\S]komkMMFkl7jl<iG"
    A$ = A$ + "nUoOWoNg[ZBd[[Lco\;DnKemM7ejM4cmKLLH;oaZec6O^jki=ToWLnaK>OYF"
    A$ = A$ + "kU8o_maYIlh_l;oboeIoZl?cS1[Nng636]co?^fXJD?Y\Vbm_WFV]F^f_[bO"
    A$ = A$ + ";[SD?_LfbO?Go_l;o[Ln71b_Wo_A?g_aaQDkaN^I\Fc9]dI?gaW#c9>e]C_c"
    A$ = A$ + "K\S[e>o_U?;DcSo_Eb_l_Ziohl;SUoIM<h]ToJ]_3MNN\co[I=LeaVBoIa#7"
    A$ = A$ + "O_jhO977B9KQfo]H=HWUoF_6`FG3m<oG]63iGnUOiOUbO=V[afnk^KSFF_e8"
    A$ = A$ + "geHn;m>Og]FCY_=aN?SnH#>I;U[oLWaXNWm[ZmBToAJMR?ILj97oO[Toe=oY"
    A$ = A$ + "dS_Fe3TNWmDWoi\<6lVbO]^gJ\nKUj_O]cF\eOlTJh\eeLlHK>_gB<fOehoa"
    A$ = A$ + "eVE;7cO]MFn3MmgFTmF>6TjiO[Nn[IO7B9o]Z>TOiGn[kLYnbMg6k[gJF[e:"
    A$ = A$ + "gUX^;mf[eIOoidYDokO_kg6SjH`a?_6kcfYDoGmnBIO=Ji?dL?B=oQfFSFnc"
    A$ = A$ + "M<j97oO[Toe=oilIfgjW_C=?iVognH`K:oehL_#cWoZioGSiYWbmXS]>QBTi"
    A$ = A$ + "DccCnNciLZSI[TiOd8oboMcO9LF??>[V[M_#TOiGnKceM^kfXEeJ]bmZgo_k"
    A$ = A$ + "FkUJkdj<7Znb]f?km?R[?n\Jj>eKYgNe<g?mhIYNoS`i1m:oS^E>oUnco_9g"
    A$ = A$ + "]G>aj3D[[mI;oGegY]mEYngof#cMo>WoGbjXVokOK9kMGYgFGU=moAnUobfK"
    A$ = A$ + "QB=_dJe;4iGnUojNMWooo_oamg6OnON?G7Foon^FgoIQkMnc7oHK=RS1Yf_Z"
    A$ = A$ + "k>WeA]oGGEC?YF[af\FI>eeEFRSoUJk?JSC_]L9oiWQW\noNdo[k^?;Eo[^K"
    A$ = A$ + "ocNJNfO?gI:oWE7UNmo?]f;eHHZIk^ioZeVlde0Ubf>UJ\Fio=#nUokVoLDb"
    A$ = A$ + "NNLFF:E_#TOiGnkoeWV=okaWbegbB_mZMfg>gZDWSES]I=bla?Gmde_6jkOD"
    A$ = A$ + "joeEio9[mOof=dfYgi?deN3E7ehhoMZSAhlRJToAg:WoBEkmH<h9kcBoIbB\"
    A$ = A$ + "mb9??mj[SNnCmJe?IOEbkA5kN[?ihO>[o9fnj\ePDSe1MejN>KoYo?b_lG_n"
    A$ = A$ + "ODkNNLF^NJM;ob_l3UA]F_f8_FhDjoEYbm8do[DbO9[_H[OYGi?UeTfRnOdS"
    A$ = A$ + "noUjmjjEoOTob?GTLfVUlJOa63b]F^knj>SkeHNQ?IKWCNfoNcmW1fg#n?;C"
    A$ = A$ + "YdS\L7[[Mn_kWObIm?Q6W>kmfRk7WK=Xo?b_lGfnO\mi\AHlIO]TK6TOiGnQ"
    A$ = A$ + "bHkL`BoISmWO?JWg6J^iUlcHaVonX<FDRe>=2kSkNln\kUDSSoYF7enhlCOO"
    A$ = A$ + "SnnMDZSNVoLfVelJCi^];E?L^C^KaiOeXf^kJPOKi?dggCFoOXiNgRlWjL\:"
    A$ = A$ + "Ao?b]WK]#ZedMboX>GcWLNcIWS:oek?oRN;U\UB_36YNNLEFC=?b_l;o#IdZ"
    A$ = A$ + "nodkLNF]eRl?BS5QVOE;joB_boI[3]UWogZeMWcnZGOn_fS5[HnOB_SJEo?N"
    A$ = A$ + "JMod<gb?3NFmERaRDjCb<To#eH^Io\c9[MncmcJYT]cN?W=V?:cohZjl9i_g"
    A$ = A$ + "i[6OVAn_nJ0c#fC=KWe_PAicig9cGU;iGnUOX<Fino]:moj\jZfed8<7]DFW"
    A$ = A$ + "A;>n?Jmo[ei?gjCn;OVSMNI=>7LKOMehL;joG^mQZVS1UJ\8WN0lVcOZOniZ"
    A$ = A$ + "aZNN_X#kkWLL=ff;Wmc8h\Jn\SGOmo>d[A>[i<VLEfFml_mnjmL;[iH#>GoK"
    A$ = A$ + "oWIjM]GR\WbWoUOiOEc?D2eJ=`eN]eUZfZMm=RO6NdFoO[?N_E7]nhO]kiE:"
    A$ = A$ + "I>FMeZlWJm9oU?c]<gY>>ldaRLcl8NMXkF[?YGI_YloTggK;oYV]H_WFMOmJ"
    A$ = A$ + "<fTBV^caogVWLlOUbo8>gjJ=6Llcc>n;obojVOX4Fmno]2mo:FngoOWQmE:7"
    A$ = A$ + "_gG;]ZN>[7PmXoOm>oGEObOicL?bM:S3?M\hZScG]>ZN<6LF=Ebno=;i?dH`"
    A$ = A$ + "MOOSJnc=KWmN6QiHDbaWHiOUOngToakJKU<ojoWno8obo\U=6;[LooFUnOMf"
    A$ = A$ + "aVFUoAZ_3mXFJM=4[?2SBnkEooVilOFV7U[77JLX6mo[fWOeRc?_Z^_Z7#cB"
    A$ = A$ + "n3Ekg]gWm>gaZoLk1J\_oA:S?I\iZSOclJT\ngkMno\Uo[>oOekoYl;o[JnQ"
    A$ = A$ + "BHUkoG;Z_AL=8[Fn7Ue2gbj8fnJDbO_jog<Wo[bl8OmWk>F4KNBS`Wg_ka[D"
    A$ = A$ + "?VmFkmI9ZoLjmiX>gicZeHI;UlgkLESc;2UoEoiOKeco:OnOXgg<TmLbVl;o"
    A$ = A$ + "[LnQWBooVonO]jiODF?H>[]_6IN4>7l\NPEcno]2ioZnZ=2GkYdeJ:mDMTbM"
    A$ = A$ + "Xjo^mZ>enXnfcO:[mMOF7eciCiLhHi#o_^^o?SnijiToD>n_jiOU?o?di0c#"
    A$ = A$ + "fc9Kb_l_bi7NZomN]OnO:kj_[af]Def:eo[E?oQjA#?[SFd;ZHm5Id>o[Eoi"
    A$ = A$ + "?\2io\]k8Tk#ekC7;2]>aAjHmM>fUJ>>kkIVbO:mo;F?djM^b9oidClHSG_Y"
    A$ = A$ + "<Wki2ajocfHgGOYNGkUK<hkLMecogZVoEoloAH^e]J<hhecUOiOUc?D27o<e"
    A$ = A$ + "X_M;E]]BmoJecOXiC=keaXTiNEO[Hn7m<GSj>fgkK8gQbB>S5W]>aI:oYdo_"
    A$ = A$ + "gfilW=6TB^fgGTEliOJKLJ[_GKjM]G^aP?gigoIF:o>oOFkA#:ICnUoE>o0g"
    A$ = A$ + "cZeo[#eD[VcD;gGYN<H5kogXMoSJoWOg:VoA?ceH\h]ViB<F<Cmnl\lWJooN"
    A$ = A$ + "kI?WaPDkCjKD:IKK<J6kmegIlWm0CnMnO\gCXNTnF]?;b_l;occefPNKejoE"
    A$ = A$ + "XJJUjoiZgo_AlNSQ^7G]jogZToA?ceH\h]ViB<F<Sc1>ein>SI?WaPSc[HTV"
    A$ = A$ + "OA9bOJ?oCcK__n>Wo\7HbOjWSlFUjiojoYl;o[In1^WE[oGQZYHc[j=__BmH"
    A$ = A$ + "`Zeo_AjL_FEO[Hn7m<GSjn]ViBTWILNRYVYI<kiT]HWW<;iOfnL=UeZOn_nO"
    A$ = A$ + ":obojVOPkihW_ZMo_6]?37J]Dc`nj\JH4F;Qnoe^j;dm#7]lGjjKdcL=ZkgJ"
    A$ = A$ + "V;ANVai9VJVVa\WCffoNfjG`7Cdc1ffOFQ7cI_[;63[nionco#nUoe=o0gcZ"
    A$ = A$ + "olo]J6UN4dbj#ooF_l?jI^6emK=cU8?chl4mloUgjOfjkaVNGkUK<hlomOPe"
    A$ = A$ + "fZOn_ol?TOiOMc?`mLL>3e^oO]JOAlS1S`j4mloe^jKDjiK;[_A?ceX^O[I^"
    A$ = A$ + "4iI6WWXWo_Lnko^i\g7OWahoko0[]EolOoiO8obojVOPk9dJ9VQm5a?6<2[C"
    A$ = A$ + "dcoGkZ_E<oSNV[AMoFcL9bc<>?A?oOY_nWI^g7OWCoIWb_]jWok?o3iGnGgl"
    A$ = A$ + "30GKDjA#[Ono6ikODkjK5coXWiJDg_e<GRl<ScCdcogLW=PW;fL9WQ[A\USL"
    A$ = A$ + "On_TOiOEb?0L]SoI5g[WUPFF7Snm?JmcogX=gP#gS_d?oOSFV[aHaK=cUH\H"
    A$ = A$ + "6W3LZcmM6cN^S10[YmoI4\MmRIjiPLK^a7cYl;ob?0TR#Gg\Gmo[EeaXoLAe"
    A$ = A$ + "bWo_AM^1KgS_Dio=TiB?FlVclC7;Vei0WbLOWe\WcH0`JJk?OPSoI:gkjZLi"
    A$ = A$ + "kjom?AnUoE=o00Q<j?o8]jioKol3jMVoM=Ffk_o6bLY7;NcInYS5cjLPCI^_"
    A$ = A$ + "cJfcI<0H=]o?cSIkJOOWacogo4iGnGel304bak=^M?TNGG]Zn>>oPNWgheIi"
    A$ = A$ + "^onK9cUL\h]WiW<F<cc1nZin>cI?ea0Ped\O]__cIhi7:obo:WO0P#6UOVWk"
    A$ = A$ + "EmmVj9DY^onK:cUJ\H6blM7;Vmi0OfLOWm\WbH0000000000000000000000"
    A$ = A$ + "0000000000000000000000000000000000000000000`hkc?n\ke`K\f0000"
    A$ = A$ + "00N36iN\=be600000`Xk[n[]YgebKZf000000N3nZmJOmok[oK_[UgD]1000"
    A$ = A$ + "0c\]79WNmm3m#=N6d6QW[]M?RM3GnC]f00000:[WncSWONnNg:aa^AkhO:eC"
    A$ = A$ + "_joG]7[do?0000hWnhS?n[N^=jUO\PlKd?PWnmgKKmQhY?oS?MK<27okifX6"
    A$ = A$ + "iZeeLZKcF<>]ji70000fKo[N^=jFneo_OlOkefXWioYomafXmgYKYLnH=ZiD"
    A$ = A$ + "fV]jc:YlLheSlWB]1000#i]oIGk>?oJ?mk_gFmnom?eo2ocoK9niAl=ocdh<"
    A$ = A$ + "VoDj3E=ZiDfV]ZGYmhW3gNncM<0DF_migGb\_:S1abmZ=>4J\Xgec8LN#_[;"
    A$ = A$ + "Pbhh[FomgK[n?o_[NoOWanO]ji?en`e[noeRa:mo30NR_VCgf[ghlk:A^?nJ"
    A$ = A$ + "V77>;g[bh`nec4:c_eejTKn?khn<WOHELlE[on71UH=`SB_?^ei0;lcoWSoc"
    A$ = A$ + "gonOdcn#eSn^Mg\eSl?JW[00QYoO[CO_fWkolWoLZIKLh\Nn]?cQj3f\<>Lg"
    A$ = A$ + "lgkj6NRkn<<mfOfW:A6VRa0moAoo6P]A??n?2KSFWYI^oG[Nn1PWAoodo_I_"
    A$ = A$ + "oOajiEXaQmoNcdi4a>O?DnW]\_j:EoOjM>^[S_ZmggXYDoloekLlTjO4f6mR"
    A$ = A$ + "noiho8\=JMVVinO]ji70N6moK]jga:go_#mhk\no=CS5jogjj9m`J6joeaGe"
    A$ = A$ + "nkKdXoOjoSnoeo]A??n?2KSFWYI^oG[Nn1PWAooF[nMXoO[Gooll?^fNB?\V"
    A$ = A$ + "RnO]`olon?i#oo6R]A_XoO>n?2KSFWYI^oG[Nn1PWAoodo?moK=jogZVoEgZ"
    A$ = A$ + "ocokoTSKf3[gN__:A6NkS1joSno=2KSNNlO4f6]>CcLo_Fml30?SnoYoOjog"
    A$ = A$ + "Lgo[E?oKS1?iioZgeoSco2go[E?ojoWnoXoOmOKdcSoS`fXeIJVkoeZWoBIF"
    A$ = A$ + "N6oUOiGnUokToEX_GWUKmoCooVinO]jio;kOEc_WAe:go[E?ojoWnoXoOmOK"
    A$ = A$ + "dcSo?mkOd>n_jmoJecO9leLJ?>oggnlLUOiGnUoL63FQnNMF^eo?moKVkoeZ"
    A$ = A$ + "Wo_XoO[Ko_Fml[oOjoSnoeo]QSoU=CUhmlFf_SBM<:i_4Fmeo_bi?DfGYa0i"
    A$ = A$ + "O]conaQEX_GWUKmoCooVinO]jiOK<`?o_[Io_Fml[oOjoc\eo77oGkSo[Lo_"
    A$ = A$ + "BMN9m8o_Yi<]bmoJecoZgoWE>oKI?fio[`H`naREX_GWUKmoCooVinO]jio_"
    A$ = A$ + "S3If7SgNO?:AFVUaPE>ojoWno<Kmoaaoenho:go_m_6]lWJ]=2FinO]jiOUk"
    A$ = A$ + "oeZWOmokWS5[#O_>;gjoWno=cmoJecoO77do_Vmm=JFil[oOjoc\eo77oGkS"
    A$ = A$ + "o[Loofo<fMFOfJMngVWXWo_g1iOMc_noYoOKS5[#O_>;gjoWno=cmoJecoO7"
    A$ = A$ + "7do_Vmm=JFil[oOjoc\eo77oGkSo[Loo2mZgi?eJJT\bmoI;ok73N;m]En;C"
    A$ = A$ + "fGmnoMVIO<HoHa:dg[cbmaGclhPno]NmoJecoO77b\?6_mnNDR\<;S1[LnGi"
    A$ = A$ + "noERW7UgdcdbIenMZoWnmgK>n?Wi_7om#GZKcFogoOQjgF;conmo8N^bIiIE"
    A$ = A$ + "Gg_l;o[Jneo_O>F\2mmj\L[oOjog<go[E?ooML#ooJfggXIUco:go_m_jifH"
    A$ = A$ + "4boMZoWnmgK>nokJ?eGSJnCY7C?9g?ILX5moj\J[eio>SASRE]o7b_l_UoEn"
    A$ = A$ + "iO<FnGUaP]aQ]G[J^?nJV77do_e[oG[Nng63bijk_mWkUBTUII<HUcoZolOM"
    A$ = A$ + "L^mgan]A_ccCbofebciea_oNWWL]ohhMOmV?oO6conG7oeQZiBmjZ]IXJ[f7"
    A$ = A$ + "CS=^dblWB]=Rdo7iOUcoaaPE>k[lH`n[_gkjY7i>dmijMmeRLOF_oVYaQSIn"
    A$ = A$ + "hom\nO=3S5jog_GS#:mo>fLLOKb=kcfH`:WokVmII<X4en\TokDocdaoBlZg"
    A$ = A$ + "iY4i_5O_edMk]E;>7Z5moJO^cYF[AnSmNO3cGLeGo_l_fiohH`:WmEN<h=M="
    A$ = A$ + "kJTk#g3_geG;b]noYoO[Joo:mkOTMg\<;S1gmIHj^OOSTWVQgnH#9ZmI9o[h"
    A$ = A$ + "aoBd?Vgdcdd:ToD^_D=Zi[fV]jnUYT]NToAlLU[bc:_nOiGnGel7jW]S]l_:"
    A$ = A$ + "S1KS3c#?>NB^?nJV77do?mo;Wl[oOeM^lSHfW]aPE>o?=3_maPBDkcBnMlO]"
    A$ = A$ + "?n?;i?UN<ESJ>U]I;joE:eA_boXM^B:W7]b[mGnGkl_bmoK;_kcn:=6\=>\m"
    A$ = A$ + "JEcmaGclhPnomcoNP:FoognmVQaR#mo;UGjoGj_oAfMcb\<6hioKMOn_llo]"
    A$ = A$ + "f7oWaWo]E?oYL?YNml_eRkGjio[\SU[F_?TOioHfG]aP#IOe63f67fN]Zinh"
    A$ = A$ + "[INLhhak#V]aQSIjhaj#Iohkm=?F4ZoOa>f_OL#ooZoLi7a\?KS17kkM^io]"
    A$ = A$ + "fkSWTmII<h9I?dH#_ccM[mWNlo]N=Pmg3oYSQ_ak1>Si?en#EjcICILHDjoE"
    A$ = A$ + "_boKd8LlZWIO5kkQl[oOjoWno5je<?>hioccoGZ_VYnoM\oVUnm?b>nZfOOS"
    A$ = A$ + "VE>o[ncoUWo_enho<nl_]ji?UNKekWo_N?Fe[lckcZO<MUco<]>WWVmEM<HD"
    A$ = A$ + "^WE_bmaGclhPWo??oOWM\OFOnoFIgmnKcbm5GilodNHnd_oN[4en\TO7oGkS"
    A$ = A$ + "ocBncY?LU\VCIK>:g_XGi70N7VUNLlTLOle<?>hioccoGZ_do?hMkYm`l]g3"
    A$ = A$ + "dIliObaO7oGilWBOXjecofXdS<?oO0`Ido_e]oONnolloiio30PgPA^?DSL]"
    A$ = A$ + "10\IFjaaCbm:go_#IOf67^:cWMN`<<Fhio30000FKcB?>NJfGYaPDj1f\=>T"
    A$ = A$ + "COoV]aRHWWWkG_gi00000hNdo_e[?7joGN_NkS5QniJ>d_G\_n<<600000[\"
    A$ = A$ + "E^oO[LnGaOnW3mgmQQbn\M>Qno10000[]I[G7bOniNUkog:l_1:WUWSi>e_?"
    A$ = A$ + "0000PgUEoO_ZFel7[gGm^^6QSecfHaMcc\=>000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "00000000000000000000000000egWOlIFOmEYF000000V1SD?g6YJ100000H"
    A$ = A$ + "6lATN[5k[_:e200000cXAji\ZEeb8m<WejJi[nZ]9U_N==Be200000c:mo[_"
    A$ = A$ + "S5mXF6YWi^AZFPEaoo7_>mG_Ze2000`\JTjcB[ZUAZWC]^F6YWi^ND;KKc[n"
    A$ = A$ + "_]lHo8D;[P?no7#g\o[Mf_o<E;oMKniWO;d_^UiO0Z5000PIg8mcII[ZUE_o"
    A$ = A$ + "GKKoLnjeN<XUeb8ec]ND;K=Gi_e`^WeZSoNeF[[U_jUdOncOn7KmFjhok]OM"
    A$ = A$ + "m?fgnJi_kSMmH;h_^QiO4Z500PigKHmO#]=BW[iio[^ebofKQ?giSMniG_ni"
    A$ = A$ + "^mebgKk[o_];o][FnhOfPOn3OmOneG[Ai_eebnnZMVFgo_FE;SD?g6YJ100H"
    A$ = A$ + "n=2mNK4ZQoIo=0om]C;[QHk[N<>dcJacoGO7;JI]lcWYX?Sd[Q?KB?#jA]lm"
    A$ = A$ + "cGeW9nO[OnKI]\O<oH?ff[e7oKE]\oi[kZn]e^So][FnacGhWogeGfgc]]fa"
    A$ = A$ + "fhlgkJ100F=kGSI?j3#?goQFgM?cOG63f]T[FWmND3afGmHLH4ZUAXgO]^FR"
    A$ = A$ + "]O6Q?oGSJiHoffL\OK7ojeHMgmXF2e_a[n_]:o]XF>fWYDjiF;bO[ZUSold^"
    A$ = A$ + "OKOloM]oi0^7eb_oI=nhcMk?oe]<om\F0PeffL]kilokij`Fml_Zni?[A]kW"
    A$ = A$ + "mYAHookmm8ToFocOFOokKkFG3afGQnj=9k=^FniiIWmcOIKokonFE;W_OniG"
    A$ = A$ + "_=i_=ebaN^laQN[4k[gRnodRJAoonmcIfEmK[E7oKA]lkN>M^ffo[jG;[Nn1"
    A$ = A$ + "02iS5_oG[NnGAKc]jW[aX3omoB7foQfgS#nKE=lSiEOh__MJMnKE=lgak0k["
    A$ = A$ + "#OmF<ngbJ9dj^?_o;]il_FE;QjkbIkoVmi_6D;OO]V`?O=Wme[fin=\F>^]_"
    A$ = A$ + "ZWK]<o]XFRmi]cjgF;koG][UHkc[dblGcJIec?iLlYmomOcXHkN>cjn;US5m"
    A$ = A$ + "hho8<68o]k?koN^?3G3OOLXmi_?kkSe`nok:\_oNooKcnn?fj?kmjOKano\e"
    A$ = A$ + "NgklgRJhhl_Sf3Z6UoFD3Ge[aHOmZol?dXJi\n]]Yg[o[Veba?_5Jo4j[GoW"
    A$ = A$ + "oUfD;o^gJOoO_j[G[lgbJiWKkddVlgVJi\N^Le_G=?o_Eeb8ec9moKLZU#eF"
    A$ = A$ + ";W3N_GkKhJZe?okSAno^NjacoOO73jaj`kmJokM]<JiOomOKI?8Jin<N=lma"
    A$ = A$ + "QfWof__?F3mjN]mJOOfn_gi_5kOmokgk_A8o]X6do?mo;fiKmNmOeZFneiKA"
    A$ = A$ + "kahLocoj?Gcajmlo]O\lZog]khOm[5moKLnI>]7ebZWoD[[SGgI6fGiNLIkn"
    A$ = A$ + ">]HnO]HOUKmdjlgkaPOO\XWokOEOk1d:WoFL_oN^??[6>NLXUi_ekkH73JaL"
    A$ = A$ + "O7QmmIWoekco]o[on?Umm8ToF<okoIOXoOAojEOm?M\oOajcB[?o[5eB?jid"
    A$ = A$ + "8E;aFcm_?6d_eoGcJiZiKdbiQdSJi\mAXaoFoioJG;7??:UoK[>o_5ebZWoD"
    A$ = A$ + "[[SGgM6fGiNLiS5^oOenJOmJoUK]dSlg[aPOO^Xno]27o_J=hmLmo]HLh\k3"
    A$ = A$ + "gblg[keOL>W7WoIKnl_mO[goQfgane]<o]Z6nmnjojedOO>TkAn[K=lcmggk"
    A$ = A$ + "[ON=gOF3]Il_=eB\[anmhmWojg[5i_Eeb_6c?\O>k[GmSo=ZF^J>7SdlOZA]"
    A$ = A$ + "8oQFci?oI?YWi_feba[kTbo]fi_UebZWoDZY?do_^lioNWo`G?BooVYmiEeb"
    A$ = A$ + "fmMnnoZoOcdn<eJH4VoG[^OgZVo#c_Xgcoan_=koAH>Wm\6nMO6fogele]g7"
    A$ = A$ + "mZ6fOof?nA_enlR_N=7oKG]4KnV7G3B;^>L?ZU#W_Mll\HOmFL^O[ZU#S[]j"
    A$ = A$ + "OgG7QJAn3gg]A9oe^F^JNWm>oe^FFmlWB=]IVfGSH==JiOOmdjlgkaPSeB?b"
    A$ = A$ + "O?73nN>GOoOWamiIeB[FkK?gWWE37k1a<__?F3Sdmo7UiNdRnOHognmo8<_c"
    A$ = A$ + "NF3kgg7G_enOM[bO;ZQmmL;dn:nG_^mo[EebIG[MomNJmiO]ZFniiK[g?o[Y"
    A$ = A$ + "<ngbkofcJAnUOiOMc?07mel\goOWemIlJYmmQMLjmk7ojom\__3M<XW7okan"
    A$ = A$ + "^Wck`n_OkoAHNWm\6FalWJ?G7QaoJD;boJWoSkoHmL\FINTZ5iGnUoe=o00\"
    A$ = A$ + "^2eoaNgoCkof\oS]_7QlgZn_]Jio\mg8=nG[JAnGklOF=Dkl>ReRl;obojVO"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "000000000000000000000000000000000000000000000000000H>lo1lf0]"
    A$ = A$ + "%%%0"
    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$)
    _MemPut m, m.OFFSET, btemp$: _MemFree m
    BASIMAGE1& = _CopyImage(v&): _FreeImage v&
End Function

Print this item

  _OpenFile Dialog in same folder as exe
Posted by: bplus - 12-04-2022, 08:28 PM - Forum: Utilities - Replies (16)

I want the DefaultPathAndFile$ where my exe is.

_StartDir$ sure didn't get it, that's my QB64 exe folder

_Cwd$ works if I have been in folder for awhile but sometimes seems to be wrong when just starting cold.

So I am trying this:

Code: (Select All)
Function ExePath$
    Dim As Long t1, t2
    t1 = _InStrRev(Command$(0), "\")
    t2 = _InStrRev(Command$(0), "/")
    If t1 > t2 Then ExePath$ = Left$(Command$(0), t1 - 1) Else ExePath$ = Left$(Command$(0), t2 - 1)
End Function

Look alright?  I add forward slash in case of Linux, Windows doesn't care. It seems to be working for all the tests I gave trying to get out of _CWD$

Print this item

  Day 024: LCASE$
Posted by: Pete - 12-04-2022, 05:17 AM - Forum: Keyword of the Day! - Replies (12)

Not much to say here. LCASE$ just converts any uppercase characters in a string to lowercase. LCASE$(mystring$)

The most obvious use for LCASE$ is an input routine...

Code: (Select All)
PRINT "Was this information helpful? Y/N"; ans$
DO
    _LIMIT 30
    mykey$ = INKEY$
    IF LCASE$(mykey$) = "y" THEN PRINT "You darn tootin' it waz ya mangy polecat!"
LOOP

The code above allows the user to type either "y" or "Y" to get a printed response."

Anyway, not much ELSE to see here; besides, it's Sunday, and God takes this day off. Me, I take a 1/2 day! Big Grin

Pete

Print this item

  mini-weapon mixer
Posted by: James D Jarvis - 12-03-2022, 11:20 PM - Forum: Programs - Replies (2)

A cousin to the mini-monster-mixer and robot mixer.  Generates 80 weapon sprites for a rpg/rougelike.
here's a sample run:

[Image: image.png]


Code: (Select All)
'Mini-Weapon-Mixer v0.1
'By James D. Jarvis December 2022
'This program uses BASIMAGE coded by Dav for QB64GL 1.4, MAY/2020
'
'generate a sprite sheet of weapons for use in a roguelike/RPG
'each is 64 by 64 pixels but code here can be modified to change that
'
'press c or s to save a sprite sheet to the clipboard so you can paste it into a paint program
'and save is whatever format you desire
'pres <esc> to quit
'
'License: Share sprite sheets as long as they include generated credit bar in image
'any programs using original code or graphics from source or generated by program
' please include the following (or equivalent) line somwhere in comments and documentation:
'Includes Art and/or Code from Mini-Weapon-Mixer v0.1 created by James D. Jarvis
'
Randomize Timer
Dim Shared ms&
ms& = _NewImage(512, 360, 32)
Screen ms&
_Title "Mini-Weapon-Mixer V0.1"
Dim Shared part&
Dim Shared kk1 As _Unsigned Long
Dim Shared kk2 As _Unsigned Long
Dim Shared kk3 As _Unsigned Long
Dim Shared kk4 As _Unsigned Long
Dim Shared kk5 As _Unsigned Long
Dim Shared kk6 As _Unsigned Long

Dim Shared clr~&
part& = BASIMAGE1&

Type weapon_type
    style As Integer
    pole As Integer
    rhead As Integer
    chead As Integer
    lhead As Integer
    blade As Integer
    handle As Integer
    fgard As Integer
    k1 As _Unsigned Long
    k2 As _Unsigned Long
    k3 As _Unsigned Long
    k4 As _Unsigned Long
End Type
Dim Shared weapon_limit
weapon_limit = 80
Dim klrset(12, 3) As Integer
Dim Shared wlook(weapon_limit) As weapon_type
_Source part&
'read the colors from the color reference bar whichever color is in the top left corner will be transparent
clr~& = Point(0, 0) 'find background color of image
kk1 = Point(0, 1): kk2 = Point(0, 2): kk3 = Point(0, 3): kk4 = Point(0, 4)
_Dest part&
Line (0, 0)-(0, 8), clr~& 'erase the color reference bar from the bit map
_ClearColor clr~&, ms& 'set background color as transparent
_ClearColor clr~&, part&
_Source ms&
_Dest ms&
Do
    Cls
    mmx = 0: mmy = 0
    For m = 1 To weapon_limit
        'create a new set of weapon sprites
        wlook(m).style = Int(1 + Rnd * 20)
        '1- pole only
        '2 - pole and chead
        '3 - pole chead,rhead
        '4 - pole chead,rhead and lhead
        '5- pole rhead and lhead
        '6- pole and rhead
        '7- sword and handle
        '8- sword , handle, and foregarde
        '9- sword and pole
        '10- sword, pole and foregarde
        '11- sword, pole and  lhead
        '12- sword,pole lhead and rhead
        Select Case wlook(m).style
            Case 1
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = 0
                wlook(m).handle = 0
                wlook(m).fgard = 0
            Case 2, 18
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = 0
                wlook(m).chead = Int(1 + Rnd * 20)
                wlook(m).lhead = 0
                wlook(m).blade = 0
                wlook(m).handle = 0
                wlook(m).fgard = 0
                wlook(m).style = 2

            Case 3, 13, 19
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = Int(1 + Rnd * 20)
                wlook(m).chead = Int(1 + Rnd * 20)
                wlook(m).lhead = 0
                wlook(m).blade = 0
                wlook(m).handle = 0
                wlook(m).fgard = 0
                wlook(m).style = 3

            Case 4
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = Int(1 + Rnd * 20)
                wlook(m).chead = Int(1 + Rnd * 20)
                wlook(m).lhead = Int(1 + Rnd * 20)
                wlook(m).blade = 0
                wlook(m).handle = 0
                wlook(m).fgard = 0

            Case 5, 20
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = Int(1 + Rnd * 20)
                wlook(m).chead = 0
                wlook(m).lhead = Int(1 + Rnd * 20)
                wlook(m).handle = 0
                wlook(m).fgard = 0
                wlook(m).style = 5

            Case 6, 14
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = Int(1 + Rnd * 20)
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = 0
                wlook(m).handle = 0
                wlook(m).fgard = 0
                wlook(m).style = 6

            Case 7, 15, 16
                wlook(m).pole = 0
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = Int(1 + Rnd * 20)
                wlook(m).handle = Int(1 + Rnd * 10)
                wlook(m).fgard = 0
                wlook(m).style = 7

            Case 8
                wlook(m).pole = 0
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = Int(1 + Rnd * 20)
                wlook(m).handle = Int(1 + Rnd * 10)
                wlook(m).fgard = Int(1 + Rnd * 10)

            Case 9, 17
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = Int(1 + Rnd * 20)
                wlook(m).handle = 0
                wlook(m).fgard = 0
                wlook(m).style = 9

            Case 10
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = 0
                wlook(m).blade = Int(3 + Rnd * 18)
                wlook(m).handle = 0
                wlook(m).fgard = Int(1 + Rnd * 10)
            Case 11
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = 0
                wlook(m).chead = 0
                wlook(m).lhead = Int(1 + Rnd * 15)
                wlook(m).blade = Int(1 + Rnd * 20)
                wlook(m).handle = 0
                wlook(m).fgard = Int(1 + Rnd * 10)
            Case 12
                wlook(m).pole = Int(1 + Rnd * 20)
                wlook(m).rhead = Int(1 + Rnd * 15)
                wlook(m).chead = 0
                wlook(m).lhead = Int(1 + Rnd * 15)
                wlook(m).blade = Int(1 + Rnd * 20)
                wlook(m).handle = 0
                wlook(m).fgard = Int(1 + Rnd * 10)
        End Select

        wlook(m).k1 = _RGB32(Int(80 + Rnd * 150), Int(80 + Rnd * 150), Int(80 + Rnd * 150))
        If Rnd * 6 < 2 Then wlook(m).k1 = _RGB32(Int(80 + Rnd * 150), Int(80 + Rnd * 120), Int(80 + Rnd * 50))
        kk = Int(155 + Rnd * 100)
        vk1 = kk: vk2 = kk: vk3 = kk
        Select Case Int(Rnd * 10)
            Case 1
                vk1 = Int(vk1 * .8)
                vk2 = Int(vk2 * .9)
            Case 2
                vk3 = Int(vk3 * .8)
                vk2 = Int(vk2 * .9)
            Case 3
                vk1 = Int(vk1 * .8)
                vk3 = Int(vk3 * .9)
        End Select
        wlook(m).k2 = _RGB32(vk1, vk2, vk3)
        wlook(m).k3 = _RGB32(Int(vk1 * 0.7), vk2 * (0.7), Int(vk3 * 0.7))
        kk = Int(150 + Rnd * 100)
        wlook(m).k4 = _RGB32(kk, kk, Int(kk / Int(1 + Rnd * 10)))

        draw_weapon mmx, mmy, m, 1
        mmx = mmx + 32
        If mmx >= _Width Then
            mmx = 0
            mmy = mmy + 64
        End If
    Next m
    md$ = "Weapon Sprite Sheet generated " + Date$ + " at " + Time$
    md2$ = "Mini-Weapon-Mixer V0.1 by James D. Jarvis"
    _PrintString (0, 321), md$
    _PrintString (0, 337), md2$
    Do
        _Limit 60
        kk$ = InKey$
    Loop Until kk$ <> ""
    If kk$ = "C" Or kk$ = "c" Or kk$ = "S" Or kk$ = "s" Then
        _ClipboardImage = ms&
        _Delay 0.3
        Locate 1, 1: Print "Sprite Sheet Saved to Clipboard"
        Sleep 3
    End If
Loop Until kk$ = Chr$(27)
_FreeImage part&
System


Sub draw_weapon (Mx, my, mid, scale)
    'generate a monster image from source sprite sheet part& and render to the programs main screen ms&
    tempi& = _NewImage(32, 64, 32)
    'tempi& creates a temporary one sprite image for rendering
    _ClearColor clr~&, tempi&
    _Dest tempi&
    Cls
    'Locate 1, 1: Print wlook(mid).style
    Select Case wlook(mid).style
        Case 1 To 6
            _PutImage (0, 32)-(31, 63), part&, tempi&, ((wlook(mid).pole - 1) * 32, 64)-((wlook(mid).pole - 1) * 32 + 31, 64 + 31)
            If wlook(mid).rhead > 0 Then _PutImage (0, 0 + 16)-(31, 31 + 16), part&, tempi&, ((wlook(mid).rhead - 1) * 32, 32)-((wlook(mid).rhead - 1) * 32 + 31, 32 + 31)
            If wlook(mid).lhead > 0 Then _PutImage (0, 0 + 16)-(31, 31 + 16), part&, tempi&, ((wlook(mid).lhead - 1) * 32, 96)-((wlook(mid).lhead - 1) * 32 + 31, 96 + 31)
            If wlook(mid).chead > 0 Then _PutImage (0, 0 + 16)-(31, 31 + 16), part&, tempi&, ((wlook(mid).chead - 1) * 32, 0)-((wlook(mid).chead - 1) * 32 + 31, 0 + 31)

        Case 7, 8
            _PutImage (0, 0 + 24)-(31, 31 + 24), part&, tempi&, ((wlook(mid).blade - 1) * 32, 128)-((wlook(mid).blade - 1) * 32 + 31, 128 + 31)
            If wlook(mid).handle > 0 Then _PutImage (0, 0 + 24)-(31, 31 + 24), part&, tempi&, ((wlook(mid).handle - 1) * 32, 160)-((wlook(mid).handle - 1) * 32 + 31, 160 + 31)
            If wlook(mid).fgard > 0 Then _PutImage (0, 0 + 24)-(31, 31 + 24), part&, tempi&, ((wlook(mid).fgard + 9) * 32, 160)-((wlook(mid).fgard + 9) * 32 + 31, 160 + 31)

        Case 9 To 12
            _PutImage (0, 32)-(31, 63), part&, tempi&, ((wlook(mid).pole - 1) * 32, 64)-((wlook(mid).pole - 1) * 32 + 31, 64 + 31)
            If wlook(mid).rhead > 0 Then _PutImage (0, 0 + 16)-(31, 31 + 16), part&, tempi&, ((wlook(mid).rhead - 1) * 32, 32)-((wlook(mid).rhead - 1) * 32 + 31, 32 + 31)
            If wlook(mid).lhead > 0 Then _PutImage (0, 0 + 16)-(31, 31 + 16), part&, tempi&, ((wlook(mid).lhead - 1) * 32, 96)-((wlook(mid).lhead - 1) * 32 + 31, 96 + 31)

            _PutImage (0, 0 + 13)-(31, 31 + 13), part&, tempi&, ((wlook(mid).blade - 1) * 32, 128)-((wlook(mid).blade - 1) * 32 + 31, 128 + 31)
            If wlook(mid).fgard > 0 Then _PutImage (0, 0 + 13)-(31, 31 + 13), part&, tempi&, ((wlook(mid).fgard + 9) * 32, 160)-((wlook(mid).fgard + 9) * 32 + 31, 160 + 31)
    End Select


    _Source tempi&
    'repaint source image with generate color values for new monster sprite
    For y = 0 To 63
        For x = 0 To 31
            Select Case Point(x, y)
                Case kk1
                    PSet (x, y), wlook(mid).k1
                Case kk2
                    PSet (x, y), wlook(mid).k2
                Case kk3
                    PSet (x, y), wlook(mid).k3
                Case kk4
                    PSet (x, y), wlook(mid).k4
            End Select
        Next x
    Next y
    'generated image in tempi& is rendered to ms& as a 32 by 64 sprite

    _PutImage (Mx, my)-(Mx + 31, my + 63), tempi&, ms&
    _Source ms&
    _Dest ms&
    _FreeImage tempi&
End Sub

'================================
'PNG file saved using BASIMAGE1&
'================================
Function BASIMAGE1& 'weapon_pieces.png
    v& = _NewImage(640, 192, 32)
    Dim m As _MEM: m = _MemImage(v&)
    A$ = ""
    A$ = A$ + "haIkM_ULLLT\504KB\9aV4SeD:=F<Ie?dH\RC`>l?LkBaiJjTIT?ZX[6TjS?"
    A$ = A$ + "nhk?000VS?o:oH00h5mmgO6O<0o]ci8nKUm^cfTGo_=gC?oCVoGO=keOh?QK"
    A$ = A$ + "WSB?6PoOhnoIKb[oMYo?m0>?km<DI?4g;[Z63Yco?Mmof9hZ6g_KLgCfJOjW"
    A$ = A$ + "o#nm0Y73Y\jm9I=8mI`>D3VVKelcjoXRnOfcIoGGeHhIoj:73EWMWTnLOjlW"
    A$ = A$ + "\d?kY3[obO^?koH_?YZ17cG?PiZmEG_k#oO[OmnoL5SQWm[OG[oMBjkMFSQd"
    A$ = A$ + "eQYjF]?mgoCjeoYWOjeodgiV^gW>d3J7639Vc;E>_gkijIonGeHh\<ClmoFM"
    A$ = A$ + "oOgK^FM=X3BOgg=CinV>:MoOYOVCjl?>6BUOjk0BOOK7VoMHOHjj#RikN?PE"
    A$ = A$ + "WoSnW[:kD_o]TiW^ng5Mh<o4[k7U^gSdmo=il_Y3iWlNPdWoCO7hTko;mn^M"
    A$ = A$ + "EWoSnW[:KmoEOfMAjknVJMo8moU9oenndW1jBnYN78Yoi^Y;eoY=6Bmm_N_a"
    A$ = A$ + "#Z\goeEUmcne_ci__fWn>XDBm^__gNQY9mmnjoCoO[cO9oiPGoOcZo_mnnB>"
    A$ = A$ + "oC]g;Io7WUMUSQdiOfh8aNPddoGFC^o[d[o[ilanOB>oCWORa#7^oEoOeG3f"
    A$ = A$ + "OVo4koCnb_3B?oCVOjkMCgoEjlC_n;olWoj`n_9ekE7bo\NoB]?HbWoTOnlC"
    A$ = A$ + ";mON_BnnOBoM?TniOYc?ij_lcVO7nngComOT>oeH8m?kMYoI`;mkO>Efb?oJ"
    A$ = A$ + "odn\OM8okmcNbdnn_T_lCn\gdOn[9GoU_lUOnlWHoGYco\O^CBg7jTZobGnM"
    A$ = A$ + "iWm[YFoU_lU_lWHnWmcORnoT_l[=Kmo9Oi;Oi;oZcEoObGnjoKZeOi;OiW?o"
    A$ = A$ + "dOocC=oSIgQa`dZobGnbGnbGnC=Obbj?0000000000000000000000000000"
    A$ = A$ + "0000000000000000000000000000lgU_onchS1POUcU0`Ej[_nWWehi=#O<m"
    A$ = A$ + "cS9VoC_V3<;7kocmO#?<mcSYjoKbeLPIiFoO;^k3jQYg;BZiod[k0canko[C"
    A$ = A$ + "gm]gKJW6KDW9^fgacSCI=OZeLPIYSmHML<eYa5e_78eW=9mn]^doGbN`l>01"
    A$ = A$ + "hjdagoWNoV]cjo_ja#jmMMhlHjg1GjnoL_3<7ClW1^TmoM<kmWi[g_gOgK=n"
    A$ = A$ + "\m0GaNQ7mWmY:fkm:iOUS1iOnj\nonej#ja1DUYe3Hb_W]WeoGjg1dEKj?Wi"
    A$ = A$ + "EGo_ZJdjOgEW[lkOnMiLIRaAWZ1MH<#>[mREWgDfc]GOkDoOELooSbm:cN_O"
    A$ = A$ + "k^]O[jgoEbno>>6>KmYRiOjgoedc_j\_GnEnIOOUl[^nWNnGY7MoGeig]iO5"
    A$ = A$ + "eRGYoSZ[oE^?XC[okonEd3hmZoEdKfnl[CWoGSWD?omNmRoWN\Xo?igUnoNf"
    A$ = A$ + "Wo9AnEFokfl_C[oC=o[\fO_l[hIoM\nOeejkUoIcaZ>;nOYo_[XgSEF?J]?m"
    A$ = A$ + "WoiZkonEGo_ji_noVMnEWmNnM[oW[>KcoO?omkR>>^BFoCWOZmOENnoh_GEm"
    A$ = A$ + "0W^o_GIlMUm0n:eo[J_`nlZbemcVo?Zg_4k?ZHLl\n_[Zo3ig_l[^o_SoN9j"
    A$ = A$ + "oi\lCdoMjioISS:Wo;We7HUiGQG9oZjoL?_:Z9o=DoOWm:goLEeWcj_Y3com"
    A$ = A$ + "J#7fKLU[1Mim?UNm_KcoYlnoNfcg^baamb_ZcoMMnOfNTdco[X?XZOO3o=TO"
    A$ = A$ + "U?c[Sco9iN_gQ:oloMMmO2k;fGc?noFe[o9Ze_bl_ZWoW>oZc^kVnk6HO?Bb"
    A$ = A$ + "a`Eeo7onJmdg_3hIOYk1Z;iWNM89??\?eQ[jk060nEY__?]dmoT>o^<6BKjc"
    A$ = A$ + "o>E7j`H00N_U^gWdigUa0mPm10`4TniMYcohhX;S500h:U^WWdigea200000"
    A$ = A$ + "000000000000000000000000l0One?58o_njWVhl?MnZoc^n;Oi;Oi;oIVod"
    A$ = A$ + "OnGjiObl_EcGogF`HogH`1GoG[1[eQ8co?bVOjcobOfiOKOObmoYc?MmGnc^"
    A$ = A$ + "oWY?oCgog^9=ok#nY_oOUojGGMnY?o;oIWOjcOYWobOfiWniOCOnW>OeOmo]"
    A$ = A$ + "f7DeHHoM>GmkQFnIcoXdgoTllgN=?I?X9WkkkoZN<L<o4eQXOo?3^oSdOoWC"
    A$ = A$ + "?oO#oOaonO?n>0[bI_ki:_7#nIco\aAUi^TnlGjioJ<TZf?mn_BWOjWoU^o_"
    A$ = A$ + "^Lgg4co7doGlnoFk5BUkTonGVDnW]7oAiGaIRYonoVdn?iOR1goWiOnlCGoC"
    A$ = A$ + "WOjno>nI`CTOjmOb_^l?kmlLFnE^WLBeo7=6BUM7joNb_oad?o;mkoKbOo[Y"
    A$ = A$ + "co7doG\mok?7nMom?Tnm?U>odeoE>_b?oQE^W8icnSOok7c]o?ioAlWoU^o_"
    A$ = A$ + "9om_V>oOHhmoMlIREWm:cejnkNoOWeWamjoh:NoCYcoD5_oo\kL^Wg]mObGn"
    A$ = A$ + "M;o^ll?co<codiW^nW>odOn_diWlim9jo8MnoV#koS?_oGYOgKYcO]FTL^Ol"
    A$ = A$ + "co<YlGS1_o_IfoaIO^o9UOjjO7b?nio?bocNdTol?Yc?mnodiW^nW>oeH8Ef"
    A$ = A$ + "Y_oKji?mcOYkocgok\OnCjcoY?o9oiNoG7b?mkO;MnYgo9oIOnOjcOi?klCg"
    A$ = A$ + "oGjiOjcoYc?MmOjiWNm?Mn[a#Z\WNn^ogm_bO^iWl?o_MHnWnlOjlCGoWNnY"
    A$ = A$ + "OoKYcoV9goEjleoWkOUoLcO]ggio0cm6TOjjodc?mj_lUoT_oIjcOi?klmio"
    A$ = A$ + "LokTgoW>od_o]diOcTOoKYcgmo^oEnc=OWoeogTgoW>od[oYcO=6BUmdcgmo"
    A$ = A$ + "^oEnc=OWo7ncO7nnodiWnm_U>odkoUo\_oIjcOi?kleoWkOWlnodiWNm?Mn["
    A$ = A$ + "a#Z\WNn^ogm_bO^kolWogQolgQOn;MnYOoKYcoV9goEjleoWkOUOfmOMhkOa"
    A$ = A$ + "io0cm6TOjjodc?mj_lUoT_oIjcOiWOoGj?o_noLokD?oU>od_o]diWNo_loi"
    A$ = A$ + "c0BTOjcOY[oYWobOfkodoGnkOMocLc?mj_lU_noLo[lmnoVJm?mm_^oI^iWn"
    A$ = A$ + "lGjmObOfiWnlgdWoC?od[ojocj_kOVKna?oma\oco`dcgkocm_C=oS[mYf3T"
    A$ = A$ + "NoWoloZo_YNn_3i[o?i[o_iNoOjioTc_;moimo=gcoYc?MmOji7olg7c^o7i"
    A$ = A$ + "7>oQOoOjioTcGoOoLN[o_0cm6TOjjodcGoObOdi?lkoC?oWNnYGoWNnFoWMm"
    A$ = A$ + "OjiWNmGnb?jm?#Hfk30000000000000000000d39okN=HBLF30BKmgkfnko7"
    A$ = A$ + "X6C_o_^<okbh0PZ]jmCoO#=BnOWSjR><o]>0<I[nnlgmm#=VNO7MHngQa00Y"
    A$ = A$ + "LlMoME_o_SokF?VcTWenkeR9G?j`l?Mn0TDEmVMF>j3L6>kcHdUen4m0T^o_"
    A$ = A$ + "dmmTNnOL<T\>0#BElnofcBoOcDgjo?E?0Yko9M_?MIn[o?HfVnOV7Z\o_Si]"
    A$ = A$ + "g7`RkUOoL_gognN]ZGogcjHnGiHhNI8onTO5koBhMOn1_:mnmJ?Gn?I]nIVl"
    A$ = A$ + "mC_c_GRWegOe[o?JlDEo7?[>T:odcoTiOUIgQcf9oI`X3cObY3OW?;MkW3YD"
    A$ = A$ + "ePmgoaEGCBOgoaa`S67YF;ZlmOTHne]nolnoToIiOEinXkJZZggDigQioSDM"
    A$ = A$ + "nMkmODAnMhnodmO<emo?km<FEnkmoUZnO_mNE]6Deco>[VWHmoNSYcb?Mo7b"
    A$ = A$ + "O>moeUgmi4Vo?[6l^goCjlOfhXbcnW]?H:eok=f^Zl_gI^kEKZHM?AoO_jjo"
    A$ = A$ + "E^6dYko[JmoAeRcFoCgoQleoGRaPioeUoa<fg[GInC_ocD?okNePSon_SmoM"
    A$ = A$ + "F?7E?gNdJNZjoSjmkZko[b?okmb]jm0?K?IU?3jEN>DZlC?oCVORnOFo_WJ^"
    A$ = A$ + "GEnMHnoXW1MUiOFOOEVooUahEgoIZl?j\W3m^GokNnE\VoXg1EbiO5mo]Z1g"
    A$ = A$ + "k>`[Lng]mEWEWgG3B_7Xbi^l[YoW7m_k:nla?kloEVOjioJ^GMn_jW]8ik7I"
    A$ = A$ + "Ri__OHJco^UOENUgobkLmoAOng9\n__?X;ePZf3nXnOTokmnoSgmUN\D]dW["
    A$ = A$ + "kdWoUoaD?;0CGgNWTE?_C=gkBnYG7B=gWhckB>_ek70mcD_G>M?#Yb?ml>]Y"
    A$ = A$ + ">gC_G?ml70hVdm1Yo?ZNM?mH00X3Bo<aZcG_O00<MYk5:AoOY[i000000000"
    A$ = A$ + "000000000000000000000`4Tj_OhGogUXYVObJ?00iO>LjN#VJ?HM9oD[md3"
    A$ = A$ + "Cml?iOf3TN?H7^o;M?0C<oSI?mlC\fCNYg3T>oeH8mj`DWkYcWlB_78mM?Om"
    A$ = A$ + "eLoN#Gcmdmo<al?>6BT=I]FkWlm?[a#jeRY>gC_fCFY?ogQWoWZ7Xmn?BD3>"
    A$ = A$ + ">gWfl?MnkSQZcVlBNoc:oY_o?MfM8Ogo<CYGok`M?joKVmOU>omaAR\9_d_o"
    A$ = A$ + "_^doIZjOj\k#nY77CFjeo^LoCR\Cgog:kDePTmoealC?6Z>kDBo<WdiOLLLK"
    A$ = A$ + "m?Mn9ko;icOFSQTIW<o9NgCgTNoWnodoG7jmY3iWN<DMfkZ\>T^7\^TOG^o="
    A$ = A$ + "eH8MoWCM^O<o4ICnmOMjnWDeNmoeSNOj#nY73EWmBZJ#GVg9c?mjoTc?mcOk"
    A$ = A$ + "B]?AfTOoWnodoGGjmY3iWN<DMfg\?oCdoG7Vk9bohjOZiOjmOjo;On9bNEoC"
    A$ = A$ + "UM7<in_BW_nojGoGYc?mHXj\CfkGjiN7bOMf?AfMX6<ikog[m9c_jLgG3BUo"
    A$ = A$ + "J<T<kYfoEjlCOnGoOm;odSQZc^CmoU^fWhlOW^oEoOcJogal[>gmePDi_639"
    A$ = A$ + "c^;WoWFnY?o[o_nUOja#eIWLNgaeo4eod_3bdkoVjmoken9goGbn?BWoDko:"
    A$ = A$ + "MnY?o[o?i_?6BUMRiM7ZoYc?mJ#jnOfG3ZLNOfmoYOogYb?ajnnj`Dc_;WoW"
    A$ = A$ + "Fnjo;ocoVNnkSQDIWHNgQjOjlGWmCEog[1C9Omom[iWHMOOM8EnC]oWYW_no"
    A$ = A$ + "bol_YWonH8Ef9VgMXnWnkn\Cgo>Ymojo;G]oN[3Yb_;WoTOmIgQnoFBol_YW"
    A$ = A$ + "OeIgQa#jiodGoWJoGW=oCTMjj_mojoCnc=oSmoU:oYn\W>Toaa`4WoMiiOYF"
    A$ = A$ + "kC?6BOogdcOjWodoWlCOn;MoGb?OnCNoGGNnCblCTMGFoWLn[a#jeoTiWnco"
    A$ = A$ + "200000000000000000000000000000000000000000000000000000000000"
    A$ = A$ + "00000000000000000000000000ekk_olod_?0lWcWohffOEUioeGo^DckTe1"
    A$ = A$ + "HJdo70IU^WWZkmkNcMmm1eAoO0TEjNOBfoG7VoDojmObook_]lGokn\mlENF"
    A$ = A$ + "#oO0TEjnOVNoO[LWBngkM^FekRMjiOfhh\oi[f:]Wmk10GSdmodQno^UMbn_"
    A$ = A$ + "Z\n_WeIiOemol:cogelC_ngYl?f_WNo0NWmZgeVhM0<YolO\G3BeoGbjoIIW"
    A$ = A$ + "H?`TkoAnolkk=F_OOne?=\lCOfOO<<]ioDcoA?k9EO?C:O0hSAgoG[b?mjOC"
    A$ = A$ + "bgWoFn0#1BoloeHHZiW^ng\lSd7`Tgo9O0VYd?oO=6VJnY[o=;Omo9O0X0YO"
    A$ = A$ + "noJ<<elCGoKFnjoCn0#1BoloeHHZiW^ng\leoWl1P2Tnio[a`Dc?Mm_Ai7k?"
    A$ = A$ + "30CNoWl10XHncoI`nNU?004AbnOBgoMjl10P9:I_OWmo50000000P?nnoaJo"
    A$ = A$ + "%%h1"
    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$)
    _MemPut m, m.OFFSET, btemp$: _MemFree m
    BASIMAGE1& = _CopyImage(v&): _FreeImage v&
End Function

Print this item

  Tough to ID key sequences...
Posted by: Pete - 12-03-2022, 08:38 PM - Forum: General Discussion - Replies (4)

One ID key sequence toggle tough to identify is Ctrl + Ctrl -. It is often used in browser to enlarge or decrease text size.

I love INKEY$ but it is worthless for this one. When Ctrl is held using a PEEK routine to identify it, the + and - keys simply do not get picked up by INKEY$. Now with Windows API we can accomplish this with...

Code: (Select All)
CONST VK_CONTROL = &H11
CONST VK_OEM_PLUS = &HBB

CONST VK_OEM_MINUS = &HBD
CONST VK_ESCAPE = &H1B

DECLARE DYNAMIC LIBRARY "User32"
    FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
END DECLARE

DO
    _LIMIT 30
    IF GetAsyncKeyState%(VK_CONTROL) AND GetAsyncKeyState%(VK_OEM_PLUS) THEN
        PRINT "Ctrl +"
    END IF
    IF GetAsyncKeyState%(VK_CONTROL) AND GetAsyncKeyState%(VK_OEM_MINUS) THEN
        PRINT "Ctrl -"
    END IF
LOOP UNTIL GetAsyncKeyState%(VK_ESCAPE)

But what about x-platform methods?

Well, here is my shout out to _KEYHIT using Ctrl+ and Ctrl- to change font sizes...

Code: (Select All)
SCREEN 0
fontsize% = 16
style$ = "monospace"
fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf"
DIM font(8 TO 32) AS LONG
FOR i = 8 TO 32 STEP 2
    font(i) = _LOADFONT(fontpath$, i, style$)
NEXT
_FONT font(fontsize%)
ww = 600: wh = 350
WIDTH ww \ _FONTWIDTH, wh \ _FONTHEIGHT
PALETTE 7, 63: COLOR 0, 7: CLS
_FONT font(fontsize%)
_SCREENMOVE 0, 0

PRINT "Press ctrl + to increase font size or ctrl - to decrease."
DO
    _LIMIT 30
    c = _KEYHIT
    IF c THEN
        SELECT CASE c
            CASE -189
                IF fontsize% > 9 THEN fontsize% = fontsize% - 2: resizeit fontsize%, ww, wh, font()
            CASE -187
                IF fontsize% < 31 THEN fontsize% = fontsize% + 2: resizeit fontsize%, ww, wh, font()
        END SELECT
    END IF
LOOP

SUB resizeit (fontsize%, ww, wh, font() AS LONG)
    _FONT font(fontsize%)
    fw% = 0: fh% = 0
    DO
        fw% = _FONTWIDTH: fh% = _FONTHEIGHT
        IF fw% <> 0 AND fh% <> 0 THEN EXIT DO
        _DELAY .1
    LOOP
    WIDTH ww / fw%, wh / fh%
    PALETTE 7, 63: COLOR 0, 7: CLS
    _FONT font(fontsize%)
    DO: LOOP UNTIL _SCREENEXISTS: _SCREENMOVE 0, 0
    PRINT "Font size changed to:"; fontsize%: PRINT: PRINT "Window width:"; _WIDTH
    _KEYCLEAR
END SUB

Pete

Print this item

  Day 023: INKEY$
Posted by: Pete - 12-03-2022, 07:18 PM - Forum: Keyword of the Day! - Replies (1)

INKEY$ is one of several methods to communicate with the keyboard. Others are _KEYHIT, _KEYDOWN, INP(), PEEK and POKE, and for Windows users, the function GetAsyncKeyState%.

So why is INKEY$ so much better than those other choices, why because I code with it, of course!

Well, my comedy bit aside, INKEY$ is comfortable for me because it has easily recognized key associations, by string representation of ASCII values.

Terminate loop with the Esc key example...

Code: (Select All)
DO
_LIMIT 30
LOOP UNTIL INKEY$ = CHR$(27) ' The string character for ASCII code 27.

Since INKEY$ functions as a string, unlike the other alternatives, we need recognize a string is true or false by being either filled or null.

Terminate loop with press almost any key...
Code: (Select All)
DO
_LIMIT 30
LOOP UNTIL LEN(INKEY$) ' Loop exits when INKEY$ is no longer null, (e.g. INKEY$ = "").

I find the best way to set up a keyboard poll routine is by assigning a variable to INKEY$...

Code: (Select All)
DO
    _LIMIT 30
    mykey$ = INKEY$
    IF LEN(mykey$) THEN
        SELECT CASE mykey$
            CASE CHR$(27)
                PRINT " INKEY$ CODE: CHR$(27)"
                EXIT DO ' Escape loop to end program snippet.
            CASE ELSE
                show_Values (mykey$)
        END SELECT
    END IF
LOOP

SUB show_Values (mykey$)
    SELECT CASE LEN(mykey$)
        CASE 1
            b = ASC(mykey$) ' ASC() converts a string character to a numeric value.
            a$ = ""
        CASE 2
            b = ASC(MID$(mykey$, 2, 1))
            a$ = "CHR$(0)" ' This is the nul character INKEY$ reports for 2 byte length key representation like the F1 - F12 keys.
    END SELECT
    b$ = LTRIM$(STR$(b)) ' This is how you convert a numeric variable to a string variable.
        PRINT " INKEY$ CODE: ";
        IF LEN(a$) THEN PRINT a$; " + ";
        PRINT "CHR$("; b$; ") "; "AKA: " + CHR$(34) + CHR$(b) + CHR$(34) + " ";
END SUB

"...press almost any key." WTH is that???

Well, INKEY$ does not register for certain keys like...

Shift
Ctrl
Alt
Fn
Windows key
PrtScr
NumLock
Capslock

These keys need to be referenced in some other either supportive method or via a different key recognition keyword like _KEYDOWN.

An "old school" method I love, and successfully lobbied for 15+ years ago, is the supportive method of using PEEK addresses.

This routine identifies if Alt, Ctrl, or Shift keys are held down while other keys are pressed...
Code: (Select All)
_CONTROLCHR OFF '  Allows us to key input combinations that would otherwise adversely affect screen output.
DO
    _LIMIT 30
    DEF SEG = 0
    IF PEEK(1047) MOD 16 = 1 OR PEEK(1047) MOD 16 = 2 THEN
        KeyCombos = 1 ' Shift
    ELSEIF PEEK(1047) MOD 16 = 3 OR PEEK(1047) MOD 16 = 4 THEN
        KeyCombos = 2 ' Ctrl
    ELSEIF PEEK(1047) MOD 16 = 5 OR PEEK(1047) MOD 16 = 6 THEN
        KeyCombos = 3 ' Ctrl+Shift
    ELSEIF PEEK(1047) MOD 16 = 7 OR PEEK(1047) MOD 16 = 8 THEN
        KeyCombos = 4 ' Alt
    ELSEIF PEEK(1047) MOD 16 = 9 OR PEEK(1047) MOD 16 = 10 THEN
        KeyCombos = 5 ' Shift+Alt
    ELSEIF PEEK(1047) MOD 16 = 12 THEN
        KeyCombos = 6 ' Ctrl+Alt
    ELSEIF PEEK(1047) MOD 16 = 14 THEN
        KeyCombos = 7 ' Shift+Ctrl+Alt
    ELSE
        KeyCombos = 0
    END IF
    DEF SEG

    mykey$ = INKEY$
    IF LEN(mykey$) OR KeyCombos THEN
        SELECT CASE mykey$
            CASE CHR$(27)
                PRINT " INKEY$ CODE: CHR$(27)"
                EXIT DO ' Escape loop to end program snippet.
        END SELECT
        show_Values mykey$, KeyCombos
    END IF
LOOP

SUB show_Values (mykey$, KeyCombos)
    STATIC OldKeyCombos
    IF KeyCombos = OldKeyCombos AND LEN(mykey$) = 0 THEN EXIT SUB ' Neat trick to only print once to screen while PEEK discovered keys are held down.
    DO ' Falx loop to avoid printing INKEY printing if only a non-INKEY$ is held down.
        SELECT CASE LEN(mykey$)
            CASE 0
                EXIT DO
            CASE 1
                b = ASC(mykey$) ' ASC() converts a string character to a numeric value.
                a$ = ""
            CASE 2
                b = ASC(MID$(mykey$, 2, 1))
                a$ = "CHR$(0)" ' This is the nul character INKEY$ reports for 2 byte length key representation like the F1 - F12 keys.
        END SELECT
        b$ = LTRIM$(STR$(b)) ' This is how you convert a numeric variable to a string variable.
        PRINT " INKEY$ CODE: ";
        IF LEN(a$) THEN PRINT a$; " + ";
        PRINT "CHR$("; b$; ") "; "AKA: " + CHR$(34) + CHR$(b) + CHR$(34) + " ";
        EXIT DO
    LOOP
    IF KeyCombos THEN
        SELECT CASE KeyCombos
            CASE 1
                PRINT " Shift Down";
            CASE 2
                PRINT " Crtl Down";
            CASE 3
                PRINT " Shift + Ctrl Down";
            CASE 4
                PRINT " Alt Down";
            CASE 5
                PRINT " Shift + Alt Down";
            CASE 6
                PRINT " Ctrl + Alt Down";
            CASE 7
                PRINT " Shift + Ctrl + Alt Down";
        END SELECT
        OldKeyCombos = KeyCombos
    END IF
    PRINT
END SUB

Cool, right? Well, not so fast there Sparky, there is a drawback. We can only read 3 key inputs at a time. Hold Shift + Ctrl + Alt then press "A" and just like I stated, the 4th input, "A" won't get printed. INP() won't help here either, and interestingly enough, although _KEYHIT and _KEYDOWN can handle most 3 key combinations, I noted some arrow combos and others were not registered when trying to get that technique to work. WinAPI can recognize some but not all 4+ multiple key presses. Fool around with some keys in this example if you have a Windows System. Hold Shift+Ctrl+Alt and try some arrow keys etc to see which ones show up for INKEY$. Some will, some won't, but those are all 4 key press events with this INKEY$ helper.

The only key I set to register in the alphabet is "A" so try Shift+Ctrl+Alt+A to see them all register. Oh, if you fooled with the code to try and get A+B+C+D to register, it would only register A+B+C.

Code: (Select All)
CONST VK_SHIFT = &H10 'SHIFT key
CONST VK_CONTROL = &H11 'CTRL key
CONST VK_MENU = &H12 'ALT key

DECLARE DYNAMIC LIBRARY "User32"
    FUNCTION GetAsyncKeyState% (BYVAL vkey AS LONG)
END DECLARE

DO
    _LIMIT 30
    a% = GetAsyncKeyState%(VK_SHIFT)
    b% = GetAsyncKeyState%(VK_CONTROL)
    c% = GetAsyncKeyState%(VK_MENU)
    d% = GetAsyncKeyState%(&H41)
    SELECT CASE a%
        CASE 0
        CASE ELSE
            PRINT a%
    END SELECT
    PRINT a%, b%, c%, d%, INKEY$
LOOP

So what else can we say about INKEY$? Well, it can be used in combination with other keyboard keywords. Maybe not good practice, but just saying it's workable.

INKEY$ stores key presses in a buffer. You can use _KEYCLEAR to clear that buffer. Some programs need this to stop users who press keys during a program pause from being used in the routine. SLEEP is actually a very simple example...

Code: (Select All)
SLEEP
IF LEN(INKEY$) THEN BEEP ' Will Beep
SLEEP
_KEYCLEAR
IF LEN(INKEY$) THEN BEEP ' Won't beep.

A bit more involved example of the buffer uses a delay to slow the typing output to the screen. With the buffer, Demo 1, the output catches up after you are done fast typing. In demo 2, _KEYCLEAR clears the buffer and the utput stops the moment the user stops fast typing.

Code: (Select All)
PRINT "Demo 1: Buffer will catch up to your typing. Press Es when ready for demo 2..": PRINT
LOCATE , , 1 ' Let's show the cursor for these typing demos...
' That third LOCATE parameter of 1 gives us the underline stype cursor.
' See the LOCATE Keyword of the Day for other cursor appearance options).
DO
    _LIMIT 30
    mykey$ = INKEY$
    IF LEN(mykey$) OR KeyCombos THEN
        SELECT CASE mykey$
            CASE CHR$(27)
                EXIT DO
            CASE ELSE
                IF LEN(mykey$) = 1 THEN
                    PRINT mykey$;
                    _DELAY .25
                END IF
        END SELECT
    END IF
LOOP
PRINT: PRINT: PRINT "Okay, demo two. The printing to the screen stops the moment you stop typing.": PRINT
DO
    _LIMIT 30
    mykey$ = INKEY$
    IF LEN(mykey$) OR KeyCombos THEN
        SELECT CASE mykey$
            CASE CHR$(27)
                EXIT DO
            CASE ELSE
                IF LEN(mykey$) = 1 THEN
                    PRINT mykey$;
                    _KEYCLEAR
                    _DELAY .25
                END IF
        END SELECT
    END IF
LOOP

On a final note, my beloved INKEY$, as stated previously, can't do everything. For instance say you want to use Ctrl + and Ctrl - to resize text, just like browsers. Well, we can't do that with INKEY$, but we can use _KEYHIT or Win32 API. An example of each is provided here: https://staging.qb64phoenix.com/showthread.php?tid=1230

Pete

Print this item

  DAY 023: MOD
Posted by: Pete - 12-03-2022, 06:08 PM - Forum: General Discussion - No Replies

OH HELL NO!!!!!!!!! Big Grin Big Grin Big Grin

Just a spoof. This is in General Discussion, not our KEYWORD board.

The real Keyword of the Day is here: https://staging.qb64phoenix.com/showthread.php?tid=1229

Pete

Print this item

  Remainder(n, d) Better than MOD, same as capping wrapping?
Posted by: bplus - 12-03-2022, 05:22 PM - Forum: Utilities - Replies (13)

Break this? 
For ideal modulus, I imagine it should be between 0 and the divisor = modulus whether divisor is pos or negative.

I read johannhowitzer Wrapping, capping and other... and it all fell in place what we are trying to reach, keeping numbers between 0 and the divisor whether integer or float like Pi, we just want a proper remainder.

Code: (Select All)
_Title "Remainder test" ' b+ for a modulus that always returns a number between 0 and divisor
' if divisor is negative then return a rational between 0 and some rational d < 0
' if divisor is positive then return a rational between 0 and some rational d > 0
' if divisor is 0 ? can't divide by 0
' Do we need to round? Doesn't look like it but I just ran a couple quick tests. Folks here can find fault with anything! ;-))

' NOTE: when testing don't leave space between , and d  eg, do 5,3 not 5, 3

$Console:Only
Do
    Input "0's quit, please enter n, d to find remainder n/d between 0 and d "; n, d
    If (n = 0) Or (d = 0) Then End
    Print Remainder##(n, d)
    Print
Loop

' modeled on MODn
'ref Pete  https://staging.qb64phoenix.com/showthread.php?tid=1195&pid=10983#pid10983
Function Remainder## (n##, d##)
    If d## = 0 Then Exit Function
    Remainder## = n## - (d##) * Int(n## / (d##))
End Function

BTW best toggle I've seen and used often from Chia Pet:
toggle = 1 - toggle

Print this item

  Wrapping, capping, toggling, and slicing, oh my!
Posted by: johannhowitzer - 12-03-2022, 11:24 AM - Forum: One Hit Wonders - Replies (4)

Who knows, maybe everyone out there is already using these things in some form,
but I use them EVERYWHERE and maybe someone will enjoy them!  They're just simple
and common ways to manipulate values, but they will replace multiple lines of code
and make said code much easier to understand at a glance.



Code: (Select All)
function wrap(n, l1, h1) ' n is adjusted back within lower(l) and upper(h) bounds similar to mod operator
l = l1: h = h1 ' make sure h is never less than l, this also prevents division by zero
if h1 < l1 then
  l = h1: h = l1
end if
x = (l - n) / ((h - l) + 1)
if x <> int(x) then x = x + 1
wrap = n + (int(x) * ((h - l) + 1))
end function

This first function wraps a value between two values.  You pass n, and if it's beyond one
of the bounds, it wraps back around.  So say you have five menu options, and the user moves
the cursor to position 6, this will wrap it back around to 1.  Going to 0 will also wrap around
to 5.  It doesn't matter how far outside you go, and negatives are treated properly, so -256
in this example will get wrapped correctly to 4.

The bounds can be in any order, and n is usually going to be a simple addition or subtraction.
So in the case of the above menu example, [wrap(cursor + 1, 1, 5)] will move the cursor, with
the check to wrap around.  And in most menu navigation scenarios, wrapping is super nice for
the user.  So you can write the following:

if [input] = [up arrow]  then cursor = wrap(cursor - 1, 1, [max])
if [input] = [down arrow] then cursor = wrap(cursor + 1, 1, [max])

You could also use this to wrap coordinates, so the player can leave the right side of your
stage and emerge on the left, like the Pac-Man tunnel, or create a seemingly infinitely scrolling
stage, like Asteroids, which really just repeats on itself.  For the latter example, you would
wrap the coordinates of objects whenever they travel beyond the stage, and also wrap the
coordinates to within a range around the player's position, when using them to draw the screen.
The result will appear seamless, and it won't matter how fast things travel each frame.



Code: (Select All)
function wrap_a(a) ' angle a is adjusted back within 0 and 2pi, noninclusive of 2pi
x = -a / atn1(8)
if x <> int(x) then x = x + 1
wrap_a = a + (int(x) * atn1(8))
end function


function atn1(n)
atn1 = n * atn(1)
end function

This does exactly the same thing, but for angles.  Put any angle value in this function,
and it will simplify it to a positive angle less than a full circle.  Very useful when
angle values can get adjusted over and over.  Just put the function around any angle changes.

(Note that the little atn1() function is just a shorthand thing, I got tired of typing
n * atn(1) in a ton of places.  It generates an angle in radians, where the value passed in
is an eighth of a circle or 45 degrees, so atn1(8) = 2 * pi radians, or 360 degrees.)



Code: (Select All)
function plus_limit(n, p, l) ' p is added to n, but can't go past l in the direction of travel
q = n + p
if sgn(q - l) = sgn(p) then q = l
plus_limit = q
end function

This saves a lot of space capping values, and is direction-dependent.  If p is positive,
n can't go past l upward; if p is negative, n can't go past l downward.  I use this for many
things, like decaying values without going below zero, capping healing at maximum health,
trapping position coordinates at the edges of the screen, the uses are endless.  The syntax
is very clean, all packed up in one line, it replaces stuff like this:

health = health + 100
if health > max_health then health = max_health

with this:

health = plus_limit(health, 100, max_health)

The directional dependency of this is more useful than you might think at first glance,
and is a feature that simple floor and ceiling functions don't have.  For example,
you can use sgn() comparison to move something toward a goal value, and stop it if it
reaches the goal, but not snap to the goal if moving away from it.
Then you might use something like this:

x = plus_limit(x, sgn(goal - x) * speed, goal)

This can be very useful in having one value that changes instantly, and another that
constantly follows it.  In my current game project, one way I use this is to give visual
feedback about damage that was just taken.  If the player gets hit, the health is instantly
lowered, so the green health bar gets shorter.  But there's a hidden second red bar behind
it, and that red bar's value follows the health value.  If you gain health, this does
nothing, since the red bar will be shorter, but when you LOSE health, the player will see
part of the health bar become red, and instantly start shrinking, until all that's left
is the green part.

Do note that because of the dependency, if for example you are subtracting, this function
won't catch a value that was already higher than it should be.  So be careful.



Code: (Select All)
function toggle(v, p, q)
toggle = v
if v = p then toggle = q
if v = q then toggle = p
end function

This one just toggles between the given values.  However, it will not do anything
if the variable passed is not one of these two values.  Use like v = toggle(v, value1, value2).
Replaces the messier [if v = value1 then v = value2 else v = value1].  And since it's a function,
you can use it very compactly and dynamically, rather than directly manipulating variables.
Let's say you have a 1v1 RPG combat scenario, and one of the characters decided to attack.
You've calculated the damage already.  So instead of:

if turn = char1 then target = char2 else target = char1
call damage_char(target, damage)

You can write:

call damage_char(toggle(turn, char1, char2), damage)

Think of it like the binary NOT operator, except this works between any two values you want.



Code: (Select All)
function before$(t$, c$)
p = instr(t$, c$)
if p = false then p = len(t$) + 1
before$ = left$(t$, p - 1)
end function


function after$(t$, c$)
after$ = right$(t$, len(t$) - instr(t$, c$) - (len(c$) - 1))
end function


function between$(t$, c1$, c2$)
between$ = before$(after$(t$, c1$), c2$)
end function

These functions are used for slicing strings, which has been useful in developing my own scripting,
among other things.  before$ will return everything in t$ before the first instance it finds of c$,
while after$ will return everything after it.  If c$ is not found, it will simply return t$ unchanged.

An interesting application of this is to return more than one value from a function.  For example,
if you want a function to return both x and y coordinates, you can make the function's return data type
a string, pack the two values up with a comma between like "100, 50", then use before and after
functions with val() to pull the values apart outside the function.  You can also easily do this
for three-dimensional coordinates.  And it need not be limited to coordinates, you could also use
a separator character to return multiple strings packed into one string, like "Alice|Timothy|Eric".

between$, of course, just cleans up the syntax when using before$ and after$ together, which often
happens in my code.  This:

result$ = before$(after$(t$, "["), "]")

Becomes this:

result$ = between$(t$, "[", "]")

Print this item