'
'                                QuickBasic
'                              Enhanced  Draw
'                               version 1.0A
'
'                          by Angelo Mottola soft
'                          (C) copyright Jan 1997
'
' Warning: this program was made in QB45. It hasn't been tested on QBASIC.
' Also, is pushes QB memory to the limit; if you have problems with "Out
' of memory" messages, try to remove some TSRs and then restart QB, or
' simply load QB with /AH option.
'
'                          Press SHIFT-F5 to run.
'
' If you notice a bug or you just want to do a comment to this program,
' please send me an E-Mail at:
'                               ------------
'                                eri@cdc.it
'                               ------------
' If you like my work, take a look at my last game, WetSpot: it is located
' at: http://www.qbasic.com
'
' Enjoy it !
'

DEFINT A-Z

'$DYNAMIC

TYPE RegTypeX
     ax    AS INTEGER
     Bx    AS INTEGER
     cx    AS INTEGER
     Dx    AS INTEGER
     bp    AS INTEGER
     Si    AS INTEGER
     di    AS INTEGER
     flags AS INTEGER
     ds    AS INTEGER
     es    AS INTEGER
END TYPE

TYPE FileFindBuf
    DOS            AS STRING * 19
    CreateTime     AS STRING * 1
    Attributes     AS INTEGER
    AccessTime     AS INTEGER
    AccessDate     AS INTEGER
    FileSize       AS LONG
    FileName       AS STRING * 13
END TYPE

TYPE DTAdata                     'used by DOS services
  Reserved  AS STRING * 21       'reserved for use by DOS
  Attribute AS STRING * 1        'the file's attribute
  FileTime  AS STRING * 2        'the file's time
  Filedate  AS STRING * 2        'the file's date
  FileSize  AS LONG              'the file's size
  FileName  AS STRING * 13       'the file's name
END TYPE

TYPE ButtonType
  LineAt AS INTEGER
  xStart AS INTEGER
  xEnd AS INTEGER
  Page AS INTEGER
END TYPE

DECLARE SUB MouseStatus (Lb%, Rb%, x%, y%)
DECLARE SUB MouseRange (x1%, y1%, x2%, y2%)
DECLARE SUB MousePut (x%, y%)
DECLARE SUB MouseHide ()
DECLARE SUB MouseDriver (ax%, Bx%, cx%, Dx%)
DECLARE SUB MouseShow ()
DECLARE SUB PalSet (C, R, G, B)
DECLARE SUB PalGet (C, R, G, B)
DECLARE SUB ToolOn ()
DECLARE SUB DrawMenu ()
DECLARE SUB SubMenu (SelectedMenu)
DECLARE SUB NewFile ()
DECLARE SUB LoadFile ()
DECLARE SUB SaveFile ()
DECLARE SUB DeleteFile ()
DECLARE SUB DrawWindow (x1, y1, x2, y2, t$)
DECLARE SUB DrawButton (x1, y1, t$)
DECLARE SUB ABSOLUTE (ax, Bx, cx, Dx, addr)
DECLARE SUB interruptx (intNum AS INTEGER, inreg AS RegTypeX, outreg AS RegTypeX)
DECLARE SUB ChangeDrive (drive$)
DECLARE SUB GetDir (EntryName$(), Extension$(), EntryType(), DirNum, Path$, Status)
DECLARE SUB Sort (A$(), Low%, High%)
DECLARE SUB About ()
DECLARE SUB ZoomEdit ()
DECLARE SUB InvertBlock ()
DECLARE SUB ShiftBlock ()
DECLARE SUB RotateBlock ()
DECLARE SUB ModifyBlock ()
DECLARE SUB MoveBlock (Mode)
DECLARE SUB HandleBlk ()
DECLARE SUB Preferences ()
DECLARE SUB EditPalette ()
DECLARE SUB Help ()
DECLARE SUB OpenPage (Page)
DECLARE FUNCTION MouseInit% ()
DECLARE FUNCTION Menu ()
DECLARE FUNCTION Quit ()
DECLARE FUNCTION CurrentPath$ ()
DECLARE FUNCTION CurrentDrive$ ()
DECLARE FUNCTION RealPath$ ()
DECLARE FUNCTION LogicalDrives (drive$)
DECLARE FUNCTION NumDrives ()
DECLARE FUNCTION FloppyDriveReady% (drive$)
DECLARE FUNCTION SelectFile$ (Mode)
DECLARE FUNCTION Exist (Nam$, SearchA)
DECLARE FUNCTION CountSpace! ()

CLEAR , , 4000

CONST TRUE = -1, FALSE = NOT TRUE, FILE = 0, DIRECTORY = 1
CONST PENCIL = 0, LINER = 1, BOX = 2, BOXFULL = 3, FILLER = 4
CONST ELLIPSE = 5, RUBBER = 6, SPRAY = 7, LENS = 8, INVERT = 9
CONST SHIFT = 10, ROTATE = 11, MODIFY = 12, COPY = 13, MOVE = 14

DIM SHARED Mouse$: Mouse$ = SPACE$(57)
DIM SHARED FileName$, x, y, Lb, Rb
DIM SHARED Oldx, Oldy, x1, y1, RubX, RubY, SprayX, SprayY, SprayI
DIM SHARED Col, Tool, CoordBox, JustPressed, Pointed, FCol, BCol, SaveSpace
DIM SHARED Video&(16000), CoordBox&(1000), SelBox&(500)
DIM SHARED Temp1&(1000), Temp2&(1000)
DIM SHARED BlkExt AS STRING * 3
DIM SHARED BinExt AS STRING * 3
DIM SHARED PalExt AS STRING * 3
DIM SHARED Status, DirNum, OriginalPath$
DIM SHARED HelpPage, Lin(40) AS STRING * 33
DIM SHARED NumLines, NumButtons, Button(10) AS ButtonType

OriginalPath$ = RealPath$

BinExt = "P13": BlkExt = "BLK": PalExt = "PAL"
FCol = 15: BCol = 0: SaveSpace = TRUE

ON ERROR GOTO ErrorHandle

SCREEN 13
PalSet FCol, 0, 0, 0
LINE (0, 0)-(79, 7), FCol, BF
GET (0, 0)-(79, 7), SelBox&
CLS
PalSet FCol, 63, 63, 63
FOR i% = 1 TO 57:  READ A$:  H$ = CHR$(VAL("&H" + A$))
MID$(Mouse$, i%, 1) = H$: NEXT i%
DATA 55,89,E5,8B,5E,0C,8B,07,50,8B,5E,0A,8B,07,50,8B
DATA 5E,08,8B,0F,8B,5E,06,8B,17,5B,58,1E,07,CD,33,53
DATA 8B,5E,0C,89,07,58,8B,5E,0A,89,07,8B,5E,08,89,0F
DATA 8B,5E,06,89,17,5D,CA,08,00
RESTORE
ms% = MouseInit%
IF NOT ms% THEN
  SCREEN 0: WIDTH 80
  PRINT "Mouse not found"
  END
END IF

PALETTE
LINE (50, 48)-(269, 151), FCol, B
LINE (52, 50)-(267, 149), FCol, B
LOCATE 8, 16: PRINT "QuickBasic"
LOCATE 9, 14: PRINT "Enhanced  DRAW"
LOCATE 11, 15: PRINT "version 1.0A"
LOCATE 13, 10: PRINT "by Angelo Mottola soft"
LOCATE 14, 10: PRINT "(C) copyright Jan 1997"
LOCATE 17, 20: PRINT "OK"
LINE (130, 122)-(189, 140), FCol, B
MouseRange 0, 0, 639, 199
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF x \ 2 > 130 AND x \ 2 < 189 THEN
      IF y > 122 AND y < 140 THEN
        EXIT DO
      END IF
    END IF
  END IF
LOOP
MouseHide
LINE (50, 48)-(269, 151), BCol, BF

FileName$ = "NONAME." + BinExt
RubX = 4: RubY = 4: SprayX = 20: SprayY = 20: SprayI = 10
Tool = PENCIL: Col = 15
GET (0, 0)-(319, 199), Video&
GET (0, 0)-(319, 9), CoordBox&
LINE (0, 190)-(319, 190), FCol
LOCATE 25, 1
COLOR FCol: PRINT USING "x:### y:###  Color:"; x \ 2; y;
COLOR Col: PRINT USING "###"; Col; : COLOR FCol: PRINT ",";
COLOR POINT(x \ 2, y): PRINT USING "###"; POINT(x \ 2, y);
COLOR FCol: LOCATE , 29: PRINT FileName$;
JustPressed = 0

'Main loop
Main:
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
PUT (0, 0), Video&, PSET
IF y > 170 THEN LINE (0, 9)-(319, 9), FCol ELSE LINE (0, 190)-(319, 190), FCol
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  '
  IF x <> Oldx OR y <> Oldy THEN
    SELECT CASE Tool
    CASE LINER, BOX, BOXFULL, ELLIPSE, RUBBER, LENS, INVERT, SHIFT, ROTATE, MODIFY, COPY, MOVE
      IF Pointed = 1 THEN
        MouseHide
        PUT (0, 0), Video&, PSET
        SELECT CASE Tool
        CASE LINER
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          LINE (x1 \ 2, y1)-(x \ 2, y), Col
        CASE BOX
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          LINE (x1 \ 2, y1)-(x \ 2, y), Col, B
        CASE INVERT, SHIFT, MODIFY, COPY, MOVE
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          LINE (x1 \ 2, y1)-(x \ 2, y), FCol, B
        CASE BOXFULL
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          LINE (x1 \ 2, y1)-(x \ 2, y), Col, BF
        CASE ELLIPSE
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          r1 = ABS((x1 \ 2) - (x \ 2)) \ 2: r2 = ABS(y1 - y) \ 2
          IF r1 > r2 THEN R = r1 ELSE R = r2
          Dy = ABS(y1 - y): Dx = ABS((x1 \ 2) - (x \ 2))
          IF Dx = 0 THEN Aspect! = 1000000 ELSE Aspect! = Dy / Dx
          CIRCLE ((x1 \ 2) + r1, y1 + r2), R, Col, , , Aspect!
        CASE ROTATE
          PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
          LINE (x1 \ 2, y1)-((x1 \ 2) + (y - y1), y), FCol, B
        END SELECT
        MouseShow
      END IF
      IF Tool = RUBBER THEN
        MouseHide
        PUT (0, 0), Video&, PSET
        LINE ((x \ 2) - RubX, y - RubY)-(x \ 2, y), FCol, B
        MouseShow
      END IF
      IF Tool = LENS THEN
        MouseHide
        PUT (0, 0), Video&, PSET
        LINE ((x \ 2) - 39, y - 33)-(x \ 2, y), FCol, B
        MouseShow
      END IF
    END SELECT
    '
    IF y > 170 AND CoordBox = 0 THEN
      MouseHide
      CoordBox = 1
      PUT (0, 190), CoordBox&, PSET
      GET (0, 0)-(319, 9), CoordBox&
      LINE (0, 0)-(319, 9), BCol, BF
      LINE (0, 9)-(319, 9), FCol
      IF Tool = PENCIL AND JustPressed = 1 THEN LINE (Oldx \ 2, Oldy)-(x \ 2, y), Col
      MouseShow
    ELSEIF y < 170 AND CoordBox = 1 THEN
      MouseHide
      CoordBox = 0
      PUT (0, 0), CoordBox&, PSET
      GET (0, 190)-(319, 199), CoordBox&
      LINE (0, 190)-(319, 199), 0, BF
      LINE (0, 190)-(319, 190), FCol
      IF Tool = PENCIL AND JustPressed = 1 THEN LINE (Oldx \ 2, Oldy)-(x \ 2, y), Col
      MouseShow
    END IF
    IF Tool <> PENCIL THEN
      IF CoordBox = 0 THEN
        LINE (0, 191)-(319, 199), BCol, BF
        LINE (0, 190)-(319, 190), FCol
      ELSE
        LINE (0, 0)-(319, 8), BCol, BF
        LINE (0, 9)-(319, 9), FCol
      END IF
    END IF
    IF CoordBox = 0 THEN LOCATE 25, 1 ELSE LOCATE 1, 1
    COLOR FCol: PRINT USING "x:### y:###  Color:"; x \ 2; y;
    COLOR Col: PRINT USING "###"; Col; : COLOR FCol: PRINT ",";
    COLOR POINT(x \ 2, y): PRINT USING "###"; POINT(x \ 2, y);
    COLOR FCol: LOCATE , 29: PRINT FileName$;
  END IF
  IF Lb THEN
    WAIT &H3DA, 8
    ToolOn
  ELSE
    JustPressed = 0
  END IF
  IF Rb THEN
    SELECT CASE Tool
    CASE LINER, BOX, BOXFULL, ELLIPSE, LENS, RUBBER, INVERT, SHIFT, ROTATE, MODIFY, COPY, MOVE
      MouseHide
      PUT (0, 0), Video&, PSET
      MouseShow
    END SELECT
    IF Pointed = 1 THEN Pointed = 0
    Tool = Menu
    t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
  END IF
  Oldx = x: Oldy = y
LOOP

END

ErrorHandle:
MouseHide
PUT (0, 0), Video&, PSET
DrawWindow 5, 10, 35, 16, "Error!"
COLOR FCol
SELECT CASE ERR
CASE 53
  LOCATE 12, 13: PRINT "File not found"
CASE 57
  LOCATE 12, 12: PRINT "Device I/O error"
CASE 61
  LOCATE 12, 14: PRINT "Disk is full"
CASE 54, 62
  LOCATE 12, 16: PRINT "Bad file"
  CLOSE
