'==========
'KEYS48.BAS v1.0
'==========
'A Playable/Recordable Keyboard instrument
'Coded by Dav for QB64, JAN/2021

'NOTE: Before compiling, check 'Output EXE to Source'

'-----
'ABOUT
'-----

'KEYS48 is a virtual instrument that you can play and
'and record little piano tunes with.  Use mouse to click on
'and play notes. The program starts in freeplay mode, but
'you can record in real time as you play by pressing R.
'Record over your song several times to add more notes and
'make more complex patterns (called overdubbing).

'--------
'CONTROLS
'--------

'Press M fo a menu list of commands.

'Press R to record song and to overdub (add) notes to a song.
'Press U to Undo last recording (in case you make a mistake!)
'Press P to playback the recorded song currently in memory.
'Press C to clear (erase) recorded notes currently in memory.
'Press +/- keys to adjust playback and recording speed.
'        Current speed value is shown at the top left.
'Press ENTER to go back to default speed of 100.

'Press ESC to stop recording playback of the song.
'NOTE: You can also play notes during song playback.

'Press S to Save your recording to .K46 file in songs dir.
'        If the file already exists, it will be overwritten.
'        If not the program will ask you for a song name.
'        The .K48 extension will be added automatically.
'Press L to Load a saved song in the songs dir.
'Press D to Delete currently load song.
'
'=========================================================
'
'PRO TIP: Having trouble playing fast enough with mouse?
'         Slow down Speed BEFORE recording, then raise it
'         back up when playing song back.
'
'=========================================================
'
'NOTES: The directory 'keys' hold the keyboard sounds.
'       The directory 'songs' holds all the .K48 songs.
'       Both directories are required to use this program.
'       They must be in the current EXE program path.
'       Currently loaded song and speed is shown top left.
'       Song speed setting is saved with the song file.
'       Currently the max song length is about 6 minutes.
'       You can change that with the MaxSongLength var.
'
'=========================================================
'
'Things planned in next version: Record speed changes
'                                (Add Page Up/Down +/- 5)
'                                Turn Overdub ON/Off
'                                Add a Metronome click
'                                Add render to .WAV file
'                                (will ask Petr for help!)
'                                Add more keyboard sounds
'                                Add Loop song playing
'                                pause, record position
'                                Seek position in song
'
'=========================================================

SCREEN _LOADIMAGE("keys48.png", 32)
DO: LOOP UNTIL _SCREENEXISTS

_TITLE "Dav's 48 Keys v1.0": _ICON _DISPLAY

'Make sure keys directory is present first...
IF _DIREXISTS("keys") = 0 THEN
    DrawBox: LOCATE 15, 37:
    PRINT "ERROR: Needed 'keys' directory not found!"
    END
END IF

'Make a songs directory if not found
IF _DIREXISTS("songs") = 0 THEN MKDIR "songs"

'share note variable, playing flag, timer for all 48 keys
DIM SHARED n01flag, n01timer, n01&, n02flag, n02timer, n02&
DIM SHARED n03flag, n03timer, n03&, n04flag, n04timer, n04&
DIM SHARED n05flag, n05timer, n05&, n06flag, n06timer, n06&
DIM SHARED n07flag, n07timer, n07&, n08flag, n08timer, n08&
DIM SHARED n09flag, n09timer, n09&, n10flag, n10timer, n10&
DIM SHARED n11flag, n11timer, n11&, n12flag, n12timer, n12&
DIM SHARED n13flag, n13timer, n13&, n14flag, n14timer, n14&
DIM SHARED n15flag, n15timer, n15&, n16flag, n16timer, n16&
DIM SHARED n17flag, n17timer, n17&, n18flag, n18timer, n18&
DIM SHARED n19flag, n19timer, n19&, n20flag, n20timer, n20&
DIM SHARED n21flag, n21timer, n21&, n22flag, n22timer, n22&
DIM SHARED n23flag, n23timer, n23&, n24flag, n24timer, n24&
DIM SHARED n25flag, n25timer, n25&, n26flag, n26timer, n26&
DIM SHARED n27flag, n27timer, n27&, n28flag, n28timer, n28&
DIM SHARED n29flag, n29timer, n29&, n30flag, n30timer, n30&
DIM SHARED n31flag, n31timer, n31&, n32flag, n32timer, n32&
DIM SHARED n33flag, n33timer, n33&, n34flag, n34timer, n34&
DIM SHARED n35flag, n35timer, n35&, n36flag, n36timer, n36&
DIM SHARED n37flag, n37timer, n37&, n38flag, n38timer, n38&
DIM SHARED n39flag, n39timer, n39&, n40flag, n40timer, n40&
DIM SHARED n41flag, n41timer, n41&, n42flag, n42timer, n42&
DIM SHARED n43flag, n43timer, n43&, n44flag, n44timer, n44&
DIM SHARED n45flag, n45timer, n45&, n46flag, n46timer, n46&
DIM SHARED n47flag, n47timer, n47&, n48flag, n48timer, n48&

'Load/open all keys sound files
n01& = _SNDOPEN("keys\01.key"): n02& = _SNDOPEN("keys\02.key")
n03& = _SNDOPEN("keys\03.key"): n04& = _SNDOPEN("keys\04.key")
n05& = _SNDOPEN("keys\05.key"): n06& = _SNDOPEN("keys\06.key")
n07& = _SNDOPEN("keys\07.key"): n08& = _SNDOPEN("keys\08.key")
n09& = _SNDOPEN("keys\09.key"): n10& = _SNDOPEN("keys\10.key")
n11& = _SNDOPEN("keys\11.key"): n12& = _SNDOPEN("keys\12.key")
n13& = _SNDOPEN("keys\13.key"): n14& = _SNDOPEN("keys\14.key")
n15& = _SNDOPEN("keys\15.key"): n16& = _SNDOPEN("keys\16.key")
n17& = _SNDOPEN("keys\17.key"): n18& = _SNDOPEN("keys\18.key")
n19& = _SNDOPEN("keys\19.key"): n20& = _SNDOPEN("keys\20.key")
n21& = _SNDOPEN("keys\21.key"): n22& = _SNDOPEN("keys\22.key")
n23& = _SNDOPEN("keys\23.key"): n24& = _SNDOPEN("keys\24.key")
n25& = _SNDOPEN("keys\25.key"): n26& = _SNDOPEN("keys\26.key")
n27& = _SNDOPEN("keys\27.key"): n28& = _SNDOPEN("keys\28.key")
n29& = _SNDOPEN("keys\29.key"): n30& = _SNDOPEN("keys\30.key")
n31& = _SNDOPEN("keys\31.key"): n32& = _SNDOPEN("keys\32.key")
n33& = _SNDOPEN("keys\33.key"): n34& = _SNDOPEN("keys\34.key")
n35& = _SNDOPEN("keys\35.key"): n36& = _SNDOPEN("keys\36.key")
n37& = _SNDOPEN("keys\37.key"): n38& = _SNDOPEN("keys\38.key")
n39& = _SNDOPEN("keys\39.key"): n40& = _SNDOPEN("keys\40.key")
n41& = _SNDOPEN("keys\41.key"): n42& = _SNDOPEN("keys\42.key")
n43& = _SNDOPEN("keys\43.key"): n44& = _SNDOPEN("keys\44.key")
n45& = _SNDOPEN("keys\45.key"): n46& = _SNDOPEN("keys\46.key")
n47& = _SNDOPEN("keys\47.key"): n48& = _SNDOPEN("keys\48.key")

'Share/define these values - used often
DIM SHARED WhtOn&, WhtOff&, BlkOn&, BlkOff&, Blk& 'colors
DIM SHARED speed, MaxSongLength, release, header$
DIM SHARED scr1 AS _MEM, scr2 AS _MEM 'for screen saving

WhtOn& = _RGB(179, 192, 211): WhtOff& = _RGB(246, 255, 255) 'key colors
BlkOn& = _RGB(48, 84, 107): BlkOff& = _RGB(43, 56, 63): Blk& = _RGB(23, 23, 23)
release = .4 'how long to highlight notes when played
MaxSongLength = 500000 'max of 500k of song memory
speed = 100 'playback speed defaults to 100%


DIM keymap(1 TO 255) AS _BYTE
RESTORE keymapdata
FOR i = 32 TO 48
    READ a$
    keymap(ASC(a$)) = i
NEXT
FOR i = 8 TO 24
    READ a$
    keymap(ASC(a$)) = i
NEXT
keymapdata:
' 2 3  5 6 7  9 0
'q w er t y ui o p     <- from C to E
'
' s d  g h j  l ;
'z x cv b n m, . /     <- from C to E

DATA q,2,w,3,e,r,5,t,6,y,7,u,i,9,o,0,p
DATA z,s,x,d,c,v,g,b,h,n,j,m,",",l,".",";","/"


GOSUB UpdateInfo

'========
MainLoop: 'I dont currently call this, but it's here if needed.
'========