CASE 66
  LOCATE 12, 8: PRINT "Unable to open help file"
CASE 68
  LOCATE 12, 12: PRINT "Device not found"
CASE 70
  LOCATE 12, 8: PRINT "Disk is write protected"
CASE 71
  LOCATE 12, 13: PRINT "Disk not ready"
CASE 76
  LOCATE 12, 13: PRINT "Path not found"
CASE ELSE
  SCREEN 0: WIDTH 80
  PRINT "Internal program error (" + STR$(ERR) + " )"
  PRINT : END
END SELECT
DrawButton 17, 15, "  OK  "
MouseShow
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 108 AND y < 123 THEN
      IF x \ 2 > 124 AND x \ 2 < 187 THEN EXIT DO
    END IF
  END IF
LOOP
Tool = PENCIL
MouseHide
RESUME Main

REM $STATIC
SUB About
'
MouseHide
PUT (0, 0), Video&, PSET
DrawWindow 5, 5, 36, 20, "About"
COLOR FCol
LOCATE 8, 16: PRINT "QuickBasic"
LOCATE 9, 14: PRINT "Enhanced  DRAW"
LOCATE 11, 15: PRINT "version 1.0A"
LOCATE 13, 6: PRINT "Programmed by Angelo Mottola"
LOCATE 14, 6: PRINT "Mouse routines by Unknown"
LOCATE 15, 6: PRINT "Dir routines by Rich Geldreich"
LOCATE 17, 6: PRINT "Free mem:" + STR$(FRE(-1)) + " bytes"
DrawButton 18, 19, "  OK  "
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 140 AND y < 155 THEN
      IF x \ 2 > 132 AND x \ 2 < 195 THEN EXIT DO
    END IF
  END IF
LOOP

END SUB

'
SUB ChangeDrive (drive$)
    DIM inreg AS RegTypeX
    inreg.ax = &HE00
    inreg.Dx = ASC(drive$) - 65
    CALL interrupt(&H21, inreg, inreg)
END SUB

FUNCTION CountSpace!
'
Lines! = 0
FOR i = 199 TO 0 STEP -1
  DataBlock = FALSE
  FOR ii = 0 TO 319
    IF POINT(ii, i) <> 0 THEN DataBlock = TRUE: EXIT FOR
  NEXT ii
  IF DataBlock = TRUE THEN Lines! = i + 1: EXIT FOR
NEXT i
IF Lines! = 0 THEN Lines! = 1
CountSpace! = 320 * Lines!
     
END FUNCTION

'
FUNCTION CurrentDrive$
    DIM inreg AS RegTypeX
    inreg.ax = &H1900
    CALL interrupt(&H21, inreg, inreg)
    CurrentDrive$ = CHR$(65 + inreg.ax MOD 256)
END FUNCTION

FUNCTION CurrentPath$
        DIM inreg AS RegTypeX
        DIM PathSize AS STRING * 64
        inreg.ax = &H4700
        inreg.Dx = ASC(CurrentDrive$) - 64
        inreg.ds = VARSEG(PathSize)
        inreg.Si = VARPTR(PathSize)
        CALL interruptx(&H21, inreg, inreg)
        CurrentPath$ = LEFT$(PathSize, INSTR(PathSize, CHR$(0)) - 1)
END FUNCTION

SUB DeleteFile
'
ToDel$ = SelectFile$(3)
IF ToDel$ = "" THEN EXIT SUB
IF NOT Exist(ToDel$, 0) THEN ERROR 53
MouseHide
PUT (0, 0), Video&, PSET
DrawWindow 5, 9, 35, 16, "Deleting " + ToDel$
LOCATE 11, 8: PRINT "WARNING: You are about to"
LOCATE 12, 7: PRINT "delete an image. Continue ?"
DrawButton 12, 15, "  OK  "
DrawButton 22, 15, "CANCEL"
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 108 AND y < 123 THEN
      IF x \ 2 > 84 AND x \ 2 < 147 THEN
        IF INSTR(ToDel$, ".") <> 0 THEN
          ToDelx$ = LEFT$(ToDel$, INSTR(ToDel$, ".") - 1)
        ELSE
          ToDelx$ = ToDel$
        END IF
        IF Exist(ToDelx$ + "." + PalExt, 0) THEN KILL ToDelx$ + "." + PalExt
        KILL ToDel$
        EXIT DO
      END IF
      IF x \ 2 > 164 AND x \ 2 < 227 THEN EXIT DO
    END IF
  END IF
LOOP

END SUB

SUB DrawButton (x1, y1, t$)
'
LINE (((x1 - 1) * 8) - 5, ((y1 - 1) * 8) - 5)-(((x1 - 2 + LEN(t$)) * 8) + 12, ((y1 - 1) * 8) + 11), BCol, BF
LINE (((x1 - 1) * 8) - 4, ((y1 - 1) * 8) - 4)-(((x1 - 2 + LEN(t$)) * 8) + 11, ((y1 - 1) * 8) + 10), FCol, B
LOCATE y1, x1: COLOR FCol: PRINT t$

END SUB

SUB DrawMenu
'
MouseHide
LINE (0, 0)-(319, 9), BCol, BF
LINE (0, 9)-(319, 9), FCol
LOCATE 1, 1: PRINT " File      Tools     Block     Options"
LINE (0, 10)-(45, 199), BCol, BF
LINE (0, 11)-(44, 175), FCol, B
LINE (0, 175)-(44, 199), FCol, B
LOCATE 24, 2: PRINT "#"; : PRINT USING "###"; Col;
LINE (4, 177)-(40, 182), Col, BF
FOR i = 0 TO 255
  LINE (((i \ 32) * 5) + 3, ((i MOD 32) * 5) + 14)-(((i \ 32) * 5) + 6, ((i MOD 32) * 5) + 17), i, BF
NEXT i
LINE (((Col \ 32) * 5) + 2, ((Col MOD 32) * 5) + 13)-(((Col \ 32) * 5) + 7, ((Col MOD 32) * 5) + 18), FCol, B
MouseShow

END SUB

SUB DrawWindow (x1, y1, x2, y2, t$)
'
LINE (((x1 - 1) * 8) - 5, ((y1 - 1) * 8) - 3)-(((x2 - 1) * 8) + 12, ((y2 - 1) * 8) + 12), BCol, BF
LINE (((x1 - 1) * 8) - 4, ((y1 - 1) * 8) - 2)-(((x2 - 1) * 8) + 11, ((y2 - 1) * 8) + 11), FCol, B
LINE (((x1 - 1) * 8) - 2, ((y1 - 1) * 8) + 9)-(((x2 - 1) * 8) + 9, ((y2 - 1) * 8) + 9), FCol, B
LOCATE y1, x1 + ((x2 - x1 - LEN(t$)) \ 2) + 1
COLOR FCol: PRINT t$

END SUB

SUB EditPalette
'
MouseHide
DrawWindow 9, 4, 32, 21, "Edit palette"
LINE (77, 38)-(241, 82), FCol, B
FOR i = 0 TO 255
  LINE (80 + ((i MOD 32) * 5), 41 + ((i \ 32) * 5))-(83 + ((i MOD 32) * 5), 44 + ((i \ 32) * 5)), i, BF
NEXT i
LOCATE 13, 11: PRINT "RED"
LOCATE 15, 11: PRINT "GRN"
LOCATE 17, 11: PRINT "BLU"
LINE (112, 94)-(179, 104), FCol, B
LINE (112, 110)-(179, 120), FCol, B
LINE (112, 126)-(179, 136), FCol, B
CurCol = 15
LINE (79 + ((CurCol MOD 32) * 5), 40 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5)), FCol, B
LOCATE 13, 26: PRINT "#"; : PRINT USING "###"; CurCol
LINE (192, 94)-(239, 136), FCol, B
LINE (194, 104)-(237, 134), CurCol, BF
DrawButton 18, 20, "  OK  "
PalGet CurCol, R, G, B
LINE (114 + R, 96)-(114 + R, 102), FCol
LINE (114 + G, 112)-(114 + G, 118), FCol
LINE (114 + B, 128)-(114 + B, 134), FCol
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 41 AND y < 81 THEN
      IF x \ 2 > 79 AND x \ 2 < 239 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (79 + ((CurCol MOD 32) * 5), 40 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5)), BCol, B
        CurCol = (((y - 41) \ 5) * 32) + (((x \ 2) - 80) \ 5)
        LINE (79 + ((CurCol MOD 32) * 5), 40 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5)), FCol, B
        LINE (194, 104)-(237, 134), CurCol, BF
        LINE (114 + R, 96)-(114 + R, 102), BCol
        LINE (114 + G, 112)-(114 + G, 118), BCol
        LINE (114 + B, 128)-(114 + B, 134), BCol
        PalGet CurCol, R, G, B
        LINE (114 + R, 96)-(114 + R, 102), FCol
        LINE (114 + G, 112)-(114 + G, 118), FCol
        LINE (114 + B, 128)-(114 + B, 134), FCol
        MouseShow
      END IF
    END IF
    IF x \ 2 > 113 AND x \ 2 < 178 THEN
      IF y > 94 AND y < 104 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (114 + R, 96)-(114 + R, 102), BCol
        R = (x \ 2) - 114
        LINE (114 + R, 96)-(114 + R, 102), FCol
        PalSet CurCol, R, G, B
        MouseShow
      END IF
      IF y > 110 AND y < 120 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (114 + G, 112)-(114 + G, 118), BCol
        G = (x \ 2) - 114
        LINE (114 + G, 112)-(114 + G, 118), FCol
        PalSet CurCol, R, G, B
        MouseShow
      END IF
      IF y > 126 AND y < 136 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (114 + B, 128)-(114 + B, 134), BCol
        B = (x \ 2) - 114
        LINE (114 + B, 128)-(114 + B, 134), FCol
        PalSet CurCol, R, G, B
        MouseShow
      END IF
    END IF
    IF x \ 2 > 132 AND x \ 2 < 187 THEN
      IF y > 148 AND y < 163 THEN EXIT DO
    END IF
  END IF
LOOP

END SUB

FUNCTION Exist% (Name$, SearchAttrb%)
DIM inreg AS RegTypeX, outreg AS RegTypeX
DIM DTA AS DTAdata
seed$ = LTRIM$(RTRIM$(UCASE$(Name$)))

IF SearchAttrb% AND 8 THEN  ' Volume label check
  IF NOT (INSTR(seed$, ".")) THEN
    FOR i = LEN(seed$) TO 1 STEP -1
      IF MID$(seed$, i, 1) = ":" OR MID$(seed$, i, 1) = "\" OR i = 1 THEN
        IF LEN(MID$(seed$, i + 1, LEN(seed$) - i)) > 8 THEN
          IF i = 1 THEN i = 0
          seed$ = LEFT$(seed$, i) + MID$(seed$, i + 1, 8) + "." + MID$(seed$, i + 9, LEN(seed$) - i)
        END IF
        i = 1
      END IF
    NEXT i
  END IF
END IF

IF SearchAttrb% = 0 THEN SearchAttrb% = 39
IF INSTR(seed$, ":") THEN
  drive$ = LEFT$(seed$, 1)
ELSE
  drive$ = "@"
END IF

IF NOT FloppyDriveReady(drive$) THEN
  SearchAttrb% = -1
  Exist% = 0
  EXIT FUNCTION
END IF

inreg.Dx = VARPTR(DTA)
inreg.ds = VARSEG(DTA)
inreg.ax = &H1A00
CALL interruptx(&H21, inreg, outreg)

seed$ = seed$ + CHR$(0)
inreg.ax = &H4E00
inreg.cx = SearchAttrb%
inreg.Dx = SADD(seed$)
inreg.ds = VARSEG(seed$)
CALL interruptx(&H21, inreg, outreg)

IF (outreg.flags AND 1) THEN
  SearchAttrb% = 0
  Exist% = 0
ELSE
  Exist% = -1
END IF

END FUNCTION

 FUNCTION FloppyDriveReady% (drive$)
 DIM inreg AS RegTypeX, outreg AS RegTypeX

 ' This function may also be used independently from
 ' the Exist% function. It returns -1, true if the
 ' drive is ready, or 0, false, if the drive is not
 ' ready, or the drive letter is an invalid drive.

 drive% = (ASC(drive$) OR 32) - 97

 'reset floppy drive
 inreg.ax = 0
 inreg.Dx = drive%
 CALL interruptx(&H13, inreg, outreg)

 inreg.ax = &H401     'verify disk sector
 inreg.cx = &H101
 inreg.Dx = drive%
 CALL interruptx(&H13, inreg, inreg)
 'call the interrupt twice since if a disk has just been
 'inserted, the first time gives a wrong answer
 inreg.ax = &H401
 inreg.cx = &H101
 inreg.Dx = drive%
 CALL interruptx(&H13, inreg, outreg)

 'if it was a hard disk we just checked forget the whole thing
 IF outreg.ax AND 256 THEN
   inreg.ax = &H1C00      ' check drive type
   inreg.Dx = drive% + 1  ' diff. drive number system must add 1
   CALL interruptx(&H21, inreg, outreg)
   ' check if drive was a valid drive letter.
   IF (outreg.ax AND &HFF) = &HFF THEN HardCheck = 0 ELSE HardCheck = -1
 END IF

 FloppyDriveReady% = ((outreg.flags AND 1) = 0) OR HardCheck

 END FUNCTION

SUB GetDir (EntryName$(), Extension$(), EntryType(), DirNum, Path$, Status)