DO

    GOSUB PlayKeys 'freeplay notes

    'Get user input...
    k$ = UCASE$(INKEY$)
    IF k$ <> "" THEN

        IF k$ = "R" THEN
            GOSUB record: GOSUB UpdateInfo
        END IF

        IF k$ = "P" THEN
            GOSUB playback: GOSUB UpdateInfo
        END IF

        IF k$ = "C" THEN
            NoteData$ = "": song$ = ""
            GOSUB SaveScreen
            DrawBox: LOCATE 15, 37: PRINT " SONG MEMORY IS NOW CLEARED! "
            _DELAY 2
            GOSUB RestoreScreen: GOSUB UpdateInfo
        END IF

        IF k$ = "U" THEN
            GOSUB SaveScreen: DrawBox
            IF NoteData$ <> "" THEN
                NoteData$ = UndoData$
                LOCATE 15, 37: PRINT "  UNDOING YOUR LAST RECORDING...  ";
            ELSE
                LOCATE 15, 37: PRINT "  THERE'S NO RECORDING TO UNDO!";
            END IF
            _DELAY 2
            GOSUB RestoreScreen
        END IF

        IF k$ = "S" THEN

            GOSUB SaveScreen: DrawBox

            IF NoteData$ = "" THEN
                LOCATE 15, 37: PRINT "  THERE IS NO SONG TO SAVE!  ";
                _DELAY 2
            END IF

            IF song$ <> "" THEN 'song already opened...just update song
                OPEN "songs\" + song$ FOR OUTPUT AS #1
                header$ = CHR$(27) + "K48V100" + CHR$(speed)
                PRINT #1, header$;
                PRINT #1, _DEFLATE$(NoteData$);: CLOSE 1
                LOCATE 15, 37: PRINT UCASE$(song$); " HAS BEEN SAVED!";
                _DELAY 2
            END IF

            'notedata here, song$ not made yet, so save new file
            IF NoteData$ <> "" AND song$ = "" THEN
                LOCATE 15, 37: INPUT "SONG TO SAVE: ", song$
                IF song$ <> "" THEN
                    'strip out any path given (thanks, Steve!)
                    song$ = MID$(song$, _INSTRREV(song$, "\") + 1)
                    IF INSTR(1, song$, ".") = 0 THEN song$ = song$ + ".k48"
                    OPEN "songs\" + song$ FOR OUTPUT AS #1
                    header$ = CHR$(27) + "K48V100" + CHR$(speed)
                    PRINT #1, header$;
                    PRINT #1, _DEFLATE$(NoteData$);: CLOSE 1
                    LOCATE 15, 37: PRINT SPACE$(45);
                    LOCATE 15, 37: PRINT UCASE$(song$); " HAS BEEN SAVED!";
                    _DELAY 2
                END IF
            END IF

            GOSUB RestoreScreen
            GOSUB UpdateInfo

        END IF

        IF k$ = "L" THEN

            GOSUB SaveScreen: DrawBox

            LOCATE 15, 37: INPUT "SONG TO LOAD: ", tmpsong$
            IF tmpsong$ <> "" THEN
                'strip out any path given (thanks, Steve!)
                tmpsong$ = MID$(tmpsong$, _INSTRREV(tmpsong$, "\") + 1)
                IF INSTR(1, tmpsong$, ".") = 0 THEN tmpsong$ = tmpsong$ + ".k48"
                IF _FILEEXISTS("songs\" + tmpsong$) THEN
                    OPEN "songs\" + tmpsong$ FOR BINARY AS #1
                    IF LOF(1) < 9 THEN
                        header$ = "" 'file not big enough
                    ELSE
                        header$ = INPUT$(9, 1) 'load header
                    END IF
                    IF MID$(header$, 1, 8) <> CHR$(27) + "K48V100" THEN
                        DrawBox: LOCATE 15, 37: PRINT UCASE$(tmpsong$); " FILE NOT VALID!";
                    ELSE
                        'set saved speed
                        speed = ASC(MID$(header$, 9, 1))
                        NoteData$ = _INFLATE$(INPUT$(LOF(1) - 9, 1)): CLOSE 1
                        DrawBox: LOCATE 15, 37: PRINT UCASE$(tmpsong$); " HAS BEEN LOADED.";
                        song$ = tmpsong$
                    END IF
                ELSE
                    DrawBox: LOCATE 15, 37: PRINT UCASE$(tmpsong$); " SONG FILE NOT FOUND!";
                END IF
                _DELAY 2
            END IF

            GOSUB RestoreScreen
            GOSUB UpdateInfo

        END IF

        IF k$ = "D" THEN

            GOSUB SaveScreen: DrawBox

            IF song$ <> "" AND _FILEEXISTS("songs\" + song$) THEN
                LOCATE 15, 37: PRINT "DELETE FILE "; UCASE$(song$);
                LOCATE 16, 45: PRINT "ARE YOU SURE? (Y/N)";
                sure$ = UCASE$(INPUT$(1))
                IF sure$ = "Y" THEN
                    DrawBox
                    KILL "songs\" + song$
                    LOCATE 15, 37: PRINT UCASE$(song$); " DELETED!";
                    NoteData$ = "": song$ = ""
                    _DELAY 2
                END IF
            ELSE
                LOCATE 15, 37: PRINT " NO SONG FOUND TO DELETE!  ";
                _DELAY 2
            END IF

            GOSUB RestoreScreen
            GOSUB UpdateInfo

        END IF

        IF k$ = "M" THEN
            GOSUB SaveScreen
            menu& = _LOADIMAGE("keys48m.png", 32)
            _PUTIMAGE (235, 90), menu&: _FREEIMAGE menu&
            SLEEP: _KEYCLEAR
            GOSUB RestoreScreen
        END IF

        IF k$ = "-" THEN
            speed = speed - 1: IF speed < 40 THEN speed = 40
            GOSUB UpdateInfo
        END IF

        IF k$ = "+" THEN
            speed = speed + 1: IF speed > 200 THEN speed = 200
            GOSUB UpdateInfo
        END IF

        IF k$ = CHR$(13) THEN
            speed = 100: GOSUB UpdateInfo
        END IF

        _KEYCLEAR

    END IF

    _LIMIT speed * 15 'this is the current delay/speed method....

LOOP

END


'=========================================================
PlayKeys: 'Gets mouse input and plays keyboard
'=======

mi = _MOUSEINPUT
IF _MOUSEBUTTON(1) = 0 THEN done = 0

IF _MOUSEBUTTON(1) AND done = 0 THEN
    mx = _MOUSEX: my = _MOUSEY

    '=== play notes if clicked on one
    'bottom row...
    IF mx > 4 AND mx < 63 AND my > 432 AND my < 515 THEN DoNote 1
    IF mx > 42 AND mx < 76 AND my > 348 AND my < 428 THEN DoNote 2
    IF mx > 68 AND mx < 127 AND my > 432 AND my < 515 THEN DoNote 3
    IF mx > 112 AND mx < 146 AND my > 348 AND my < 428 THEN DoNote 4
    IF mx > 133 AND mx < 189 AND my > 432 AND my < 515 THEN DoNote 5
    IF mx > 182 AND mx < 214 AND my > 348 AND my < 428 THEN DoNote 6
    IF mx > 196 AND mx < 255 AND my > 432 AND my < 515 THEN DoNote 7
    IF mx > 260 AND mx < 319 AND my > 432 AND my < 515 THEN DoNote 8
    IF mx > 298 AND mx < 332 AND my > 348 AND my < 428 THEN DoNote 9
    IF mx > 324 AND mx < 383 AND my > 432 AND my < 515 THEN DoNote 10
    IF mx > 373 AND mx < 409 AND my > 348 AND my < 428 THEN DoNote 11
    IF mx > 387 AND mx < 447 AND my > 432 AND my < 515 THEN DoNote 12
    IF mx > 451 AND mx < 512 AND my > 432 AND my < 515 THEN DoNote 13
    IF mx > 489 AND mx < 526 AND my > 348 AND my < 428 THEN DoNote 14
    IF mx > 515 AND mx < 575 AND my > 432 AND my < 515 THEN DoNote 15
    IF mx > 557 AND mx < 596 AND my > 348 AND my < 428 THEN DoNote 16
    IF mx > 579 AND mx < 639 AND my > 432 AND my < 515 THEN DoNote 17
    IF mx > 627 AND mx < 667 AND my > 348 AND my < 428 THEN DoNote 18
    IF mx > 643 AND mx < 702 AND my > 432 AND my < 515 THEN DoNote 19
    IF mx > 707 AND mx < 767 AND my > 432 AND my < 515 THEN DoNote 20
    IF mx > 743 AND mx < 783 AND my > 348 AND my < 428 THEN DoNote 21
    IF mx > 771 AND mx < 831 AND my > 432 AND my < 515 THEN DoNote 22
    IF mx > 818 AND mx < 858 AND my > 348 AND my < 428 THEN DoNote 23
    IF mx > 835 AND mx < 895 AND my > 432 AND my < 515 THEN DoNote 24
    'top row...
    IF mx > 5 AND mx < 65 AND my > 211 AND my < 294 THEN DoNote 25
    IF mx > 42 AND mx < 81 AND my > 124 AND my < 207 THEN DoNote 26
    IF mx > 69 AND mx < 129 AND my > 211 AND my < 294 THEN DoNote 27
    IF mx > 114 AND mx < 147 AND my > 124 AND my < 207 THEN DoNote 28
    IF mx > 133 AND mx < 192 AND my > 211 AND my < 294 THEN DoNote 29
    IF mx > 184 AND mx < 215 AND my > 124 AND my < 207 THEN DoNote 30
    IF mx > 197 AND mx < 256 AND my > 211 AND my < 294 THEN DoNote 31
    IF mx > 261 AND mx < 320 AND my > 211 AND my < 294 THEN DoNote 32
    IF mx > 301 AND mx < 332 AND my > 124 AND my < 207 THEN DoNote 33
    IF mx > 325 AND mx < 384 AND my > 211 AND my < 294 THEN DoNote 34
    IF mx > 376 AND mx < 407 AND my > 124 AND my < 207 THEN DoNote 35
    IF mx > 388 AND mx < 448 AND my > 211 AND my < 294 THEN DoNote 36
    IF mx > 452 AND mx < 512 AND my > 211 AND my < 294 THEN DoNote 37
    IF mx > 493 AND mx < 525 AND my > 124 AND my < 207 THEN DoNote 38
    IF mx > 516 AND mx < 576 AND my > 211 AND my < 294 THEN DoNote 39
    IF mx > 561 AND mx < 594 AND my > 124 AND my < 207 THEN DoNote 40
    IF mx > 580 AND mx < 640 AND my > 211 AND my < 294 THEN DoNote 41
    IF mx > 631 AND mx < 664 AND my > 124 AND my < 207 THEN DoNote 42
    IF mx > 644 AND mx < 703 AND my > 211 AND my < 294 THEN DoNote 43
    IF mx > 708 AND mx < 767 AND my > 211 AND my < 294 THEN DoNote 44
    IF mx > 748 AND mx < 780 AND my > 124 AND my < 207 THEN DoNote 45
    IF mx > 772 AND mx < 831 AND my > 211 AND my < 294 THEN DoNote 46
    IF mx > 823 AND mx < 855 AND my > 124 AND my < 207 THEN DoNote 47
    IF mx > 836 AND mx < 895 AND my > 211 AND my < 294 THEN DoNote 48

    done = 1 'make a mouse click flag

END IF

GOSUB NoteDisplay

RETURN


'=========================================================
record:
'=======
_KEYCLEAR
'Make copy of NoteData$ for undo purposes
UndoData$ = NoteData$

IF NoteData$ = "" THEN NoteData$ = "1" 'song recording marker
note = 1

COLOR _RGB(255, 255, 255), _RGB(255, 0, 0)
LOCATE 1, 1: PRINT " Now Recording | ESC to Stop ";


DO

    _LIMIT speed * 15 'this is the current delay/speed method....

    note$ = ""

    'playback any previously recorded notes
    SELECT CASE MID$(NoteData$, note, 1)
        CASE CHR$(1): DoNote 1
        CASE CHR$(2): DoNote 2
        CASE CHR$(3): DoNote 3
        CASE CHR$(4): DoNote 4
        CASE CHR$(5): DoNote 5
        CASE CHR$(6): DoNote 6
        CASE CHR$(7): DoNote 7
        CASE CHR$(8): DoNote 8
        CASE CHR$(9): DoNote 9
        CASE CHR$(10): DoNote 10
        CASE CHR$(11): DoNote 11
        CASE CHR$(12): DoNote 12
        CASE CHR$(13): DoNote 13
        CASE CHR$(14): DoNote 14
        CASE CHR$(15): DoNote 15
        CASE CHR$(16): DoNote 16
        CASE CHR$(17): DoNote 17
        CASE CHR$(18): DoNote 18
        CASE CHR$(19): DoNote 19
        CASE CHR$(20): DoNote 20
        CASE CHR$(21): DoNote 21
        CASE CHR$(22): DoNote 22
        CASE CHR$(23): DoNote 23
        CASE CHR$(24): DoNote 24
        CASE CHR$(25): DoNote 25
        CASE CHR$(26): DoNote 26
        CASE CHR$(27): DoNote 27
        CASE CHR$(28): DoNote 28
        CASE CHR$(29): DoNote 29
        CASE CHR$(30): DoNote 30
        CASE CHR$(31): DoNote 31
        CASE CHR$(32): DoNote 32
        CASE CHR$(33): DoNote 33
        CASE CHR$(34): DoNote 34
        CASE CHR$(35): DoNote 35
        CASE CHR$(36): DoNote 36
        CASE CHR$(37): DoNote 37
        CASE CHR$(38): DoNote 38
        CASE CHR$(39): DoNote 39
        CASE CHR$(40): DoNote 40
        CASE CHR$(41): DoNote 41
        CASE CHR$(42): DoNote 42
        CASE CHR$(43): DoNote 43
        CASE CHR$(44): DoNote 44
        CASE CHR$(45): DoNote 45
        CASE CHR$(46): DoNote 46
        CASE CHR$(47): DoNote 47
        CASE CHR$(48): DoNote 48
    END SELECT

    mi = _MOUSEINPUT
    IF _MOUSEBUTTON(1) = 0 THEN done = 0

    IF _MOUSEBUTTON(1) AND done = 0 THEN
        mx = _MOUSEX: my = _MOUSEY

        '=== play notes if clicked on one
        'top row...
        IF mx > 4 AND mx < 63 AND my > 432 AND my < 515 THEN DoNote 1: note$ = CHR$(1)
        IF mx > 42 AND mx < 76 AND my > 348 AND my < 428 THEN DoNote 2: note$ = CHR$(2)
        IF mx > 68 AND mx < 127 AND my > 432 AND my < 515 THEN DoNote 3: note$ = CHR$(3)
        IF mx > 112 AND mx < 146 AND my > 348 AND my < 428 THEN DoNote 4: note$ = CHR$(4)
        IF mx > 133 AND mx < 189 AND my > 432 AND my < 515 THEN DoNote 5: note$ = CHR$(5)
        IF mx > 182 AND mx < 214 AND my > 348 AND my < 428 THEN DoNote 6: note$ = CHR$(6)
        IF mx > 196 AND mx < 255 AND my > 432 AND my < 515 THEN DoNote 7: note$ = CHR$(7)
        IF mx > 260 AND mx < 319 AND my > 432 AND my < 515 THEN DoNote 8: note$ = CHR$(8)
        IF mx > 298 AND mx < 332 AND my > 348 AND my < 428 THEN DoNote 9: note$ = CHR$(9)
        IF mx > 324 AND mx < 383 AND my > 432 AND my < 515 THEN DoNote 10: note$ = CHR$(10)
        IF mx > 373 AND mx < 409 AND my > 348 AND my < 428 THEN DoNote 11: note$ = CHR$(11)
        IF mx > 387 AND mx < 447 AND my > 432 AND my < 515 THEN DoNote 12: note$ = CHR$(12)
        IF mx > 451 AND mx < 512 AND my > 432 AND my < 515 THEN DoNote 13: note$ = CHR$(13)
        IF mx > 489 AND mx < 526 AND my > 348 AND my < 428 THEN DoNote 14: note$ = CHR$(14)
        IF mx > 515 AND mx < 575 AND my > 432 AND my < 515 THEN DoNote 15: note$ = CHR$(15)
        IF mx > 557 AND mx < 596 AND my > 348 AND my < 428 THEN DoNote 16: note$ = CHR$(16)
        IF mx > 579 AND mx < 639 AND my > 432 AND my < 515 THEN DoNote 17: note$ = CHR$(17)
        IF mx > 627 AND mx < 667 AND my > 348 AND my < 428 THEN DoNote 18: note$ = CHR$(18)
        IF mx > 643 AND mx < 702 AND my > 432 AND my < 515 THEN DoNote 19: note$ = CHR$(19)
        IF mx > 707 AND mx < 767 AND my > 432 AND my < 515 THEN DoNote 20: note$ = CHR$(20)
        IF mx > 743 AND mx < 783 AND my > 348 AND my < 428 THEN DoNote 21: note$ = CHR$(21)
        IF mx > 771 AND mx < 831 AND my > 432 AND my < 515 THEN DoNote 22: note$ = CHR$(22)
        IF mx > 818 AND mx < 858 AND my > 348 AND my < 428 THEN DoNote 23: note$ = CHR$(23)
        IF mx > 835 AND mx < 895 AND my > 432 AND my < 515 THEN DoNote 24: note$ = CHR$(24)
        'bottom row...
        IF mx > 5 AND mx < 65 AND my > 211 AND my < 294 THEN DoNote 25: note$ = CHR$(25)
        IF mx > 42 AND mx < 81 AND my > 124 AND my < 207 THEN DoNote 26: note$ = CHR$(26)
        IF mx > 69 AND mx < 129 AND my > 211 AND my < 294 THEN DoNote 27: note$ = CHR$(27)
        IF mx > 114 AND mx < 147 AND my > 124 AND my < 207 THEN DoNote 28: note$ = CHR$(28)
        IF mx > 133 AND mx < 192 AND my > 211 AND my < 294 THEN DoNote 29: note$ = CHR$(29)
        IF mx > 184 AND mx < 215 AND my > 124 AND my < 207 THEN DoNote 30: note$ = CHR$(30)
        IF mx > 197 AND mx < 256 AND my > 211 AND my < 294 THEN DoNote 31: note$ = CHR$(31)
        IF mx > 261 AND mx < 320 AND my > 211 AND my < 294 THEN DoNote 32: note$ = CHR$(32)
        IF mx > 301 AND mx < 332 AND my > 124 AND my < 207 THEN DoNote 33: note$ = CHR$(33)
        IF mx > 325 AND mx < 384 AND my > 211 AND my < 294 THEN DoNote 34: note$ = CHR$(34)
        IF mx > 376 AND mx < 407 AND my > 124 AND my < 207 THEN DoNote 35: note$ = CHR$(35)
        IF mx > 388 AND mx < 448 AND my > 211 AND my < 294 THEN DoNote 36: note$ = CHR$(36)
        IF mx > 452 AND mx < 512 AND my > 211 AND my < 294 THEN DoNote 37: note$ = CHR$(37)
        IF mx > 493 AND mx < 525 AND my > 124 AND my < 207 THEN DoNote 38: note$ = CHR$(38)
        IF mx > 516 AND mx < 576 AND my > 211 AND my < 294 THEN DoNote 39: note$ = CHR$(39)
        IF mx > 561 AND mx < 594 AND my > 124 AND my < 207 THEN DoNote 40: note$ = CHR$(40)
        IF mx > 580 AND mx < 640 AND my > 211 AND my < 294 THEN DoNote 41: note$ = CHR$(41)
        IF mx > 631 AND mx < 664 AND my > 124 AND my < 207 THEN DoNote 42: note$ = CHR$(42)
        IF mx > 644 AND mx < 703 AND my > 211 AND my < 294 THEN DoNote 43: note$ = CHR$(43)
        IF mx > 708 AND mx < 767 AND my > 211 AND my < 294 THEN DoNote 44: note$ = CHR$(44)
        IF mx > 748 AND mx < 780 AND my > 124 AND my < 207 THEN DoNote 45: note$ = CHR$(45)
        IF mx > 772 AND mx < 831 AND my > 211 AND my < 294 THEN DoNote 46: note$ = CHR$(46)
        IF mx > 823 AND mx < 855 AND my > 124 AND my < 207 THEN DoNote 47: note$ = CHR$(47)
        IF mx > 846 AND mx < 895 AND my > 211 AND my < 294 THEN DoNote 48: note$ = CHR$(48)

        done = 1 'did a mouse click

    END IF



    k& = _KEYHIT
    IF k& >= 1 AND k& <= 255 THEN
        IF keymap(k&) THEN
            DoNote keymap(k&)
            note$ = CHR$(keymap(k&))
        END IF
    END IF


    GOSUB NoteDisplay

    IF note$ <> "" THEN
        IF note <= LEN(NoteData$) THEN
            MID$(NoteData$, note, 1) = note$ 'add the note
        ELSE
            NoteData$ = NoteData$ + note$
        END IF
    ELSE
        IF note >= LEN(NoteData$) THEN
            NoteData$ = NoteData$ + CHR$(255) 'else add empty space
        END IF
    END IF

    note = note + 1
    IF note >= MaxSongLength THEN EXIT DO

LOOP UNTIL INKEY$ = CHR$(27)

DO: LOOP UNTIL INKEY$ = ""

RETURN

'=========================================================
playback:
'========

'If nothing recorded yet, don't try play
IF NoteData$ = "" THEN
    COLOR _RGB(0, 0, 0), _RGB(255, 255, 0)
    LOCATE 1, 1: PRINT " No recorded song in memory! ";
    _DELAY 2
    DO: LOOP UNTIL INKEY$ = ""
    RETURN
END IF

COLOR _RGB(0, 0, 0), _RGB(0, 255, 0)
LOCATE 1, 1: PRINT " Playing song | ESC to stop  ";

note = 1

DO

    _LIMIT speed * 15 'this is the current delay/speed method....

    SELECT CASE MID$(NoteData$, note, 1)
        CASE CHR$(1): DoNote 1
        CASE CHR$(2): DoNote 2
        CASE CHR$(3): DoNote 3
        CASE CHR$(4): DoNote 4
        CASE CHR$(5): DoNote 5
        CASE CHR$(6): DoNote 6
        CASE CHR$(7): DoNote 7
        CASE CHR$(8): DoNote 8
        CASE CHR$(9): DoNote 9
        CASE CHR$(10): DoNote 10
        CASE CHR$(11): DoNote 11
        CASE CHR$(12): DoNote 12
        CASE CHR$(13): DoNote 13
        CASE CHR$(14): DoNote 14
        CASE CHR$(15): DoNote 15
        CASE CHR$(16): DoNote 16
        CASE CHR$(17): DoNote 17
        CASE CHR$(18): DoNote 18
        CASE CHR$(19): DoNote 19
        CASE CHR$(20): DoNote 20
        CASE CHR$(21): DoNote 21
        CASE CHR$(22): DoNote 22
        CASE CHR$(23): DoNote 23
        CASE CHR$(24): DoNote 24
        CASE CHR$(25): DoNote 25
        CASE CHR$(26): DoNote 26
        CASE CHR$(27): DoNote 27
        CASE CHR$(28): DoNote 28
        CASE CHR$(29): DoNote 29
        CASE CHR$(30): DoNote 30
        CASE CHR$(31): DoNote 31
        CASE CHR$(32): DoNote 32
        CASE CHR$(33): DoNote 33
        CASE CHR$(34): DoNote 34
        CASE CHR$(35): DoNote 35
        CASE CHR$(36): DoNote 36
        CASE CHR$(37): DoNote 37
        CASE CHR$(38): DoNote 38
        CASE CHR$(39): DoNote 39
        CASE CHR$(40): DoNote 40
        CASE CHR$(41): DoNote 41
        CASE CHR$(42): DoNote 42
        CASE CHR$(43): DoNote 43
        CASE CHR$(44): DoNote 44
        CASE CHR$(45): DoNote 45
        CASE CHR$(46): DoNote 46
        CASE CHR$(47): DoNote 47
        CASE CHR$(48): DoNote 48
    END SELECT

    note = note + 1

    'if done playing, exit
    IF note >= LEN(NoteData$) THEN EXIT DO

    GOSUB PlayKeys 'you can play notes too while song plays

    k$ = INKEY$
    IF k$ <> "" THEN
        IF k$ = "-" THEN
            speed = speed - 1
            IF speed < 40 THEN speed = 40
            COLOR _RGB(163, 163, 175), _RGB(70, 95, 114)
            LOCATE 3, 3: PRINT " Speed ="; speed; "   ";
        END IF
        IF k$ = "+" THEN
            speed = speed + 1
            IF speed > 200 THEN speed = 200
            COLOR _RGB(163, 163, 175), _RGB(70, 95, 114)
            LOCATE 3, 3: PRINT " Speed ="; speed; "   ";
        END IF
        IF k$ = CHR$(13) THEN
            speed = 100
            COLOR _RGB(163, 163, 175), _RGB(70, 95, 114)
            LOCATE 3, 3: PRINT " Speed ="; speed; "   ";
        END IF
        _KEYCLEAR
    END IF

LOOP UNTIL k$ = CHR$(27)

DO: LOOP UNTIL INKEY$ = ""

RETURN

'=======================================================
NoteDisplay:
'===========
'if note playing flag is on, check its timer.
'If release time is past, note goes back to normal, flag off
IF n01flag = 1 THEN
    IF TIMER - n01timer > release THEN 'f1
        n01flag = 0
        LINE (4, 346)-(40, 434), WhtOff&, BF
        LINE (4, 434)-(63, 515), WhtOff&, BF
    END IF
END IF

IF n02flag = 1 THEN
    IF TIMER - n02timer > release THEN '
        n02timer = 0: LINE (44, 348)-(76, 429), BlkOff&, BF
    END IF
END IF

IF n03flag = 1 THEN
    IF TIMER - n03timer > release THEN '
        n03timer = 0
        LINE (81, 346)-(109, 434), WhtOff&, BF
        LINE (68, 434)-(127, 515), WhtOff&, BF
    END IF
END IF

IF n04flag = 1 THEN
    IF TIMER - n04timer > release THEN '
        n04timer = 0: LINE (113, 348)-(146, 429), BlkOff&, BF
    END IF
END IF

IF n05flag = 1 THEN
    IF TIMER - n05timer > release THEN '
        n05timer = 0
        LINE (150, 346)-(178, 434), WhtOff&, BF
        LINE (132, 434)-(191, 515), WhtOff&, BF
    END IF
END IF

IF n06flag = 1 THEN
    IF TIMER - n06timer > release THEN '
        n06timer = 0: LINE (183, 348)-(214, 429), BlkOff&, BF
    END IF
END IF

IF n07flag = 1 THEN
    IF TIMER - n07timer > release THEN '
        n07timer = 0
        LINE (219, 346)-(255, 434), WhtOff&, BF
        LINE (196, 434)-(255, 515), WhtOff&, BF
    END IF
END IF

IF n08flag = 1 THEN
    IF TIMER - n08timer > release THEN '
        n08timer = 0
        LINE (260, 346)-(295, 434), WhtOff&, BF
        LINE (260, 434)-(319, 515), WhtOff&, BF
    END IF
END IF

IF n09flag = 1 THEN
    IF TIMER - n09timer > release THEN '
        n09timer = 0: LINE (300, 348)-(332, 429), BlkOff&, BF
    END IF
END IF

IF n10flag = 1 THEN
    IF TIMER - n10timer > release THEN '
        n10timer = 0
        LINE (337, 346)-(370, 434), WhtOff&, BF
        LINE (324, 434)-(383, 515), WhtOff&, BF
    END IF
END IF

IF n11flag = 1 THEN
    IF TIMER - n11timer > release THEN '
        n11timer = 0: LINE (375, 348)-(406, 429), BlkOff&, BF
    END IF
END IF

IF n12flag = 1 THEN
    IF TIMER - n12timer > release THEN '
        n12timer = 0
        LINE (411, 346)-(447, 434), WhtOff&, BF
        LINE (387, 434)-(447, 515), WhtOff&, BF
    END IF
END IF

IF n13flag = 1 THEN
    IF TIMER - n13timer > release THEN '
        n13timer = 0
        LINE (451, 346)-(487, 434), WhtOff&, BF
        LINE (451, 434)-(511, 515), WhtOff&, BF
    END IF
END IF

IF n14flag = 1 THEN
    IF TIMER - n14timer > release THEN '
        n14timer = 0: LINE (492, 348)-(523, 429), BlkOff&, BF
    END IF
END IF

IF n15flag = 1 THEN
    IF TIMER - n15timer > release THEN '
        n15timer = 0
        LINE (528, 346)-(556, 434), WhtOff&, BF
        LINE (515, 434)-(575, 515), WhtOff&, BF
    END IF
END IF

IF n16flag = 1 THEN
    IF TIMER - n16timer > release THEN '
        n16timer = 0: LINE (560, 348)-(593, 429), BlkOff&, BF
    END IF
END IF

IF n17flag = 1 THEN
    IF TIMER - n17timer > release THEN '
        n17timer = 0
        LINE (598, 346)-(625, 434), WhtOff&, BF
        LINE (579, 434)-(639, 515), WhtOff&, BF
    END IF
END IF

IF n18flag = 1 THEN
    IF TIMER - n18timer > release THEN '
        n18timer = 0: LINE (630, 348)-(663, 429), BlkOff&, BF
    END IF
END IF

IF n19flag = 1 THEN
    IF TIMER - n19timer > release THEN '
        n19timer = 0
        LINE (667, 346)-(702, 434), WhtOff&, BF
        LINE (643, 434)-(702, 515), WhtOff&, BF
    END IF
END IF

IF n20flag = 1 THEN
    IF TIMER - n20timer > release THEN '
        n20timer = 0
        LINE (707, 346)-(743, 434), WhtOff&, BF
        LINE (707, 434)-(766, 515), WhtOff&, BF
    END IF
END IF

IF n21flag = 1 THEN
    IF TIMER - n21timer > release THEN '
        n21timer = 0: LINE (747, 348)-(779, 429), BlkOff&, BF
    END IF
END IF

IF n22flag = 1 THEN
    IF TIMER - n22timer > release THEN '
        n22timer = 0
        LINE (784, 346)-(817, 434), WhtOff&, BF
        LINE (771, 434)-(830, 515), WhtOff&, BF
    END IF
END IF

IF n23flag = 1 THEN
    IF TIMER - n23timer > release THEN '
        n23timer = 0: LINE (822, 348)-(854, 429), BlkOff&, BF
    END IF
END IF

IF n24flag = 1 THEN
    IF TIMER - n24timer > release THEN '
        n24timer = 0
        LINE (858, 346)-(894, 434), WhtOff&, BF
        LINE (835, 434)-(894, 515), WhtOff&, BF
    END IF
END IF

IF n25flag = 1 THEN
    IF TIMER - n25timer > release THEN '
        n25timer = 0
        LINE (5, 123)-(41, 210), WhtOff&, BF
        LINE (5, 211)-(64, 292), WhtOff&, BF
    END IF
END IF

IF n26flag = 1 THEN
    IF TIMER - n26timer > release THEN '
        n26timer = 0: LINE (45, 125)-(78, 207), BlkOff&, BF
    END IF
END IF

IF n27flag = 1 THEN
    IF TIMER - n27timer > release THEN '
        n27timer = 0
        LINE (82, 123)-(110, 210), WhtOff&, BF
        LINE (69, 211)-(128, 292), WhtOff&, BF
    END IF
END IF

IF n28flag = 1 THEN
    IF TIMER - n28timer > release THEN '
        n28timer = 0: LINE (114, 125)-(147, 207), BlkOff&, BF
    END IF
END IF

IF n29flag = 1 THEN
    IF TIMER - n29timer > release THEN '
        n29timer = 0
        LINE (151, 123)-(179, 210), WhtOff&, BF
        LINE (133, 211)-(192, 292), WhtOff&, BF
    END IF
END IF

IF n30flag = 1 THEN
    IF TIMER - n30timer > release THEN '
        n30timer = 0: LINE (184, 125)-(215, 207), BlkOff&, BF
    END IF
END IF

IF n31flag = 1 THEN
    IF TIMER - n31timer > release THEN '
        n31timer = 0
        LINE (220, 123)-(256, 210), WhtOff&, BF
        LINE (197, 211)-(256, 292), WhtOff&, BF
    END IF
END IF

IF n32flag = 1 THEN
    IF TIMER - n32timer > release THEN '
        n32timer = 0
        LINE (261, 123)-(296, 210), WhtOff&, BF
        LINE (261, 211)-(320, 292), WhtOff&, BF
    END IF
END IF

IF n33flag = 1 THEN
    IF TIMER - n33timer > release THEN '
        n33timer = 0: LINE (301, 125)-(332, 207), BlkOff&, BF
    END IF
END IF

IF n34flag = 1 THEN
    IF TIMER - n34timer > release THEN '
        n34timer = 0
        LINE (338, 123)-(371, 210), WhtOff&, BF
        LINE (325, 211)-(384, 292), WhtOff&, BF
    END IF
END IF

IF n35flag = 1 THEN
    IF TIMER - n35timer > release THEN '
        n35timer = 0: LINE (376, 125)-(407, 207), BlkOff&, BF
    END IF
END IF

IF n36flag = 1 THEN
    IF TIMER - n36timer > release THEN '
        n36timer = 0
        LINE (412, 123)-(448, 210), WhtOff&, BF
        LINE (388, 211)-(448, 292), WhtOff&, BF
    END IF
END IF

IF n37flag = 1 THEN
    IF TIMER - n37timer > release THEN '
        n37timer = 0
        LINE (452, 123)-(488, 210), WhtOff&, BF
        LINE (452, 211)-(512, 292), WhtOff&, BF
    END IF
END IF

IF n38flag = 1 THEN
    IF TIMER - n38timer > release THEN '
        n38timer = 0: LINE (493, 125)-(525, 207), BlkOff&, BF
    END IF
END IF

IF n39flag = 1 THEN
    IF TIMER - n39timer > release THEN '
        n39timer = 0
        LINE (529, 123)-(557, 210), WhtOff&, BF
        LINE (516, 211)-(576, 292), WhtOff&, BF
    END IF
END IF

IF n40flag = 1 THEN
    IF TIMER - n40timer > release THEN '
        n40timer = 0: LINE (561, 125)-(594, 207), BlkOff&, BF
    END IF
END IF

IF n41flag = 1 THEN
    IF TIMER - n41timer > release THEN '
        n41timer = 0
        LINE (599, 123)-(626, 210), WhtOff&, BF
        LINE (580, 211)-(640, 292), WhtOff&, BF
    END IF
END IF

IF n42flag = 1 THEN
    IF TIMER - n42timer > release THEN '
        n42timer = 0: LINE (631, 125)-(664, 207), BlkOff&, BF
    END IF
END IF

IF n43flag = 1 THEN
    IF TIMER - n43timer > release THEN '
        n43timer = 0
        LINE (668, 123)-(703, 210), WhtOff&, BF
        LINE (644, 211)-(703, 292), WhtOff&, BF
    END IF
END IF

IF n44flag = 1 THEN
    IF TIMER - n44timer > release THEN '
        n44timer = 0
        LINE (708, 123)-(744, 210), WhtOff&, BF
        LINE (708, 211)-(767, 292), WhtOff&, BF
    END IF
END IF

IF n45flag = 1 THEN
    IF TIMER - n45timer > release THEN '
        n45timer = 0: LINE (748, 125)-(780, 207), BlkOff&, BF
    END IF
END IF

IF n46flag = 1 THEN
    IF TIMER - n46timer > release THEN '
        n46timer = 0
        LINE (785, 123)-(818, 210), WhtOff&, BF
        LINE (772, 211)-(831, 292), WhtOff&, BF
    END IF
END IF

IF n47flag = 1 THEN
    IF TIMER - n47timer > release THEN '
        n47timer = 0: LINE (823, 125)-(855, 207), BlkOff&, BF
    END IF
END IF

IF n48flag = 1 THEN
    IF TIMER - n48timer > release THEN '
        n48timer = 0
        LINE (859, 123)-(895, 210), WhtOff&, BF
        LINE (836, 211)-(895, 292), WhtOff&, BF
    END IF
END IF

RETURN

'==========================================================
SaveScreen: 'save current screen image
'=========
scr1 = _MEMIMAGE(0): scr2 = _MEMNEW(scr1.SIZE)
_MEMCOPY scr1, scr1.OFFSET, scr1.SIZE TO scr2, scr2.OFFSET

RETURN

'==========================================================
RestoreScreen: 'restores screen image saved
'============
_MEMCOPY scr2, scr2.OFFSET, scr2.SIZE TO scr1, scr1.OFFSET
_MEMFREE scr1: _MEMFREE scr2

RETURN

'==========================================================
UpdateInfo: 'clears area and sets info at the top left
'=============
COLOR _RGB(163, 163, 175), _RGB(70, 95, 114)
LOCATE 1, 1: PRINT SPACE$(32);
LOCATE 2, 1: PRINT SPACE$(32);
IF song$ = "" THEN
    LOCATE 2, 3: PRINT " Song: (none)"
ELSE
    LOCATE 2, 3: PRINT " Song: "; UCASE$(song$);
END IF
LOCATE 3, 3: PRINT " Speed ="; speed; "   ";

RETURN

'==========================================================

SUB DoNote (keynum)
    'Plays the note$ sound, sets playing flag
    SELECT CASE keynum
        CASE 1: _SNDPLAYCOPY n01&
            n01flag = 1: n01timer = TIMER
            LINE (4, 346)-(40, 434), WhtOn&, BF
            LINE (4, 434)-(63, 515), WhtOn&, BF
        CASE 2: _SNDPLAYCOPY n02&
            n02flag = 1: n02timer = TIMER
            LINE (44, 348)-(76, 429), BlkOn&, BF
        CASE 3: _SNDPLAYCOPY n03&
            n03flag = 1: n03timer = TIMER
            LINE (81, 346)-(109, 434), WhtOn&, BF
            LINE (68, 434)-(127, 515), WhtOn&, BF
        CASE 4: _SNDPLAYCOPY n04&
            n04flag = 1: n04timer = TIMER
            LINE (113, 348)-(146, 429), BlkOn&, BF
        CASE 5: _SNDPLAYCOPY n05&
            n05flag = 1: n05timer = TIMER:
            LINE (150, 346)-(178, 434), WhtOn&, BF
            LINE (132, 434)-(191, 515), WhtOn&, BF
        CASE 6: _SNDPLAYCOPY n06&
            n06flag = 1: n06timer = TIMER
            LINE (183, 348)-(214, 429), BlkOn&, BF
        CASE 7: _SNDPLAYCOPY n07&
            n07flag = 1: n07timer = TIMER
            LINE (219, 346)-(255, 434), WhtOn&, BF
            LINE (196, 434)-(255, 515), WhtOn&, BF
        CASE 8: _SNDPLAYCOPY n08&
            n08flag = 1: n08timer = TIMER
            LINE (260, 346)-(295, 434), WhtOn&, BF
            LINE (260, 434)-(319, 515), WhtOn&, BF
        CASE 9: _SNDPLAYCOPY n09&
            n09flag = 1: n09timer = TIMER
            LINE (300, 348)-(332, 429), BlkOn&, BF
        CASE 10: _SNDPLAYCOPY n10&
            n10flag = 1: n10timer = TIMER
            LINE (337, 346)-(370, 434), WhtOn&, BF
            LINE (324, 434)-(383, 515), WhtOn&, BF
        CASE 11: _SNDPLAYCOPY n11&
            n11flag = 1: n11timer = TIMER
            LINE (375, 348)-(406, 429), BlkOn&, BF
        CASE 12: _SNDPLAYCOPY n12&
            n12flag = 1: n12timer = TIMER
            LINE (411, 346)-(447, 434), WhtOn&, BF
            LINE (387, 434)-(447, 515), WhtOn&, BF
        CASE 13: _SNDPLAYCOPY n13&
            n13flag = 1: n13timer = TIMER
            LINE (451, 346)-(487, 434), WhtOn&, BF
            LINE (451, 434)-(511, 515), WhtOn&, BF
        CASE 14: _SNDPLAYCOPY n14&
            n14flag = 1: n14timer = TIMER
            LINE (492, 348)-(523, 429), BlkOn&, BF
        CASE 15: _SNDPLAYCOPY n15&
            n15flag = 1: n15timer = TIMER
            LINE (528, 346)-(556, 434), WhtOn&, BF
            LINE (515, 434)-(575, 515), WhtOn&, BF
        CASE 16: _SNDPLAYCOPY n16&
            n16flag = 1: n16timer = TIMER
            LINE (560, 348)-(593, 429), BlkOn&, BF
        CASE 17: _SNDPLAYCOPY n17&
            n17flag = 1: n17timer = TIMER
            LINE (598, 346)-(625, 434), WhtOn&, BF
            LINE (579, 434)-(639, 515), WhtOn&, BF
        CASE 18: _SNDPLAYCOPY n18&
            n18flag = 1: n18timer = TIMER
            LINE (630, 348)-(663, 429), BlkOn&, BF
        CASE 19: _SNDPLAYCOPY n19&
            n19flag = 1: n19timer = TIMER
            LINE (667, 346)-(702, 434), WhtOn&, BF
            LINE (643, 434)-(702, 515), WhtOn&, BF
        CASE 20: _SNDPLAYCOPY n20&
            n20flag = 1: n20timer = TIMER
            LINE (707, 346)-(743, 434), WhtOn&, BF
            LINE (707, 434)-(766, 515), WhtOn&, BF
        CASE 21: _SNDPLAYCOPY n21&
            n21flag = 1: n21timer = TIMER
            LINE (747, 348)-(779, 429), BlkOn&, BF
        CASE 22: _SNDPLAYCOPY n22&
            n22flag = 1: n22timer = TIMER
            LINE (784, 346)-(817, 434), WhtOn&, BF
            LINE (771, 434)-(830, 515), WhtOn&, BF
        CASE 23: _SNDPLAYCOPY n23&
            n23flag = 1: n23timer = TIMER
            LINE (822, 348)-(854, 429), BlkOn&, BF
        CASE 24: _SNDPLAYCOPY n24&
            n24flag = 1: n24timer = TIMER
            LINE (858, 346)-(894, 434), WhtOn&, BF
            LINE (835, 434)-(894, 515), WhtOn&, BF
        CASE 25: _SNDPLAYCOPY n25&
            n25flag = 1: n25timer = TIMER
            LINE (5, 123)-(41, 210), WhtOn&, BF
            LINE (5, 211)-(64, 292), WhtOn&, BF
        CASE 26: _SNDPLAYCOPY n26&
            n26flag = 1: n26timer = TIMER
            LINE (45, 125)-(78, 207), BlkOn&, BF
        CASE 27: _SNDPLAYCOPY n27&
            n27flag = 1: n27timer = TIMER
            LINE (82, 123)-(110, 210), WhtOn&, BF
            LINE (69, 211)-(128, 292), WhtOn&, BF
        CASE 28: _SNDPLAYCOPY n28&
            n28flag = 1: n28timer = TIMER
            LINE (114, 125)-(147, 207), BlkOn&, BF
        CASE 29: _SNDPLAYCOPY n29&
            n29flag = 1: n29timer = TIMER
            LINE (151, 123)-(179, 210), WhtOn&, BF
            LINE (133, 211)-(192, 292), WhtOn&, BF
        CASE 30: _SNDPLAYCOPY n30&
            n30flag = 1: n30timer = TIMER
            LINE (184, 125)-(215, 207), BlkOn&, BF
        CASE 31: _SNDPLAYCOPY n31&
            n31flag = 1: n31timer = TIMER
            LINE (220, 123)-(256, 210), WhtOn&, BF
            LINE (197, 211)-(256, 292), WhtOn&, BF
        CASE 32: _SNDPLAYCOPY n32&
            n32flag = 1: n32timer = TIMER
            LINE (261, 123)-(296, 210), WhtOn&, BF
            LINE (261, 211)-(320, 292), WhtOn&, BF
        CASE 33: _SNDPLAYCOPY n33&
            n33flag = 1: n33timer = TIMER
            LINE (301, 125)-(332, 207), BlkOn&, BF
        CASE 34: _SNDPLAYCOPY n34&
            n34flag = 1: n34timer = TIMER
            LINE (338, 123)-(371, 210), WhtOn&, BF
            LINE (325, 211)-(384, 292), WhtOn&, BF
        CASE 35: _SNDPLAYCOPY n35&
            n35flag = 1: n35timer = TIMER
            LINE (376, 125)-(407, 207), BlkOn&, BF
        CASE 36: _SNDPLAYCOPY n36&
            n36flag = 1: n36timer = TIMER
            LINE (412, 123)-(448, 210), WhtOn&, BF
            LINE (388, 211)-(448, 292), WhtOn&, BF
        CASE 37: _SNDPLAYCOPY n37&
            n37flag = 1: n37timer = TIMER
            LINE (452, 123)-(488, 210), WhtOn&, BF
            LINE (452, 211)-(512, 292), WhtOn&, BF
        CASE 38: _SNDPLAYCOPY n38&
            n38flag = 1: n38timer = TIMER
            LINE (493, 125)-(525, 207), BlkOn&, BF
        CASE 39: _SNDPLAYCOPY n39&
            n39flag = 1: n39timer = TIMER
            LINE (529, 123)-(557, 210), WhtOn&, BF
            LINE (516, 211)-(576, 292), WhtOn&, BF
        CASE 40: _SNDPLAYCOPY n40&
            n40flag = 1: n40timer = TIMER
            LINE (561, 125)-(594, 207), BlkOn&, BF
        CASE 41: _SNDPLAYCOPY n41&
            n41flag = 1: n41timer = TIMER
            LINE (599, 123)-(626, 210), WhtOn&, BF
            LINE (580, 211)-(640, 292), WhtOn&, BF
        CASE 42: _SNDPLAYCOPY n42&
            n42flag = 1: n42timer = TIMER
            LINE (632, 125)-(664, 207), BlkOn&, BF
        CASE 43: _SNDPLAYCOPY n43&
            n43flag = 1: n43timer = TIMER
            LINE (668, 123)-(703, 210), WhtOn&, BF
            LINE (644, 211)-(703, 292), WhtOn&, BF
        CASE 44: _SNDPLAYCOPY n44&
            n44flag = 1: n44timer = TIMER
            LINE (708, 123)-(744, 210), WhtOn&, BF
            LINE (708, 211)-(767, 292), WhtOn&, BF
        CASE 45: _SNDPLAYCOPY n45&
            n45flag = 1: n45timer = TIMER
            LINE (748, 125)-(780, 207), BlkOn&, BF
        CASE 46: _SNDPLAYCOPY n46&
            n46flag = 1: n46timer = TIMER
            LINE (785, 123)-(818, 210), WhtOn&, BF
            LINE (772, 211)-(831, 292), WhtOn&, BF
        CASE 47: _SNDPLAYCOPY n47&
            n47flag = 1: n47timer = TIMER
            LINE (823, 125)-(855, 207), BlkOn&, BF
        CASE 48: _SNDPLAYCOPY n48&
            n48flag = 1: n48timer = TIMER
            LINE (859, 123)-(895, 210), WhtOn&, BF
            LINE (836, 211)-(895, 292), WhtOn&, BF

    END SELECT

END SUB

'=======================================================

SUB DrawBox 'Draws the litte info box.  Used often
    LINE (250, 200)-(650, 270), _RGB(70, 95, 114), BF
    LINE (252, 202)-(648, 268), _RGB(255, 255, 255), B
    COLOR _RGB(255, 255, 255), _RGB(70, 95, 114)
END SUB