DIM inreg AS RegTypeX, outreg AS RegTypeX
DIM Buffer AS FileFindBuf
DirNum = 0
inreg.ax = &H1A00
inreg.ds = VARSEG(Buffer)
inreg.Dx = VARPTR(Buffer)
CALL interrupt(&H21, inreg, outreg)
inreg.ax = &H4E00
inreg.cx = 16
Npath$ = Path$ + CHR$(0)
inreg.Dx = SADD(Npath$)
CALL interruptx(&H21, inreg, outreg)
FirstFM = (outreg.ax AND &HF)
IF outreg.flags AND 1 THEN
  Status = TRUE
  EXIT SUB
ELSE
  Status = FALSE
END IF
IF FirstFM = 0 THEN
  GOSUB MakeFile
  DO
    inreg.ax = &H4F00
    inreg.Dx = SADD(Npath$)
    CALL interrupt(&H21, inreg, outreg)
    NextFM = outreg.ax AND &HF
    IF NextFM = 0 THEN
      GOSUB MakeFile
    END IF
  LOOP WHILE NextFM = 0
END IF
EXIT SUB

MakeFile:
IF LEFT$(Buffer.FileName, 1) = "." THEN
  RETURN
END IF
Entry$ = RTRIM$(Buffer.FileName)
IF Buffer.Attributes = 4096 THEN
  EntryName$ = RTRIM$(LEFT$(Entry$, 8))
  EntryType = DIRECTORY
ELSE
  IF INSTR(Entry$, ".") = 0 THEN
    EntryName$ = RTRIM$(LEFT$(Entry$, 8))
    Extension$ = ""
  ELSE
    EntryName$ = LEFT$(Entry$, INSTR(Entry$, ".") - 1)
    Extension$ = RTRIM$(LEFT$(MID$(Entry$, INSTR(Entry$, ".") + 1), 3))
  END IF
  EntryType = FILE
END IF
EntryName$(DirNum) = EntryName$
Extension$(DirNum) = Extension$
EntryType(DirNum) = EntryType
DirNum = DirNum + 1
IF DirNum > 200 THEN DirNum = 200
Buffer.Attributes = 0
Buffer.AccessTime = 0
Buffer.AccessDate = 0
Buffer.FileSize = 0
Buffer.FileName = STRING$(13, 32)
RETURN

END SUB

SUB HandleBlk
'
MouseHide
BlockFile$ = SelectFile$(Tool - 11)
IF BlockFile$ <> "" THEN
  IF Tool = 15 THEN
    OPEN BlockFile$ FOR BINARY AS #1
    IF LOF(1) = 0 OR LOF(1) > 64007 THEN
      CLOSE #1
      ERROR 62
    ELSE
      CLOSE #1
      MouseHide
      PUT (0, 0), Video&, PSET
      REDIM Video&(0)
      REDIM Buffer(32004)
      DEF SEG = VARSEG(Buffer(0))
      BLOAD BlockFile$, VARPTR(Buffer(0))
      Xsize = Buffer(0) \ 8
      Ysize = Buffer(1) + Buffer(2)
      REDIM Buffer(0)
      REDIM Video&(16000)
      GET (0, 0)-(319, 199), Video&
      MouseRange Xsize * 2, Ysize, 639, 199
      MouseShow
      t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
      Oldx = x: Oldy = y: Ok = FALSE
      DO
        MouseStatus Lb, Rb, x, y
        IF x <> Oldx OR y <> Oldy THEN
          MouseHide
          PUT (0, 0), Video&, PSET
          LINE ((x \ 2) - Xsize, y - Ysize)-(x \ 2, y), FCol, B
          MouseShow
        END IF
        IF Lb THEN Ok = TRUE: EXIT DO
        IF Rb THEN EXIT DO
        Oldx = x: Oldy = y
      LOOP
      IF Ok = TRUE THEN
        MouseHide
        PUT (0, 0), Video&, PSET
        REDIM Video&(0)
        REDIM Buffer(32004)
        DEF SEG = VARSEG(Buffer(0))
        BLOAD BlockFile$, VARPTR(Buffer(0))
        PUT ((x \ 2) - Xsize, y - Ysize), Buffer, PSET
        ERASE Buffer
        REDIM Video&(16000)
        GET (0, 0)-(319, 199), Video&
        MouseShow
      END IF
    END IF
  ELSE
    MouseHide
    PUT (0, 0), Video&, PSET
    MouseShow
    t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
    Ok = FALSE
    DO
      MouseStatus Lb, Rb, x, y
      IF Lb THEN Ok = TRUE: EXIT DO
    LOOP
    IF Ok = TRUE THEN
      MouseRange x, y, 639, 199
      x1 = x: y1 = y
      Oldx = x: Oldy = y
      t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
      Ok = FALSE
      DO
        MouseStatus Lb, Rb, x, y
        IF x <> Oldx OR y <> Oldy THEN
          MouseHide
          PUT (0, 0), Video&, PSET
          LINE (x1 \ 2, y1)-(x \ 2, y), FCol, B
          MouseShow
        END IF
        IF Lb THEN Ok = TRUE: EXIT DO
        IF Rb THEN EXIT DO
      LOOP
      IF Ok = TRUE THEN
        IF NOT FloppyDriveReady(CurrentDrive$) THEN ERROR 71
        MouseHide
        t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
        PUT (0, 0), Video&, PSET
        REDIM Video&(0)
        REDIM Buffer(32004)
        GET (x1 \ 2, y1)-(x \ 2, y), Buffer
        DEF SEG = VARSEG(Buffer(0))
        BSAVE BlockFile$, VARPTR(Buffer(0)), ((x \ 2) - (x1 \ 2) + 1) * (y - y1 + 1)
        ERASE Buffer
        REDIM Video&(16000)
        GET (0, 0)-(319, 199), Video&
        MouseShow
      END IF
    END IF
  END IF
  t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
  MouseRange 0, 0, 639, 199
END IF

END SUB

SUB Help
'
MaxPages = 38
IF LEN(OriginalPath$) = 3 THEN HelpFile$ = OriginalPath$ + "EDRAW.HLP" ELSE HelpFile$ = OriginalPath$ + "\EDRAW.HLP"
IF NOT Exist(HelpFile$, 0) THEN ERROR 66
MouseHide
DEF SEG = &HA000
BSAVE "TEMPDRAW.$$$", 0, 64000
PalGet 15, R, G, B
R15 = R: G15 = G: B15 = B
PalGet 14, R, G, B
R14 = R: G14 = G: B14 = B
PalSet 15, 63, 63, 63
PalSet 14, 40, 40, 40
DrawWindow 2, 2, 39, 24, "Help"
DrawButton 4, 4, " PREV "
DrawButton 12, 4, " NEXT "
DrawButton 20, 4, "INDEX "
DrawButton 32, 4, "  OK  "
LINE (7, 37)-(312, 37), FCol
LINE (290, 40)-(304, 190), FCol, B
LINE (290, 47)-(304, 47), FCol
LINE (290, 183)-(304, 183), FCol
PSET (296, 45), FCol: DRAW "C=" + VARPTR$(FCol) + "R2E1R1L6E1R4H1L2"
PSET (296, 185), FCol: DRAW "C=" + VARPTR$(FCol) + "R2F1R1L6F1R4G1L2"
CurPage = HelpPage
DO
  OpenPage CurPage
  LINE (16, 40)-(287, 191), BCol, BF
  IF NumLines > 19 THEN PageLines = 19 ELSE PageLines = NumLines
  FOR i = 1 TO PageLines
    LOCATE 5 + i, 3
    IF INSTR(Lin(i), "<") = 0 THEN
      COLOR 15: PRINT Lin(i);
    ELSE
      COLOR 15: PRINT MID$(Lin(i), 1, INSTR(Lin(i), "<"));
      COLOR 14: PRINT MID$(Lin(i), INSTR(Lin(i), "<") + 1, INSTR(Lin(i), ">") - INSTR(Lin(i), "<") - 1);
      COLOR 15: PRINT MID$(Lin(i), INSTR(Lin(i), ">"), 34 - INSTR(Lin(i), ">"));
    END IF
  NEXT i
  LINE (292, 49)-(302, 181), BCol, BF
  IF NumLines <= 19 THEN LINE (292, 49)-(302, 181), FCol, BF ELSE LINE (292, 49)-(302, 51), FCol, BF
  PagePos = 0
  MouseShow
  DO
    MouseStatus Lb, Rb, x, y
    IF Lb THEN
      IF x \ 2 > 290 AND x \ 2 < 304 THEN
        IF y > 40 AND y < 47 THEN
          IF PagePos > 0 THEN
            PagePos = PagePos - 1
            GOSUB DrawHelp
          END IF
        END IF
        IF y > 183 AND y < 190 THEN
          IF NumLines > 19 THEN
            IF PagePos < NumLines - 19 THEN
              PagePos = PagePos + 1
              GOSUB DrawHelp
            END IF
          END IF
        END IF
      END IF
      IF y > 20 AND y < 36 THEN
        IF x \ 2 > 20 AND x \ 2 < 76 THEN
          IF CurPage > 1 THEN CurPage = CurPage - 1: EXIT DO
        END IF
        IF x \ 2 > 84 AND x \ 2 < 140 THEN
          IF CurPage < MaxPages THEN CurPage = CurPage + 1: EXIT DO
        END IF
        IF x \ 2 > 148 AND x \ 2 < 204 THEN
          CurPage = 1: EXIT DO
        END IF
        IF x \ 2 > 244 AND x \ 2 < 300 THEN
          CurPage = 0: EXIT DO
        END IF
      END IF
      IF NumButtons > 0 THEN
        PageToSeek = 0
        FOR i = 1 TO NumButtons
          IF x \ 2 > ((Button(i).xStart + 1) * 8) AND x \ 2 < ((Button(i).xEnd + 2) * 8) - 1 THEN
            IF y > ((Button(i).LineAt + 4 - PagePos) * 8) - 1 AND y < ((Button(i).LineAt + 5 - PagePos) * 8) - 2 THEN
              PageToSeek = Button(i).Page: EXIT FOR
            END IF
          END IF
        NEXT i
        IF PageToSeek <> 0 THEN CurPage = PageToSeek: EXIT DO
      END IF
    END IF
  LOOP
  t! = TIMER: DO: LOOP UNTIL TIMER > t! + .1
  MouseHide
  IF CurPage = 0 THEN EXIT DO
LOOP
DEF SEG = &HA000
BLOAD "TEMPDRAW.$$$", 0
KILL "TEMPDRAW.$$$"
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
PalSet 15, R15, G15, B15
PalSet 14, R14, G14, B14
EXIT SUB

DrawHelp:
WAIT &H3DA, 8
MouseHide
FOR i = 1 TO 19
  LOCATE 5 + i, 3
  IF INSTR(Lin(i + PagePos), "<") = 0 THEN
    COLOR 15: PRINT Lin(i + PagePos);
  ELSE
    COLOR 15: PRINT MID$(Lin(i + PagePos), 1, INSTR(Lin(i + PagePos), "<"));
    COLOR 14: PRINT MID$(Lin(i + PagePos), INSTR(Lin(i + PagePos), "<") + 1, INSTR(Lin(i + PagePos), ">") - INSTR(Lin(i + PagePos), "<") - 1);
    COLOR 15: PRINT MID$(Lin(i + PagePos), INSTR(Lin(i + PagePos), ">"), 34 - INSTR(Lin(i + PagePos), ">"));
  END IF
NEXT i
LINE (292, 49)-(302, 181), BCol, BF
LINE (292, 49 + ((129 / (NumLines - 19)) * PagePos))-(302, 51 + ((129 / (NumLines - 19)) * PagePos)), FCol, BF
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .02
RETURN



END SUB

SUB InvertBlock
'
x2 = x: y2 = y
MouseRange 0, 0, 639, 199
DrawWindow 10, 11, 31, 14, "Invert block"
DrawButton 15, 13, " "
DrawButton 18, 13, " "
DrawButton 21, 13, "CANCEL"
LINE (112, 96)-(119, 103), FCol, B
LINE (116, 96)-(119, 103), FCol, BF
LINE (136, 96)-(143, 103), FCol, B
LINE (136, 100)-(143, 103), FCol, BF
InvertDir = 0
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 92 AND y < 107 THEN
      IF x \ 2 > 108 AND x \ 2 < 123 THEN InvertDir = 1: EXIT DO
      IF x \ 2 > 132 AND x \ 2 < 147 THEN InvertDir = 2: EXIT DO
      IF x \ 2 > 156 AND x \ 2 < 211 THEN InvertDir = 0: EXIT DO
    END IF
  END IF
LOOP
MouseHide
IF InvertDir = 0 THEN
  PUT (0, 0), Video&, PSET
  MouseShow
  t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
  EXIT SUB
END IF
REDIM b1&(100), b2&(100)
PUT (0, 0), Video&, PSET
IF InvertDir = 1 THEN
  FOR i = 0 TO (x2 - x1) \ 4
    GET ((x1 \ 2) + i, y1)-((x1 \ 2) + i, y2), b1&
    GET ((x2 \ 2) - i, y1)-((x2 \ 2) - i, y2), b2&
    PUT ((x1 \ 2) + i, y1), b2&, PSET
    PUT ((x2 \ 2) - i, y1), b1&, PSET
  NEXT i
ELSE
  FOR i = 0 TO (y2 - y1) \ 2
    GET (x1 \ 2, y1 + i)-(x2 \ 2, y1 + i), b1&
    GET (x1 \ 2, y2 - i)-(x2 \ 2, y2 - i), b2&
    PUT (x1 \ 2, y1 + i), b2&, PSET
    PUT (x1 \ 2, y2 - i), b1&, PSET
  NEXT i
END IF
GET (0, 0)-(319, 199), Video&
IF CoordBox = 0 THEN GET (0, 190)-(319, 199), CoordBox& ELSE GET (0, 0)-(319, 9), CoordBox&
MouseShow
ERASE b1&, b2&
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
END SUB

SUB LoadFile
'
ToLoad$ = SelectFile(1)
IF INSTR(ToLoad$, ".") <> 0 THEN
  ToLoadx$ = LEFT$(ToLoad$, INSTR(ToLoad$, ".") - 1)
ELSE
  ToLoadx$ = ToLoad$
END IF
IF ToLoad$ = "" THEN EXIT SUB
IF Exist(ToLoadx$ + "." + PalExt, 0) THEN
  DIM Buf AS STRING * 1
  OPEN ToLoadx$ + "." + PalExt FOR BINARY AS #1
  FOR i = 0 TO 255
    GET #1, , Buf: R = ASC(Buf)
    GET #1, , Buf: G = ASC(Buf)
    GET #1, , Buf: B = ASC(Buf)
    PalSet i, R, G, B
  NEXT i
  CLOSE #1
ELSE
  PALETTE
END IF
MouseHide
CLS
DEF SEG = &HA000: BLOAD ToLoad$, 0
GET (0, 0)-(319, 199), Video&
GET (0, 190)-(319, 199), CoordBox&
FileName$ = ToLoad$
MouseShow

END SUB

FUNCTION LogicalDrives (drive$)
    DIM inreg AS RegTypeX
    inreg.ax = &H440E
    inreg.Bx = ASC(drive$) - 64
    CALL interrupt(&H21, inreg, inreg)
    IF (inreg.flags AND 1) = 1 THEN
        LogicalDrives = -1
    ELSE
        LogicalDrives = inreg.ax AND 255
    END IF
END FUNCTION

FUNCTION Menu
'
MouseHide
MouseRange 0, 0, 639, 199
Pointed = 0
IF CoordBox = 0 THEN PUT (0, 190), CoordBox&, PSET ELSE PUT (0, 0), CoordBox&, PSET
GET (0, 0)-(319, 199), Video&
DrawMenu
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
SelMenu = -1
DO
  MouseStatus Lb, Rb, x, y
  IF y < 9 THEN
    NewMenu = (x \ 2) \ 80
    IF NewMenu <> SelMenu THEN
      MouseHide
      IF SelMenu <> -1 THEN PUT (SelMenu * 80, 0), SelBox&
      SelMenu = NewMenu
      PUT (SelMenu * 80, 0), SelBox&
      MouseShow
    END IF
  ELSE
    IF SelMenu <> -1 THEN
      MouseHide
      PUT (SelMenu * 80, 0), SelBox&
      SelMenu = -1
      MouseShow
    END IF
  END IF
  IF Rb THEN Menu = Tool: EXIT DO
  IF Lb THEN
    IF y > 13 AND y < 173 THEN
      IF x \ 2 > 2 AND x \ 2 < 42 THEN
        WAIT &H3DA, 8
        MouseHide
        NewCol = ((((x \ 2) - 3) \ 5) * 32) + ((y - 14) \ 5)
        LINE (((Col \ 32) * 5) + 2, ((Col MOD 32) * 5) + 13)-(((Col \ 32) * 5) + 7, ((Col MOD 32) * 5) + 18), BCol, B
        Col = NewCol
        LINE (((Col \ 32) * 5) + 2, ((Col MOD 32) * 5) + 13)-(((Col \ 32) * 5) + 7, ((Col MOD 32) * 5) + 18), FCol, B
        COLOR FCol
        LOCATE 24, 3: PRINT USING "###"; Col;
        LINE (4, 177)-(40, 182), Col, BF
        MouseShow
      END IF
    END IF
    IF SelMenu <> -1 THEN
      SubMenu SelMenu
      MouseHide
      PUT (SelMenu * 80, 0), SelBox&
      MouseShow
    END IF
  END IF
LOOP
'
MouseHide
PUT (0, 0), Video&, PSET
IF Tool = RUBBER THEN GET (0, 0)-(319, 9), Temp1&: GET (0, 190)-(319, 199), Temp2&
IF y > 170 AND CoordBox = 0 THEN
  MouseHide
  CoordBox = 1
  PUT (0, 190), CoordBox&, PSET
  GET (0, 0)-(319, 9), CoordBox&
  LINE (0, 0)-(319, 9), BCol, BF
  LINE (0, 9)-(319, 9), FCol
  IF Tool = PENCIL AND JustPressed = 1 THEN PSET (x \ 2, y), POINT(x \ 2, y)
  MouseShow
ELSEIF y < 170 AND CoordBox = 1 THEN
  MouseHide
  CoordBox = 0
  PUT (0, 0), CoordBox&, PSET
  GET (0, 190)-(319, 199), CoordBox&
  LINE (0, 190)-(319, 199), BCol, BF
  LINE (0, 190)-(319, 190), FCol
  IF Tool = PENCIL AND JustPressed = 1 THEN PSET (x \ 2, y), POINT(x \ 2, y)
  MouseShow
END IF
IF CoordBox = 0 THEN LINE (0, 190)-(319, 199), BCol, BF: LINE (0, 190)-(319, 190), FCol ELSE LINE (0, 0)-(319, 9), BCol, BF: LINE (0, 9)-(319, 9), FCol
IF CoordBox = 0 THEN LOCATE 25, 1 ELSE LOCATE 1, 1
COLOR FCol: PRINT USING "x:### y:###  Color:"; x \ 2; y;
COLOR Col: PRINT USING "###"; Col; : COLOR FCol: PRINT ",";
COLOR POINT(x \ 2, y): PRINT USING "###"; POINT(x \ 2, y);
COLOR FCol: LOCATE , 29: PRINT FileName$;
SELECT CASE Tool
CASE LENS
  MouseRange 78, 33, 639, 199
END SELECT
MouseShow
Menu = Tool
END FUNCTION

SUB ModifyBlock
'
x2 = x: y2 = y
MouseRange 0, 0, 639, 199
DrawWindow 9, 3, 32, 23, "Modify block colors"
LINE (77, 43)-(241, 87), FCol, B
FOR i = 0 TO 255
  LINE (80 + ((i MOD 32) * 5), 46 + ((i \ 32) * 5))-(83 + ((i MOD 32) * 5), 49 + ((i \ 32) * 5)), i, BF
NEXT i
LOCATE 5, 11: PRINT "Selected color (# 15)"
LINE (77, 107)-(241, 151), FCol, B
FOR i = 0 TO 255
  LINE (80 + ((i MOD 32) * 5), 110 + ((i \ 32) * 5))-(83 + ((i MOD 32) * 5), 113 + ((i \ 32) * 5)), i, BF
NEXT i
LOCATE 13, 11: PRINT "Changed with # 15"
DrawButton 13, 22, "  OK  "
DrawButton 23, 22, "CANCEL"
DIM Pal(255): FOR i = 0 TO 255: Pal(i) = i: NEXT i
CurCol = 15
LINE (79 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 50 + ((CurCol \ 32) * 5)), FCol, B
LINE (79 + ((Pal(CurCol) MOD 32) * 5), 109 + ((Pal(CurCol) \ 32) * 5))-(84 + ((Pal(CurCol) MOD 32) * 5), 114 + ((Pal(CurCol) \ 32) * 5)), FCol, B
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
Change = FALSE
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF x \ 2 > 79 AND x \ 2 < 239 THEN
      IF y > 46 AND y < 86 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (79 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 50 + ((CurCol \ 32) * 5)), BCol, B
        FOR i = 0 TO 255
          IF Pal(i) <> i THEN
            PSET (79 + ((i MOD 32) * 5), 45 + ((i \ 32) * 5)), FCol
            PSET (84 + ((i MOD 32) * 5), 45 + ((i \ 32) * 5)), FCol
            PSET (79 + ((i MOD 32) * 5), 50 + ((i \ 32) * 5)), FCol
            PSET (84 + ((i MOD 32) * 5), 50 + ((i \ 32) * 5)), FCol
          END IF
        NEXT i
        LINE (79 + ((Pal(CurCol) MOD 32) * 5), 109 + ((Pal(CurCol) \ 32) * 5))-(84 + ((Pal(CurCol) MOD 32) * 5), 114 + ((Pal(CurCol) \ 32) * 5)), BCol, B
        CurCol = (((y - 46) \ 5) * 32) + (((x \ 2) - 80) \ 5)
        LINE (79 + ((CurCol MOD 32) * 5), 45 + ((CurCol \ 32) * 5))-(84 + ((CurCol MOD 32) * 5), 50 + ((CurCol \ 32) * 5)), FCol, B
        LINE (79 + ((Pal(CurCol) MOD 32) * 5), 109 + ((Pal(CurCol) \ 32) * 5))-(84 + ((Pal(CurCol) MOD 32) * 5), 114 + ((Pal(CurCol) \ 32) * 5)), FCol, B
        LOCATE 5, 28: PRINT USING "###"; CurCol
        LOCATE 13, 26: PRINT USING "###"; Pal(CurCol)
        MouseShow
      END IF
      IF y > 110 AND y < 150 THEN
        WAIT &H3DA, 8
        MouseHide
        LINE (79 + ((Pal(CurCol) MOD 32) * 5), 109 + ((Pal(CurCol) \ 32) * 5))-(84 + ((Pal(CurCol) MOD 32) * 5), 114 + ((Pal(CurCol) \ 32) * 5)), BCol, B
        Pal(CurCol) = (((y - 110) \ 5) * 32) + (((x \ 2) - 80) \ 5)
        LINE (79 + ((Pal(CurCol) MOD 32) * 5), 109 + ((Pal(CurCol) \ 32) * 5))-(84 + ((Pal(CurCol) MOD 32) * 5), 114 + ((Pal(CurCol) \ 32) * 5)), FCol, B
        LOCATE 13, 26: PRINT USING "###"; Pal(CurCol)
        MouseShow
      END IF
    END IF
    IF y > 164 AND y < 180 THEN
      IF x \ 2 > 92 AND x \ 2 < 148 THEN Change = TRUE: EXIT DO
      IF x \ 2 > 172 AND x \ 2 < 228 THEN Change = FALSE: EXIT DO
    END IF
  END IF
LOOP
MouseHide
PUT (0, 0), Video&, PSET
IF Change = TRUE THEN
  FOR i = x1 \ 2 TO x2 \ 2
    FOR ii = y1 TO y2
      p = POINT(i, ii)
      PSET (i, ii), Pal(p)
    NEXT ii
  NEXT i
  GET (0, 0)-(319, 199), Video&
  IF CoordBox = 0 THEN GET (0, 190)-(319, 199), CoordBox& ELSE GET (0, 0)-(319, 9), CoordBox&
END IF
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3

END SUB

DEFLNG A-Z
SUB MouseDriver (Ax1%, Bx1%, Cx1%, Dx1%)
'
DEF SEG = VARSEG(Mouse$)
Mouse% = SADD(Mouse$)
CALL ABSOLUTE(Ax1%, Bx1%, Cx1%, Dx1%, Mouse%)
END SUB

SUB MouseHide
'
Ax1% = 2
MouseDriver Ax1%, 0, 0, 0
END SUB

FUNCTION MouseInit%
'
Ax1% = 0
MouseDriver Ax1%, 0, 0, 0
MouseInit% = Ax1%
END FUNCTION

SUB MousePut (x%, y%)
'
Ax1% = 4
Cx1% = x%
Dx1% = y%
MouseDriver Ax1%, 0, Cx1%, Dx1%
END SUB

SUB MouseRange (x1%, y1%, x2%, y2%)
'
Ax1% = 7
Cx1% = x1%
Dx1% = x2%
MouseDriver Ax1%, 0, Cx1%, Dx1%
Ax1% = 8
Cx1% = y1%
Dx1% = y2%
MouseDriver Ax1%, 0, Cx1%, Dx1%
END SUB

SUB MouseShow
'
Ax1% = 1
MouseDriver Ax1%, 0, 0, 0
END SUB

SUB MouseStatus (Lb%, Rb%, x%, y%)
'
Ax1% = 3
MouseDriver Ax1%, Bx1%, Cx1%, Dx1%
Lb% = ((Bx1% AND 1) <> 0)
Rb% = ((Bx1% AND 2) <> 0)
x% = Cx1%
y% = Dx1%
END SUB

DEFINT A-Z
SUB MoveBlock (Mode)
'
x2 = x: y2 = y
MouseRange x2 - x1, y2 - y1, 639, 199
LINE (((x \ 2) - ((x2 - x1) \ 2)), y - (y2 - y1))-(x \ 2, y), FCol, B
MouseShow
Oldx = x: Oldy = y
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
DO
  MouseStatus Lb, Rb, x, y
  IF x <> Oldx OR y <> Oldy THEN
    MouseHide
    PUT (0, 0), Video&, PSET
    LINE (((x \ 2) - ((x2 - x1) \ 2)), y - (y2 - y1))-(x \ 2, y), FCol, B
    MouseShow
  END IF
  IF Lb THEN EXIT DO
  Oldx = x: Oldy = y
LOOP
MouseHide
PUT (0, 0), Video&, PSET
GET (x1 \ 2, y1)-(x2 \ 2, y2), Video&
IF Mode = 2 THEN LINE (x1 \ 2, y1)-(x2 \ 2, y2), BCol, BF
PUT ((x \ 2) - ((x2 - x1) \ 2), y - (y2 - y1)), Video&, PSET
GET (0, 0)-(319, 199), Video&
MouseRange 0, 0, 639, 199
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
END SUB

SUB NewFile
'
MouseHide
PUT (0, 0), Video&, PSET
DrawWindow 8, 9, 32, 16, "New file"
COLOR FCol: LOCATE 11, 9: PRINT "WARNING: Current image"
LOCATE 12, 9: PRINT "will be lost. Continue?"
DrawButton 12, 15, "  OK  "
DrawButton 23, 15, "CANCEL"
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 108 AND y < 123 THEN
      IF x \ 2 > 84 AND x \ 2 < 147 THEN
        MouseHide
        CLS
        GET (0, 0)-(319, 199), Video&
        GET (0, 0)-(319, 9), CoordBox&
        FileName$ = "NONAME." + BinExt
        MouseShow
        EXIT DO
      END IF
      IF x \ 2 > 172 AND x \ 2 < 227 THEN
        EXIT DO
      END IF
    END IF
  END IF
LOOP

END SUB

'Returns the number of logical drives. For instance- if 4 is returned
'then the valid drive names are A: B: C: & D:
'Since I only got to check this sub out with my computer's
'drive configuration, this sub checks over it's findings
'to make sure it has the correct number of logical drives.
'(better safe than sorry!)
FUNCTION NumDrives
    DIM inreg AS RegTypeX
    inreg.ax = &HE00
    inreg.Dx = ASC(CurrentDrive$) - 65
    CALL interrupt(&H21, inreg, inreg)
    Temp = (inreg.ax MOD 256) - 1
    FOR A = 1 TO Temp
        IF LogicalDrives(CHR$(A + 64)) = -1 THEN
            NumDrives = A - 1
            EXIT FUNCTION
        END IF
    NEXT
    NumDrives = Temp
END FUNCTION

SUB OpenPage (Page)
'
OPEN "EDRAW.HLP" FOR INPUT AS #1
NumLines = 0: NumButtons = 0
IF Page <> 1 THEN
  FOR i = 1 TO Page - 1
    INPUT #1, NumLines
    NumButtons = 0
    FOR ii = 1 TO NumLines
      LINE INPUT #1, l$
      IF INSTR(l$, "<") <> 0 THEN NumButtons = NumButtons + 1
    NEXT ii
    IF NumButtons <> 0 THEN
      FOR ii = 1 TO NumButtons: INPUT #1, p: NEXT ii
    END IF
  NEXT i
END IF
INPUT #1, NumLines
NumButtons = 0
FOR i = 1 TO NumLines
  LINE INPUT #1, Lin(i)
  IF INSTR(Lin(i), "<") <> 0 THEN
    NumButtons = NumButtons + 1
    Button(NumButtons).LineAt = i
    Button(NumButtons).xStart = INSTR(Lin(i), "<") + 1
    Button(NumButtons).xEnd = INSTR(Lin(i), ">") - 1
  END IF
NEXT i
IF NumButtons <> 0 THEN
  FOR i = 1 TO NumButtons
    INPUT #1, Button(i).Page
  NEXT i
END IF
CLOSE #1
Ti$ = "Help - " + MID$(Lin(1), 5, INSTR(Lin(1), ".") - 5)
LOCATE 2, 2: PRINT SPACE$(38)
LOCATE 2, (41 - LEN(Ti$)) \ 2: COLOR 15: PRINT Ti$
END SUB

SUB PalGet (C, R, G, B)
'
OUT &H3C7, C
R = INP(&H3C9)
G = INP(&H3C9)
B = INP(&H3C9)

END SUB

SUB PalSet (C, R, G, B)
'
OUT &H3C8, C
OUT &H3C9, R
OUT &H3C9, G
OUT &H3C9, B

END SUB

SUB Preferences
'
MouseHide
DrawWindow 3, 3, 38, 23, "Preferences"
COLOR FCol
LOCATE 5, 5: PRINT "Rubber box X size (0-319)..."
LOCATE 6, 5: PRINT "Rubber box Y size (0-199)..."
LOCATE 8, 5: PRINT "Spray box X size (0-319)...."
LOCATE 9, 5: PRINT "Spray box Y size (0-199)...."
LOCATE 10, 5: PRINT "Spray intensity (%) ........"
LOCATE 12, 5: PRINT "Foreground color (0-255)...."
LOCATE 13, 5: PRINT "Background color (0-255)...."
LOCATE 15, 5: PRINT "Image file extension ......."
LOCATE 16, 5: PRINT "Block file extension ......."
LOCATE 17, 5: PRINT "Palette file extension ....."
LOCATE 19, 5: PRINT "Save space on BSaving images"
DrawButton 18, 22, "  OK  "
LOCATE 5, 34: PRINT USING "###"; RubX
LOCATE 6, 34: PRINT USING "###"; RubY
LOCATE 8, 34: PRINT USING "###"; SprayX
LOCATE 9, 34: PRINT USING "###"; SprayY
LOCATE 10, 34: PRINT USING "###"; SprayI
LOCATE 12, 34: PRINT USING "###"; FCol
LOCATE 13, 34: PRINT USING "###"; BCol
LOCATE 15, 34: PRINT BinExt
LOCATE 16, 34: PRINT BlkExt
LOCATE 17, 34: PRINT PalExt
LOCATE 19, 34: IF SaveSpace = TRUE THEN PRINT "YES" ELSE PRINT " NO"
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF x \ 2 > 264 AND x \ 2 < 288 THEN
      Cel = (y \ 8) + 1
      SELECT CASE Cel
      CASE 5
        Typ = 0: Inf = 0: Sup = 319: GOSUB InputPref
        RubX = VAL(Enter$): LOCATE 5, 34: PRINT USING "###"; RubX
        MouseShow
      CASE 6
        Typ = 0: Inf = 0: Sup = 199: GOSUB InputPref
        RubY = VAL(Enter$): LOCATE 6, 34: PRINT USING "###"; RubY
        MouseShow
      CASE 8
        Typ = 0: Inf = 0: Sup = 319: GOSUB InputPref
        SprayX = VAL(Enter$): LOCATE 8, 34: PRINT USING "###"; SprayX
        MouseShow
      CASE 9
        Typ = 0: Inf = 0: Sup = 199: GOSUB InputPref
        SprayY = VAL(Enter$): LOCATE 9, 34: PRINT USING "###"; SprayY
        MouseShow
      CASE 10
        Typ = 0: Inf = 0: Sup = 100: GOSUB InputPref
        SprayI = VAL(Enter$): LOCATE 10, 34: PRINT USING "###"; SprayI
        MouseShow
      CASE 12
        Typ = 0: Inf = 0: Sup = 255: GOSUB InputPref
        FCol = VAL(Enter$): LOCATE 12, 34: PRINT USING "###"; FCol
        MouseShow
      CASE 13
        Typ = 0: Inf = 0: Sup = 255: GOSUB InputPref
        BCol = VAL(Enter$): LOCATE 13, 34: PRINT USING "###"; BCol
        MouseShow
      CASE 15
        Typ = 1: GOSUB InputPref
        BinExt = Enter$: LOCATE 15, 34: PRINT BinExt
        MouseShow
      CASE 16
        Typ = 1: GOSUB InputPref
        BlkExt = Enter$: LOCATE 16, 34: PRINT BlkExt
        MouseShow
      CASE 17
        Typ = 1: GOSUB InputPref
        PalExt = Enter$: LOCATE 17, 34: PRINT PalExt
        MouseShow
      CASE 19
        MouseHide
        IF SaveSpace = TRUE THEN
          SaveSpace = FALSE
          LOCATE 19, 34: PRINT " NO"
        ELSE
          LOCATE 19, 34: PRINT "YES"
          SaveSpace = TRUE
        END IF
        MouseShow
        t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
      END SELECT
    END IF
    IF x \ 2 > 132 AND x \ 2 < 187 THEN
      IF y > 164 AND y < 180 THEN
        EXIT DO
      END IF
    END IF
  END IF
LOOP
EXIT SUB

InputPref:
MouseHide
LOCATE Cel, 34: PRINT "    "
Enter$ = ""
DO
  LOCATE Cel, 34: PRINT Enter$ + CHR$(219)
  k$ = INKEY$: WHILE k$ = "": k$ = INKEY$: WEND
  IF LEN(Enter$) < 3 THEN
    Ascii = ASC(UCASE$(k$))
    IF Typ = 0 THEN
      IF Ascii > 47 AND Ascii < 58 THEN
        Enter$ = Enter$ + k$
      END IF
    ELSE
      IF Ascii > 64 AND Ascii < 91 THEN
        Enter$ = Enter$ + UCASE$(k$)
      END IF
      IF Ascii > 47 AND Ascii < 58 THEN
        Enter$ = Enter$ + k$
      END IF
    END IF
    LOCATE Cel, 34: PRINT Enter$ + CHR$(219)
  END IF
  IF k$ = CHR$(8) THEN
    IF LEN(Enter$) > 0 THEN
      Enter$ = LEFT$(Enter$, LEN(Enter$) - 1)
      LOCATE Cel, 34: PRINT Enter$ + "  "
    END IF
  END IF
  IF k$ = CHR$(13) THEN
    IF Typ = 0 THEN
      IF Enter$ = "" THEN Exter$ = "0"
      IF VAL(Enter$) >= Inf AND VAL(Enter$) <= Sup THEN EXIT DO
    ELSE
      IF Enter$ <> "" THEN EXIT DO
    END IF
  END IF
LOOP
LOCATE Cel, 34: PRINT Enter$ + " "
RETURN

END SUB

FUNCTION Quit
'
MouseHide
PUT (0, 0), Video&, PSET
DrawWindow 10, 10, 30, 15, "Quit"
LOCATE 12, 15: PRINT "End program."
DrawButton 12, 14, "  OK  "
DrawButton 23, 14, "CANCEL"
MouseShow
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 100 AND y < 115 THEN
      IF x \ 2 > 84 AND x \ 2 < 140 THEN
        Quit = TRUE: EXIT DO
      END IF
      IF x \ 2 > 172 AND x \ 2 < 227 THEN
        Quit = FALSE: EXIT DO
      END IF
    END IF
  END IF
LOOP

END FUNCTION

'Returns the current path in a usable form.
'WARNING: if the drive isn't ready this sub will HANG UP!!!
FUNCTION RealPath$
    RealPath$ = CurrentDrive$ + ":\" + CurrentPath$
END FUNCTION

SUB RotateBlock
'
x2 = x1 + ((y - y1) * 2): y2 = y
A = (y - y1 + 1)
MouseRange 0, 0, 639, 199
DrawWindow 10, 11, 31, 14, "Rotate block"
DrawButton 13, 13, " "
DrawButton 16, 13, " "
DrawButton 19, 13, " "
DrawButton 23, 13, "CANCEL"
CIRCLE (100, 99), 4, FCol, 0, 1.57, 1
CIRCLE (124, 99), 4, FCol, 4.71, 1.57, 1
CIRCLE (148, 99), 4, FCol, 3.14, 1.57, 1
RotateA = 0
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF y > 92 AND y < 107 THEN
      IF x \ 2 > 92 AND x \ 2 < 107 THEN RotateA = 1: EXIT DO
      IF x \ 2 > 116 AND x \ 2 < 131 THEN RotateA = 2: EXIT DO
      IF x \ 2 > 140 AND x \ 2 < 155 THEN RotateA = 3: EXIT DO
      IF x \ 2 > 172 AND x \ 2 < 227 THEN RotateA = 0: EXIT DO
    END IF
  END IF
LOOP
MouseHide
IF RotateA = 0 THEN
  PUT (0, 0), Video&, PSET
  MouseShow
  t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
  EXIT SUB
END IF
PUT (0, 0), Video&, PSET
IF A <> 0 THEN
  xr = 0: yr = 0: p1 = 0: p2 = 0: p3 = 0: p4 = 0
  FOR i = 1 TO (A \ 2) ^ 2
    p1 = POINT((x1 \ 2) + xr, y1 + yr)
    p2 = POINT((x2 \ 2) - yr, y1 + xr)
    p3 = POINT((x2 \ 2) - xr, y2 - yr)
    p4 = POINT((x1 \ 2) + yr, y2 - xr)
    SELECT CASE RotateA
    CASE 1
      PSET ((x1 \ 2) + xr, y1 + yr), p4
      PSET ((x2 \ 2) - yr, y1 + xr), p1
      PSET ((x2 \ 2) - xr, y2 - yr), p2
      PSET ((x1 \ 2) + yr, y2 - xr), p3
    CASE 2
      PSET ((x1 \ 2) + xr, y1 + yr), p3
      PSET ((x2 \ 2) - yr, y1 + xr), p4
      PSET ((x2 \ 2) - xr, y2 - yr), p1
      PSET ((x1 \ 2) + yr, y2 - xr), p2
    CASE 3
      PSET ((x1 \ 2) + xr, y1 + yr), p2
      PSET ((x2 \ 2) - yr, y1 + xr), p3
      PSET ((x2 \ 2) - xr, y2 - yr), p4
      PSET ((x1 \ 2) + yr, y2 - xr), p1
    END SELECT
    xr = xr + 1
    IF xr >= (A \ 2) THEN xr = 0: yr = yr + 1
  NEXT i
  IF A MOD 2 = 1 THEN
    FOR i = 0 TO (A \ 2)
      p1 = POINT((x1 \ 2) + (A \ 2), y1 + i)
      p2 = POINT((x2 \ 2) - i, y1 + (A \ 2))
      p3 = POINT((x1 \ 2) + (A \ 2), y2 - i)
      p4 = POINT((x1 \ 2) + i, y1 + (A \ 2))
      SELECT CASE RotateA
      CASE 1
        PSET ((x1 \ 2) + (A \ 2), y1 + i), p4
        PSET ((x2 \ 2) - i, y1 + (A \ 2)), p1
        PSET ((x1 \ 2) + (A \ 2), y2 - i), p2
        PSET ((x1 \ 2) + i, y1 + (A \ 2)), p3
      CASE 2
        PSET ((x1 \ 2) + (A \ 2), y1 + i), p3
        PSET ((x2 \ 2) - i, y1 + (A \ 2)), p4
        PSET ((x1 \ 2) + (A \ 2), y2 - i), p1
        PSET ((x1 \ 2) + i, y1 + (A \ 2)), p2
      CASE 3
        PSET ((x1 \ 2) + (A \ 2), y1 + i), p2
        PSET ((x2 \ 2) - i, y1 + (A \ 2)), p3
        PSET ((x1 \ 2) + (A \ 2), y2 - i), p4
        PSET ((x1 \ 2) + i, y1 + (A \ 2)), p1
      END SELECT
    NEXT i
  END IF
END IF
GET (0, 0)-(319, 199), Video&
IF CoordBox = 0 THEN GET (0, 190)-(319, 199), CoordBox& ELSE GET (0, 0)-(319, 9), CoordBox&
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3

END SUB

SUB SaveFile
'
ToSave$ = SelectFile$(2)
IF INSTR(ToSave$, ".") <> 0 THEN
  ToSavex$ = LEFT$(ToSave$, INSTR(ToSave$, ".") - 1)
ELSE
  ToSavex$ = ToSave$
END IF
IF ToSave$ = "" THEN EXIT SUB
MouseHide
PUT (0, 0), Video&, PSET
OPEN ToSavex$ + "." + PalExt FOR BINARY AS #1
FOR i = 0 TO 255
  PalGet i, R, G, B
  R$ = CHR$(R): PUT #1, , R$
  G$ = CHR$(G): PUT #1, , G$
  B$ = CHR$(B): PUT #1, , B$
NEXT i
CLOSE #1
IF SaveSpace = TRUE THEN
  Space! = CountSpace!
  DEF SEG = &HA000: BSAVE ToSave$, 0, Space!
ELSE
  DEF SEG = &HA000: BSAVE ToSave$, 0, 64000
END IF
FileName$ = ToSave$
MouseShow

END SUB

FUNCTION SelectFile$ (Mode)
'
MouseHide
IF NOT FloppyDriveReady(CurrentDrive$) THEN ERROR 71
DIM FileN$(200), FileE$(200), FileT(200), FileItem$(200), DirItem$(50)
SELECT CASE Mode
CASE 1: Ti$ = "Load image file"
CASE 2: Ti$ = "Save image file as"
CASE 3: Ti$ = "Delete image file"
CASE 4: Ti$ = "Load block"
CASE 5: Ti$ = "Save block"
CASE 6: Ti$ = "Load palette"
CASE 7: Ti$ = "Save palette"
END SELECT
DrawWindow 4, 3, 36, 22, Ti$
COLOR FCol
SELECT CASE Mode
CASE 1, 2, 3: SelFile$ = FileName$
CASE 4, 5: SelFile$ = "NONAME.BLK"
CASE 6, 7: SelFile$ = "NONAME.PAL"
END SELECT
LOCATE 6, 6: PRINT "File Name:"
DrawButton 18, 6, SelFile$ + SPACE$(13 - LEN(SelFile$))
Path$ = RealPath$
IF LEN(Path$) > 28 THEN
  Path$ = LEFT$(Path$, 25) + "..\"
END IF
LOCATE 8, 6: PRINT Path$
IF LEN(RealPath$) = 3 THEN Mask$ = RealPath$ + "*.*" ELSE Mask$ = RealPath$ + "\*.*"
GetDir FileN$(), FileE$(), FileT(), DirNum, Mask$, Status
NumFiles = 0
Sf$ = BinExt
IF Mode = 4 OR Mode = 5 THEN Sf$ = BlkExt
IF Mode = 6 OR Mode = 7 THEN Sf$ = PalExt
FOR i = 0 TO DirNum - 1
  IF FileE$(i) = Sf$ AND FileT(i) = FILE AND NumFiles < 200 THEN FileItem$(NumFiles) = FileN$(i): NumFiles = NumFiles + 1
NEXT i
IF LEN(Path$) > 3 THEN
  DirItem$(0) = ".."
  NumDirs = 1
ELSE
  NumDirs = 0
END IF

FOR i = 0 TO DirNum - 1
  IF FileT(i) = DIRECTORY AND NumDirs < 44 THEN DirItem$(NumDirs) = FileN$(i): NumDirs = NumDirs + 1
NEXT i
LINE (36, 68)-(131, 139), FCol, B
LINE (115, 68)-(115, 139), FCol
LINE (115, 75)-(131, 75), FCol
LINE (115, 132)-(131, 132), FCol
PSET (122, 73), FCol: DRAW "C=" + VARPTR$(FCol) + "R2E1R1L6E1R4H1L2"
PSET (122, 134), FCol: DRAW "C=" + VARPTR$(FCol) + "R2F1R1L6F1R4G1L2"
LINE (180, 68)-(275, 139), FCol, B
LINE (259, 68)-(259, 139), FCol
LINE (259, 75)-(275, 75), FCol
LINE (259, 132)-(275, 132), FCol
PSET (266, 73), FCol: DRAW "C=" + VARPTR$(FCol) + "R2E1R1L6E1R4H1L2"
PSET (266, 134), FCol: DRAW "C=" + VARPTR$(FCol) + "R2F1R1L6F1R4G1L2"
LOCATE 20, 6: PRINT "*." + Sf$;
SELECT CASE Sf$
CASE BinExt, BlkExt: PRINT " (BSAVEd)"
CASE PalExt: PRINT " (Binary)"
END SELECT

DrawButton 22, 20, "  OK  "
DrawButton 30, 20, "CANCEL"
DirPos = 0: FilePos = 0
IF NumDirs - 1 < 8 THEN
  LINE (261, 77)-(273, 130), FCol, BF
ELSE
  LINE (261, 77)-(273, 79), FCol, BF
END IF
IF NumFiles - 1 < 8 THEN
  LINE (117, 77)-(129, 130), FCol, BF
ELSE
  LINE (117, 77)-(129, 79), FCol, BF
END IF

Sort DirItem$(), 0, NumDirs - 1
nDrives = NumDrives
FOR i = 0 TO nDrives
  DirItem$(NumDirs + i) = "[-" + CHR$(65 + i) + "-]"
NEXT i
NumDirs = NumDirs + nDrives

IF NumDirs - 1 < 8 THEN
  FOR i = 0 TO NumDirs - 1
    LOCATE 10 + i, 24: PRINT DirItem$(i);
  NEXT i
ELSE
  FOR i = 0 TO 7
    LOCATE 10 + i, 24: PRINT DirItem$(i);
  NEXT i
END IF
IF NumFiles > 1 THEN Sort FileItem$(), 0, NumFiles - 1
IF NumFiles > 0 THEN
  IF NumFiles - 1 < 8 THEN
    FOR i = 0 TO NumFiles - 1
      LOCATE 10 + i, 6: PRINT FileItem$(i);
    NEXT i
  ELSE
    FOR i = 0 TO 7
      LOCATE 10 + i, 6: PRINT FileItem$(i);
    NEXT i
  END IF
END IF

MouseShow
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
DO
  MouseStatus Lb, Rb, x, y
  IF Lb THEN
    IF x \ 2 > 115 AND x \ 2 < 131 THEN
      IF y > 68 AND y < 75 THEN
        IF FilePos > 0 THEN
          MouseHide
          FilePos = FilePos - 1
          LINE (117, 77)-(129, 130), BCol, BF
          LINE (117, 77 + CSNG((50 / (NumFiles - 8)) * FilePos))-(129, 79 + CSNG((50 / (NumFiles - 8)) * FilePos)), FCol, BF
          FOR i = 0 TO 7
            LOCATE 10 + i, 6: PRINT SPACE$(8);
            LOCATE 10 + i, 6: PRINT FileItem$(i + FilePos);
          NEXT i
          MouseShow
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .02
        END IF
      END IF
      IF y > 132 AND y < 139 THEN
        IF FilePos < NumFiles - 8 THEN
          MouseHide
          FilePos = FilePos + 1
          LINE (117, 77)-(129, 130), BCol, BF
          LINE (117, 77 + CSNG((50 / (NumFiles - 8)) * FilePos))-(129, 79 + CSNG((50 / (NumFiles - 8)) * FilePos)), FCol, BF
          FOR i = 0 TO 7
            LOCATE 10 + i, 6: PRINT SPACE$(8);
            LOCATE 10 + i, 6: PRINT FileItem$(i + FilePos);
          NEXT i
          MouseShow
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .02
        END IF
      END IF
    END IF
    IF x \ 2 > 259 AND x \ 2 < 275 THEN
      IF y > 68 AND y < 75 THEN
        IF DirPos > 0 THEN
          MouseHide
          DirPos = DirPos - 1
          LINE (261, 77)-(273, 130), BCol, BF
          LINE (261, 77 + CSNG((50 / (NumDirs - 8)) * DirPos))-(273, 79 + CSNG((50 / (NumDirs - 8)) * DirPos)), FCol, BF
          FOR i = 0 TO 7
            LOCATE 10 + i, 24: PRINT SPACE$(8);
            LOCATE 10 + i, 24: PRINT DirItem$(i + DirPos);
          NEXT i
          MouseShow
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .02
        END IF
      END IF
      IF y > 132 AND y < 139 THEN
        IF DirPos < NumDirs - 8 THEN
          MouseHide
          DirPos = DirPos + 1
          LINE (261, 77)-(273, 130), BCol, BF
          LINE (261, 77 + CSNG((50 / (NumDirs - 8)) * DirPos))-(273, 79 + CSNG((50 / (NumDirs - 8)) * DirPos)), FCol, BF
          FOR i = 0 TO 7
            LOCATE 10 + i, 24: PRINT SPACE$(8);
            LOCATE 10 + i, 24: PRINT DirItem$(i + DirPos);
          NEXT i
          MouseShow
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .02
        END IF
      END IF
    END IF
    IF x \ 2 > 184 AND x \ 2 < 256 THEN
      IF y > 72 AND y < 135 THEN
        SelectedDir = DirPos + ((y - 72) \ 8)
        IF NOT FloppyDriveReady(CurrentDrive$) THEN ERROR 71
        IF DirItem$(SelectedDir) = ".." THEN
          CHDIR ".."
          GOSUB RefreshDir
        ELSE
          ChD = 0
          FOR i = 0 TO 25
            IF DirItem$(SelectedDir) = "[-" + CHR$(65 + i) + "-]" THEN ChD = 65 + i
          NEXT i
          IF ChD <> 0 THEN
            IF NOT FloppyDriveReady(CHR$(ChD)) THEN ERROR 71
            ChangeDrive CHR$(ChD)
            CHDIR "\"
            GOSUB RefreshDir
          ELSE
            CHDIR DirItem$(SelectedDir)
            GOSUB RefreshDir
          END IF
        END IF
        t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
      END IF
    END IF
    IF x \ 2 > 40 AND x \ 2 < 112 THEN
      IF y > 72 AND y < 135 THEN
        SelectedFile = -1
        IF NumFiles > 8 THEN
          SelectedFile = FilePos + ((y - 72) \ 8)
        ELSE
          IF ((y - 72) \ 8) <= NumFiles - 1 THEN
            SelectedFile = ((y - 72) \ 8)
          END IF
        END IF
        IF SelectedFile <> -1 THEN
          SelFile$ = FileItem$(SelectedFile) + "."
          SELECT CASE Mode
          CASE 1, 2, 3: SelFile$ = SelFile$ + BinExt
          CASE 4, 5: SelFile$ = SelFile$ + BlkExt
          CASE 6: SelFile$ = SelFile$ + PalExt
          END SELECT
          DrawButton 18, 6, SelFile$ + SPACE$(13 - LEN(SelFile$))
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
        END IF
      END IF
    END IF
    IF x \ 2 > 132 AND x \ 2 < 244 THEN
      IF y > 36 AND y < 51 THEN
        MouseHide
        DO
          LOCATE 6, 18: PRINT SelFile$ + CHR$(219);
          k$ = INKEY$: WHILE k$ = "": k$ = INKEY$: WEND
          k$ = UCASE$(k$)
          IF k$ = CHR$(8) THEN
            IF LEN(SelFile$) > 0 THEN
              SelFile$ = LEFT$(SelFile$, LEN(SelFile$) - 1)
              LOCATE 6, 18: PRINT SelFile$ + CHR$(219) + " ";
            END IF
          ELSE
            IF k$ = CHR$(13) THEN
              IF LEN(SelFile$) > 0 THEN
                IF LEFT$(SelFile$, 1) <> "." THEN EXIT DO
              END IF
            ELSE
              IF k$ <> "\" THEN
                IF k$ = "." THEN
                  IF INSTR(SelFile$, ".") = 0 THEN
                    IF LEN(SelFile$) < 12 THEN SelFile$ = SelFile$ + k$
                  END IF
                ELSE
                  IF INSTR(SelFile$, ".") = 0 THEN
                    IF LEN(SelFile$) < 8 THEN SelFile$ = SelFile$ + k$
                  ELSE
                    IF LEN(SelFile$) < INSTR(SelFile$, ".") + 3 THEN
                      IF LEN(SelFile$) < 12 THEN SelFile$ = SelFile$ + k$
                    END IF
                  END IF
                END IF
              END IF
            END IF
          END IF
        LOOP
        IF INSTR(SelFile$, ".") = 0 THEN
          SelFile$ = SelFile$ + "."
          SELECT CASE Mode
          CASE 1, 2, 3: SelFile$ = SelFile$ + BinExt
          CASE 4, 5: SelFile$ = SelFile$ + BlkExt
          CASE 6, 7: SelFile$ = SelFile$ + PalExt
          END SELECT
        END IF
        LOCATE 6, 18: PRINT SelFile$ + " ";
        MouseShow
      END IF
    END IF
    IF y > 150 AND y < 166 THEN
      IF x \ 2 > 164 AND x \ 2 < 220 THEN
        EXIT DO
      END IF
      IF x \ 2 > 228 AND x \ 2 < 280 THEN
        SelFile$ = "": EXIT DO
      END IF
    END IF
  END IF
LOOP

SelectFile$ = SelFile$
EXIT FUNCTION

RefreshDir:
MouseHide
IF NOT FloppyDriveReady(CurrentDrive$) THEN ERROR 71
FOR i = 0 TO 200: FileN$(i) = "": FileE$(i) = "": FileT(i) = 0: FileItem$(i) = "": NEXT i
FOR i = 0 TO 50: DirItem$(i) = "": NEXT i
Path$ = RealPath$
IF LEN(Path$) > 28 THEN
  Path$ = LEFT$(Path$, 25) + "..\"
END IF
LOCATE 8, 6: PRINT SPACE$(28)
LOCATE 8, 6: PRINT Path$
IF LEN(RealPath$) = 3 THEN Mask$ = RealPath$ + "*.*" ELSE Mask$ = RealPath$ + "\*.*"
GetDir FileN$(), FileE$(), FileT(), DirNum, Mask$, Status
NumFiles = 0
Sf$ = BinExt
IF Mode = 4 OR Mode = 5 THEN Sf$ = BlkExt
IF Mode = 6 OR Mode = 7 THEN Sf$ = PalExt
FOR i = 0 TO DirNum - 1
  IF FileE$(i) = Sf$ AND FileT(i) = FILE AND NumFiles < 200 THEN FileItem$(NumFiles) = FileN$(i): NumFiles = NumFiles + 1
NEXT i
IF LEN(Path$) > 3 THEN
  DirItem$(0) = ".."
  NumDirs = 1
ELSE
  NumDirs = 0
END IF
FOR i = 0 TO DirNum - 1
  IF FileT(i) = DIRECTORY AND NumDirs < 44 THEN DirItem$(NumDirs) = FileN$(i): NumDirs = NumDirs + 1
NEXT i
Sort DirItem$(), 0, NumDirs - 1
nDrives = NumDrives
FOR i = 0 TO nDrives
  DirItem$(NumDirs + i) = "[-" + CHR$(65 + i) + "-]"
NEXT i
NumDirs = NumDirs + nDrives
FOR i = 0 TO 7: LOCATE 10 + i, 6: PRINT SPACE$(8): LOCATE 10 + i, 24: PRINT SPACE$(8): NEXT i
IF NumDirs - 1 < 8 THEN
  FOR i = 0 TO NumDirs - 1
    LOCATE 10 + i, 24: PRINT DirItem$(i);
  NEXT i
ELSE
  FOR i = 0 TO 7
    LOCATE 10 + i, 24: PRINT DirItem$(i);
  NEXT i
END IF
IF NumFiles > 1 THEN Sort FileItem$(), 0, NumFiles - 1
IF NumFiles > 0 THEN
  IF NumFiles - 1 < 8 THEN
    FOR i = 0 TO NumFiles - 1
      LOCATE 10 + i, 6: PRINT FileItem$(i);
    NEXT i
  ELSE
    FOR i = 0 TO 7
      LOCATE 10 + i, 6: PRINT FileItem$(i);
    NEXT i
  END IF
END IF
LINE (261, 77)-(273, 130), BCol, BF
LINE (117, 77)-(129, 130), BCol, BF
DirPos = 0: FilePos = 0
IF NumDirs - 1 < 8 THEN
  LINE (261, 77)-(273, 130), FCol, BF
ELSE
  LINE (261, 77)-(273, 79), FCol, BF
END IF
IF NumFiles - 1 < 8 THEN
  LINE (117, 77)-(129, 130), FCol, BF
ELSE
  LINE (117, 77)-(129, 79), FCol, BF
END IF
MouseShow
MouseShow
RETURN

END FUNCTION

SUB ShiftBlock
'
x2 = x: y2 = y
PUT (0, 0), Video&, PSET
PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
REDIM Video&(0)
REDIM b1&(100), b2&(16000)
MouseRange 0, 0, 639, 199
Oldx = x: Oldy = y
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
DO
  MouseStatus Lb, Rb, x, y
  IF x <> Oldx OR y <> Oldy THEN
    IF y2 <> y1 THEN
      IF y < Oldy THEN
        GET (x1 \ 2, y1)-(x2 \ 2, y1), b1&
        GET (x1 \ 2, y1 + 1)-(x2 \ 2, y2), b2&
        PUT (x1 \ 2, y1), b2&, PSET
        PUT (x1 \ 2, y2), b1&, PSET
      END IF
      IF y > Oldy THEN
        GET (x1 \ 2, y1)-(x2 \ 2, y2 - 1), b2&
        GET (x1 \ 2, y2)-(x2 \ 2, y2), b1&
        PUT (x1 \ 2, y1 + 1), b2&, PSET
        PUT (x1 \ 2, y1), b1&, PSET
      END IF
    END IF
    IF x2 <> x1 THEN
      IF x < Oldx THEN
        GET (x1 \ 2, y1)-(x1 \ 2, y2), b1&
        GET ((x1 \ 2) + 1, y1)-(x2 \ 2, y2), b2&
        PUT ((x2 \ 2), y1), b1&, PSET
        PUT (x1 \ 2, y1), b2&, PSET
      END IF
      IF x > Oldx THEN
        GET (x2 \ 2, y1)-(x2 \ 2, y2), b1&
        GET (x1 \ 2, y1)-((x2 \ 2) - 1, y2), b2&
        PUT (x1 \ 2, y1), b1&, PSET
        PUT ((x1 \ 2) + 1, y1), b2&, PSET
      END IF
    END IF
  END IF
  Oldx = x: Oldy = y
  IF Lb THEN EXIT DO
LOOP
ERASE b1&, b2&
REDIM Video&(16000)
GET (0, 0)-(319, 199), Video&
IF CoordBox = 0 THEN GET (0, 190)-(319, 199), CoordBox& ELSE GET (0, 0)-(319, 9), CoordBox&
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3

END SUB

SUB Sort (A$(), Low, High)
'
  IF Low < High THEN
      IF High - Low = 1 THEN
         IF A$(Low) > A$(High) THEN
            SWAP A$(Low), A$(High)
         END IF
      ELSE
         RANDOMIZE TIMER
         RandIndex = INT(RND(1) * (High - Low) + .5) + Low
         SWAP A$(High), A$(RandIndex)
         Partition$ = A$(High)
         DO

            i = Low: J = High
            DO WHILE (i < J) AND (A$(i) <= Partition$)
               i = i + 1
            LOOP
            DO WHILE (J > i) AND (A$(J) >= Partition$)
               J = J - 1
            LOOP

            IF i < J THEN
               SWAP A$(i), A$(J)
            END IF
         LOOP WHILE i < J

         SWAP A$(i), A$(High)

         IF (i - Low) < (High - i) THEN
            Sort A$(), Low, i - 1
            Sort A$(), i + 1, High
         ELSE
            Sort A$(), i + 1, High
            Sort A$(), Low, i - 1
         END IF
      END IF
   END IF
END SUB

SUB SubMenu (SMenu)
'
MouseHide
SELECT CASE SMenu
CASE 0
  LINE (0, 9)-(82, 78), BCol, BF
  LINE (0, 9)-(81, 77), FCol, B
  LOCATE 3, 2: PRINT "New"
  LOCATE 4, 2: PRINT "Load"
  LOCATE 5, 2: PRINT "Save"
  LOCATE 6, 2: PRINT "Save as"
  LOCATE 7, 2: PRINT "Delete"
  LOCATE 8, 2: PRINT "About"
  LOCATE 9, 2: PRINT "Quit"
  MouseShow
  SelSubMenu = -1
  DO
    MouseStatus Lb, Rb, x, y
    IF y > 71 OR x \ 2 > 82 THEN EXIT DO
    IF y > 16 THEN
      NewMenu = (y - 16) \ 8
      IF NewMenu <> SelSubMenu THEN
        MouseHide
        IF SelSubMenu <> -1 THEN PUT (1, (SelSubMenu * 8) + 16), SelBox&
        SelSubMenu = NewMenu
        PUT (1, (SelSubMenu * 8) + 16), SelBox&
        MouseShow
      END IF
    END IF
    IF Lb AND SelSubMenu <> -1 THEN
      SELECT CASE SelSubMenu
      CASE 0
        NewFile
        EXIT DO
      CASE 1
        LoadFile
        EXIT DO
      CASE 2
        MouseHide
        PUT (0, 0), Video&, PSET
        IF INSTR(FileName$, ".") <> 0 THEN
          FileNamex$ = LEFT$(FileName$, INSTR(FileName$, ".") - 1)
        ELSE
          FileNamex$ = FileName$
        END IF
        OPEN FileNamex$ + "." + PalExt FOR BINARY AS #1
        FOR i = 0 TO 255
          PalGet i, R, G, B
          R$ = CHR$(R): PUT #1, , R$
          G$ = CHR$(G): PUT #1, , G$
          B$ = CHR$(B): PUT #1, , B$
        NEXT i
        CLOSE #1
        IF SaveSpace = TRUE THEN
          Space! = CountSpace!
          DEF SEG = &HA000: BSAVE FileName$, 0, Space!
        ELSE
          DEF SEG = &HA000: BSAVE FileName$, 0, 64000
        END IF
        GET (0, 0)-(319, 199), Video&
        GET (0, 190)-(319, 199), CoordBox&
        MouseShow
        EXIT DO
      CASE 3
        SaveFile
        EXIT DO
      CASE 4
        DeleteFile
        EXIT DO
      CASE 5
        About
        EXIT DO
      CASE 6
        IF Quit THEN
          SCREEN 0: WIDTH 80
          IF FloppyDriveReady(LEFT$(OriginalPath$, 1)) THEN
            ChangeDrive LEFT$(OriginalPath$, 1)
            CHDIR MID$(OriginalPath$, 3, LEN(OriginalPath$) - 2)
          END IF
          END
        END IF
        EXIT DO
      END SELECT
    END IF
  LOOP
  MouseHide
  PUT (0, 0), Video&, PSET
  DrawMenu
  MouseShow
CASE 1
  LINE (78, 9)-(161, 94), BCol, BF
  LINE (79, 9)-(160, 93), FCol, B
  LOCATE 3, 12: PRINT "Pen"
  LOCATE 4, 12: PRINT "Line"
  LOCATE 5, 12: PRINT "Box"
  LOCATE 6, 12: PRINT "Full box"
  LOCATE 7, 12: PRINT "Filler"
  LOCATE 8, 12: PRINT "Circle"
  LOCATE 9, 12: PRINT "Rubber"
  LOCATE 10, 12: PRINT "Spray"
  LOCATE 11, 12: PRINT "Lens"
  MouseShow
  SelSubMenu = -1
  DO
    MouseStatus Lb, Rb, x, y
    IF y > 87 OR x \ 2 < 78 OR x \ 2 > 161 THEN EXIT DO
    IF y > 16 THEN
      NewMenu = (y - 16) \ 8
      IF NewMenu <> SelSubMenu THEN
        MouseHide
        IF SelSubMenu <> -1 THEN PUT (80, (SelSubMenu * 8) + 16), SelBox&
        SelSubMenu = NewMenu
        PUT (80, (SelSubMenu * 8) + 16), SelBox&
        MouseShow
      END IF
    END IF
    IF Lb AND SelSubMenu <> -1 THEN
      Tool = ((y - 16) \ 8)
      EXIT DO
    END IF
  LOOP
  MouseHide
  PUT (0, 0), Video&, PSET
  DrawMenu
  MouseShow
CASE 2
  LINE (158, 9)-(241, 86), BCol, BF
  LINE (159, 9)-(240, 85), FCol, B
  LOCATE 3, 22: PRINT "Invert"
  LOCATE 4, 22: PRINT "Shift"
  LOCATE 5, 22: PRINT "Rotate"
  LOCATE 6, 22: PRINT "Modify"
  LOCATE 7, 22: PRINT "Copy"
  LOCATE 8, 22: PRINT "Move"
  LOCATE 9, 22: PRINT "Load BLK"
  LOCATE 10, 22: PRINT "Save BLK"
  MouseShow
  SelSubMenu = -1
  DO
    MouseStatus Lb, Rb, x, y
    IF y > 79 OR x \ 2 < 158 OR x \ 2 > 241 THEN EXIT DO
    IF y > 16 THEN
      NewMenu = (y - 16) \ 8
      IF NewMenu <> SelSubMenu THEN
        MouseHide
        IF SelSubMenu <> -1 THEN PUT (160, (SelSubMenu * 8) + 16), SelBox&
        SelSubMenu = NewMenu
        PUT (160, (SelSubMenu * 8) + 16), SelBox&
        MouseShow
      END IF
    END IF
    IF Lb AND SelSubMenu <> -1 THEN
      Tool = ((y - 16) \ 8) + 9
      IF Tool > 14 THEN
        HandleBlk
      END IF
      EXIT DO
    END IF
  LOOP
  MouseHide
  PUT (0, 0), Video&, PSET
  DrawMenu
  MouseShow
CASE 3
  LINE (237, 9)-(319, 62), BCol, BF
  LINE (238, 9)-(319, 61), FCol, B
  LOCATE 3, 32: PRINT "Prefs"
  LOCATE 4, 32: PRINT "Palette"
  LOCATE 5, 32: PRINT "Load PAL"
  LOCATE 6, 32: PRINT "Save PAL"
  LOCATE 7, 32: PRINT "Help"
  MouseShow
  SelSubMenu = -1
  DO
    MouseStatus Lb, Rb, x, y
    IF y > 55 OR x \ 2 < 237 THEN EXIT DO
    IF y > 16 THEN
      NewMenu = (y - 16) \ 8
      IF NewMenu <> SelSubMenu THEN
        MouseHide
        IF SelSubMenu <> -1 THEN PUT (239, (SelSubMenu * 8) + 16), SelBox&
        SelSubMenu = NewMenu
        PUT (239, (SelSubMenu * 8) + 16), SelBox&
        MouseShow
      END IF
    END IF
    IF Lb AND SelSubMenu <> -1 THEN
      SELECT CASE SelSubMenu
      CASE 0
        Preferences
      CASE 1
        EditPalette
      CASE 2
        PalFile$ = SelectFile$(6)
        IF PalFile$ <> "" THEN
          OPEN PalFile$ FOR BINARY AS #1
          IF LOF(1) <> 768 THEN ERROR 62
          DIM Buf AS STRING * 1
          FOR i = 0 TO 255
            GET #1, , Buf: R = ASC(Buf)
            GET #1, , Buf: G = ASC(Buf)
            GET #1, , Buf: B = ASC(Buf)
            IF R > 63 OR G > 63 OR B > 63 THEN ERROR 62
            PalSet i, R, G, B
          NEXT i
          CLOSE #1
        END IF
      CASE 3
        PalFile$ = SelectFile$(7)
        IF PalFile$ <> "" THEN
          OPEN PalFile$ FOR BINARY AS #1
          FOR i = 0 TO 255
            PalGet i, R, G, B
            R$ = CHR$(R): PUT #1, , R$
            G$ = CHR$(G): PUT #1, , G$
            B$ = CHR$(B): PUT #1, , B$
          NEXT i
          CLOSE #1
        END IF
      CASE 4
        HelpPage = 1
        Help
      END SELECT
      EXIT DO
    END IF
  LOOP
  MouseHide
  PUT (0, 0), Video&, PSET
  DrawMenu
  MouseShow

END SELECT

  
END SUB

SUB ToolOn
'
SELECT CASE Tool
CASE PENCIL
  IF JustPressed = 0 THEN
    JustPressed = 1
    MouseHide
    PSET (x \ 2, y), Col
    Oldx = x: Oldy = y
    MouseShow
  ELSE
    MouseHide
    LINE -(x \ 2, y), Col
    Oldx = x: Oldy = y
    MouseShow
  END IF
CASE LINER, BOX, BOXFULL, ELLIPSE
  IF Pointed = 0 THEN
    Pointed = 1
    x1 = x: y1 = y
    t! = TIMER: DO: LOOP UNTIL TIMER > t! + .2
    MouseHide
    PUT (0, 0), Video&, PSET
    GET (0, 0)-(319, 9), Temp1&
    GET (0, 190)-(319, 199), Temp2&
    IF Tool = ELLIPSE THEN MouseRange x, y, 639, 199
    MouseShow
  ELSE
    Pointed = 0
    MouseHide
    PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
    IF CoordBox = 0 THEN
      SELECT CASE Tool
      CASE LINER: LINE (x1 \ 2, y1)-(x \ 2, y), Col
      CASE BOX: LINE (x1 \ 2, y1)-(x \ 2, y), Col, B
      CASE BOXFULL: LINE (x1 \ 2, y1)-(x \ 2, y), Col, BF
      CASE ELLIPSE
        r1 = ABS((x1 \ 2) - (x \ 2)) \ 2: r2 = ABS(y1 - y) \ 2
        IF r1 > r2 THEN R = r1 ELSE R = r2
        Dy = ABS(y1 - y): Dx = ABS((x1 \ 2) - (x \ 2))
        IF Dx = 0 THEN Aspect! = 1000000 ELSE Aspect! = Dy / Dx
        CIRCLE ((x1 \ 2) + r1, y1 + r2), R, Col, , , Aspect!
        MouseRange 0, 0, 639, 199
      END SELECT
      GET (0, 0)-(319, 199), Video&
      GET (0, 190)-(319, 199), CoordBox&
    ELSE
      SELECT CASE Tool
      CASE LINER: LINE (x1 \ 2, y1)-(x \ 2, y), Col
      CASE BOX: LINE (x1 \ 2, y1)-(x \ 2, y), Col, B
      CASE BOXFULL: LINE (x1 \ 2, y1)-(x \ 2, y), Col, BF
      CASE ELLIPSE
        r1 = ABS((x1 \ 2) - (x \ 2)) \ 2: r2 = ABS(y1 - y) \ 2
        IF r1 > r2 THEN R = r1 ELSE R = r2
        Dy = ABS(y1 - y): Dx = ABS((x1 \ 2) - (x \ 2))
        IF Dx = 0 THEN Aspect! = 1000000 ELSE Aspect! = Dy / Dx
        CIRCLE ((x1 \ 2) + r1, y1 + r2), R, Col, , , Aspect!
        MouseRange 0, 0, 639, 199
      END SELECT
      GET (0, 0)-(319, 199), Video&
      GET (0, 0)-(319, 9), CoordBox&
    END IF
    MouseShow
    t! = TIMER: DO: LOOP UNTIL TIMER > t! + .2
  END IF
CASE FILLER
  MouseHide
  PUT (0, 0), Video&, PSET
  PAINT (x \ 2, y), Col, Col
  IF CoordBox = 0 THEN GET (0, 190)-(319, 199), CoordBox& ELSE GET (0, 0)-(319, 9), CoordBox&
  MouseShow
  t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
CASE RUBBER
  MouseHide
  PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
  LINE ((x \ 2) - RubX, y - RubY)-(x \ 2, y), BCol, BF
  GET (0, 0)-(319, 199), Video&
  GET (0, 0)-(319, 9), Temp1&: GET (0, 190)-(319, 199), Temp2&
  MouseShow
CASE SPRAY
  MouseHide
  PUT (0, 0), Video&, PSET
  FOR i = 1 TO ((SprayX * SprayY) / 100) * (SprayI / 10)
    RANDOMIZE TIMER
    PSET ((x \ 2) - INT(RND(1) * SprayX), y - INT(RND(1) * SprayY)), Col
  NEXT i
  GET (0, 0)-(319, 199), Video&
  MouseShow
CASE LENS
  ZoomEdit
CASE INVERT, SHIFT, ROTATE, MODIFY, COPY, MOVE
  IF Pointed = 0 THEN
    Pointed = 1
    x1 = x: y1 = y
    t! = TIMER: DO: LOOP UNTIL TIMER > t! + .2
    MouseHide
    PUT (0, 0), Video&, PSET
    GET (0, 0)-(319, 9), Temp1&
    GET (0, 190)-(319, 199), Temp2&
    MouseRange x, y, 639, 199
    IF Tool = ROTATE THEN
      IF ((639 - x) \ 2) > (199 - y) THEN
        MouseRange x, y, 639, 199
      ELSE
        MouseRange x, y, 639, y + ((639 - x) \ 2)
      END IF
    END IF
    MouseShow
  ELSE
    Pointed = 0
    MouseHide
    PUT (0, 0), Video&, PSET
    PUT (0, 0), Temp1&, PSET: PUT (0, 190), Temp2&, PSET
    SELECT CASE Tool
    CASE INVERT
      LINE (x1 \ 2, y1)-(x \ 2, y), FCol, B
      InvertBlock
    CASE SHIFT
      LINE (x1 \ 2, y1)-(x \ 2, y), FCol, B
      ShiftBlock
    CASE ROTATE
      LINE (x1 \ 2, y1)-((x1 \ 2) + (y - y1), y), FCol, B
      RotateBlock
    CASE MODIFY
      LINE (x1 \ 2, y1)-(x \ 2, y), FCol, B
      ModifyBlock
    CASE COPY, MOVE
      IF Tool = COPY THEN MoveBlock 1 ELSE MoveBlock 2
    END SELECT
  END IF

END SELECT

END SUB

SUB ZoomEdit
'
x1 = x: y1 = y
MouseHide
MouseRange 0, 0, 639, 199
DIM Zoomed&(1000)
PUT (0, 0), Video&, PSET
GET ((x \ 2) - 39, y - 33)-(x \ 2, y), Zoomed&
DrawWindow 4, 2, 37, 24, "Zoomed area"
LINE (25, 19)-(227, 191), FCol, B
LINE (232, 20)-(291, 144), FCol, B
FOR i = 0 TO 255
  LINE (((i \ 24) * 5) + 235, ((i MOD 24) * 5) + 23)-(((i \ 24) * 5) + 238, ((i MOD 24) * 5) + 26), i, BF
NEXT i
LINE (((Col \ 24) * 5) + 234, ((Col MOD 24) * 5) + 22)-(((Col \ 24) * 5) + 239, ((Col MOD 24) * 5) + 27), FCol, B
LINE (241, 147)-(282, 182), FCol, B
PUT (242, 148), Zoomed&, PSET
FOR i = 0 TO 39: FOR ii = 0 TO 33
  LINE (27 + (i * 5), 21 + (ii * 5))-(30 + (i * 5), 24 + (ii * 5)), POINT(242 + i, 148 + ii), BF
NEXT ii, i
BackCol = 0: IF Col = 0 THEN BackCol = 2
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
Oldx = x: Oldy = y
DO
  MouseStatus Lb, Rb, x, y
  IF x <> Oldx OR y <> Oldy THEN
    IF x \ 2 > 26 AND x \ 2 < 226 THEN
      IF y > 20 AND y < 190 THEN
        MouseHide
        PSET (((BackCol \ 24) * 5) + 234, ((BackCol MOD 24) * 5) + 22), BCol
        PSET (((BackCol \ 24) * 5) + 239, ((BackCol MOD 24) * 5) + 22), BCol
        PSET (((BackCol \ 24) * 5) + 234, ((BackCol MOD 24) * 5) + 27), BCol
        PSET (((BackCol \ 24) * 5) + 239, ((BackCol MOD 24) * 5) + 27), BCol
        LINE (((Col \ 24) * 5) + 234, ((Col MOD 24) * 5) + 22)-(((Col \ 24) * 5) + 239, ((Col MOD 24) * 5) + 27), FCol, B
        xc = ((x \ 2) - 27) \ 5: yc = (y - 21) \ 5
        BackCol = POINT(242 + xc, 148 + yc)
        PSET (((BackCol \ 24) * 5) + 234, ((BackCol MOD 24) * 5) + 22), FCol
        PSET (((BackCol \ 24) * 5) + 239, ((BackCol MOD 24) * 5) + 22), FCol
        PSET (((BackCol \ 24) * 5) + 234, ((BackCol MOD 24) * 5) + 27), FCol
        PSET (((BackCol \ 24) * 5) + 239, ((BackCol MOD 24) * 5) + 27), FCol
        MouseShow
        WAIT &H3DA, 8
      END IF
    END IF
    MouseHide
    LOCATE 24, 30: PRINT USING "###:###"; xc + (x1 \ 2) - 39; yc + y1 - 33;
    MouseShow
    WAIT &H3DA, 8
  END IF
  IF Lb THEN
    IF x \ 2 > 26 AND x \ 2 < 226 THEN
      IF y > 20 AND y < 190 THEN
        xc = ((x \ 2) - 27) \ 5: yc = (y - 21) \ 5
        MouseHide
        LINE (27 + (xc * 5), 21 + (yc * 5))-(30 + (xc * 5), 24 + (yc * 5)), Col, BF
        PSET (242 + xc, 148 + yc), Col
        MouseShow
        WAIT &H3DA, 8
      END IF
    END IF
    IF x \ 2 > 234 AND x \ 2 < 289 THEN
      IF y > 22 AND y < 142 THEN
        IF x \ 2 < 284 OR y < 102 THEN
          MouseHide
          LINE (((Col \ 24) * 5) + 234, ((Col MOD 24) * 5) + 22)-(((Col \ 24) * 5) + 239, ((Col MOD 24) * 5) + 27), BCol, B
          Col = ((((x \ 2) - 234) \ 5) * 24) + ((y - 22) \ 5)
          LINE (((Col \ 24) * 5) + 234, ((Col MOD 24) * 5) + 22)-(((Col \ 24) * 5) + 239, ((Col MOD 24) * 5) + 27), FCol, B
          MouseShow
          WAIT &H3DA, 8
          t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
        END IF
      END IF
    END IF
  END IF
  IF Rb THEN EXIT DO
  Oldx = x: Oldy = y
LOOP
MouseHide
GET (242, 148)-(281, 181), Zoomed&
PUT (0, 0), Video&, PSET
PUT ((x1 \ 2) - 39, y1 - 33), Zoomed&, PSET
GET (0, 0)-(319, 199), Video&
MouseShow
t! = TIMER: DO: LOOP UNTIL TIMER > t! + .3
Rb = FALSE
MouseRange 78, 33, 639, 199
END SUB

