DEFINT A-Z
DECLARE SUB SetupPatterns (Patterns)
DECLARE SUB PlaceSprites (NumOfSprites)
DECLARE SUB ClearSprites (NumOfSprites)
DECLARE SUB CheckMode (X, Y, NumOfSprites, Patterns)
DECLARE SUB MoveSprites (X, Y, Sprites)
DECLARE SUB SetupSprites (Sprites)
DECLARE SUB CheckOnButtons (X, Y, Button)
DECLARE SUB SetupMouse ()
DECLARE SUB CheckOnMouse (X, Y, Button)
SCREEN 12
RANDOMIZE TIMER
DEF FnDistance (Ax, Ay, Bx, By)
 Side1 = ABS(Ax - Bx)
 Side2 = ABS(Ay - By)
 FnDistance = SQR((Side1 ^ 2) + (Side2 ^ 2))
END DEF
TYPE Sprite
 X AS INTEGER
 Y AS INTEGER
 Mode AS INTEGER
 Pattern AS INTEGER
 PatternDone AS INTEGER
 Colour AS INTEGER
END TYPE
NumOfSprites = 15
Patterns = 3
DIM SHARED Mouse(9)
DIM SHARED Sprites(NumOfSprites) AS Sprite
DIM SHARED Pattern(Patterns, 100)
CLS
SetupMouse
SetupSprites NumOfSprites
SetupPatterns Patterns
DO
 FOR d = 1 TO 7000: NEXT d
 CheckOnButtons X, Y, Button
 CheckMode X, Y, NumOfSprites, Patterns

 ClearSprites NumOfSprites
 MoveSprites X, Y, NumOfSprites
 PlaceSprites NumOfSprites
 PRESET (X, Y)
 CheckOnMouse X, Y, Button
 PSET (X, Y), 16
LOOP UNTIL INKEY$ = CHR$(27)
POKE VARPTR(Mouse(0)) + 1, 2
CALL absolute(c, VARPTR(Mouse(0)))
DEF SEG
END
DATA &HB8,&H00,&H00
DATA &H55
DATA &H8B,&HEC
DATA &HCD,&H33
DATA &H92
DATA &H8B,&H5E,&H06
DATA &H89,&H07
DATA &H5D
DATA &HCA,&H02,&H00
DATA 4,4,4,4,4,4,4,1,1,1,4,4,1,1,4,1,4,4,4,1,1,4,4,4,1,4,4,4,3,3,4,4,3,4,4,3,4,3,3,3,3,2,2,3,2,2,3,3,3,2,3,3,2,3,2,3,3,3,4,4,3,3,4,3,3,3,2,2,3,2,2,3,2,2,3,2,3,3,3,2,2,2,2,2,1,2,1,2,1,2,1,1,1,2,2,1,2,1,2,1
DATA 4,4,4,4,4,3,3,4,3,4,3,3,3,2,2,3,3,2,2,2,2,1,2,1,2,1,1,4,1,4,1,4,4,1,4,1,1,4,1,1,1,1,1,2,1,1,2,2,2,1,2,2,1,2,1,2,2,2,3,3,2,3,2,3,3,3,3,4,4,4,4,1,1,4,1,4,1,4,1,4,1,4,1,4,4,4,1,4,4,1,4,4,4,3,3,4,3,4,3,3
DATA 4,4,4,4,3,4,3,4,3,3,4,3,4,3,3,2,3,2,2,3,2,2,2,3,3,3,4,4,4,4,1,1,2,1,1,4,1,2,2,2,1,1,4,3,2,2,2,1,1,1,2,2,3,3,3,4,3,3,3,2,2,1,2,1,1,2,2,1,1,4,1,1,4,1,4,2,2,2,2,2,2,3,3,3,4,3,4,3,4,3,3,3,3,3,2,3,2,2,1,2

SUB CheckMode (X, Y, NumOfSprites, Patterns)
FOR S = 1 TO NumOfSprites
 IF Sprites(S).Mode = 1 THEN
  IF FnDistance(X, Y, Sprites(S).X, Sprites(S).Y) > 200 THEN Sprites(S).Mode = 3
 ELSEIF Sprites(S).Mode = 2 THEN
  IF FnDistance(X, Y, Sprites(S).X, Sprites(S).Y) < 10 THEN
   Pat = RND * 4
   IF Pat = 1 THEN
    Sprites(S).Mode = 4
    Sprites(S).Pattern = INT(RND * Patterns) + 1
    Sprites(S).PatternDone = 1
   ELSE
    Sprites(S).Mode = 1
   END IF
  END IF
 ELSEIF Sprites(S).Mode = 3 THEN
  Move = RND * 100
  IF Move = 1 THEN Sprites(S).Mode = 2
  IF FnDistance(X, Y, Sprites(S).X, Sprites(S).Y) < 35 THEN
   Pat = RND * 4
   IF Pat = 1 THEN
    Sprites(S).Mode = 4
    Sprites(S).Pattern = RND * Patterns
    Sprites(S).PatternDone = 1
   ELSE
    Sprites(S).Mode = 2
   END IF
  END IF
 END IF
NEXT S
END SUB

SUB CheckOnButtons (X, Y, Button)
IF Button = 1 THEN
END IF
END SUB

SUB CheckOnMouse (X, Y, Button)
POKE VARPTR(Mouse(4)), &H92              ' setup y
CALL absolute(Y, VARPTR(Mouse(0)))       ' run machine code
POKE VARPTR(Mouse(4)), &H91              ' setup x
CALL absolute(X, VARPTR(Mouse(0)))       ' run machine code
POKE VARPTR(Mouse(4)), &H93              ' setup buttons
CALL absolute(Button, VARPTR(Mouse(0)))  ' run machine code
END SUB

SUB ClearSprites (NumOfSprites)
FOR S = 1 TO NumOfSprites
 PSET (Sprites(S).X, Sprites(S).Y), 0
NEXT S

END SUB

SUB MoveSprites (X, Y, NumOfSprites)
FOR S = 1 TO NumOfSprites
 SELECT CASE Sprites(S).Mode
  CASE 1
   Direction = RND * 2
   IF Direction = 0 THEN
    IF Sprites(S).X < X THEN
     Sprites(S).X = Sprites(S).X - 1
    ELSE
     Sprites(S).X = Sprites(S).X + 1
    END IF
   ELSE
    IF Sprites(S).Y < Y THEN
     Sprites(S).Y = Sprites(S).Y - 1
    ELSE
     Sprites(S).Y = Sprites(S).Y + 1
    END IF
   END IF
  CASE 2
   DistanceX = ABS(Sprites(S).X - X)
   DistanceY = ABS(Sprites(S).Y - Y)
   Direction = RND * 4
   IF DistanceX > DistanceY THEN
    Direction = Direction + 1
   ELSE
    Direction = Direction - 1
   END IF
   IF Direction > 2 THEN
    IF Sprites(S).X < X THEN
     Sprites(S).X = Sprites(S).X + 1
    ELSE
     Sprites(S).X = Sprites(S).X - 1
    END IF
   ELSE
    IF Sprites(S).Y < Y THEN
     Sprites(S).Y = Sprites(S).Y + 1
    ELSE
     Sprites(S).Y = Sprites(S).Y - 1
    END IF
   END IF
  CASE 4
   SELECT CASE Pattern(Sprites(S).Pattern, Sprites(S).PatternDone)
    CASE 1
     Sprites(S).Y = Sprites(S).Y - 1
    CASE 2
     Sprites(S).X = Sprites(S).X - 1
    CASE 3
     Sprites(S).Y = Sprites(S).Y + 1
    CASE 4
     Sprites(S).X = Sprites(S).X + 1
   END SELECT
   Sprites(S).PatternDone = Sprites(S).PatternDone + 1
   IF Sprites(S).PatternDone = 101 THEN Sprites(S).Mode = 1
 END SELECT
NEXT S
END SUB

SUB PlaceSprites (NumOfSprites)
FOR S = 1 TO NumOfSprites
 PSET (Sprites(S).X, Sprites(S).Y), Sprites(S).Colour
NEXT S
END SUB

SUB SetupMouse
DEF SEG = VARSEG(Mouse(0))
FOR i = 0 TO 17
 READ r
 POKE VARPTR(Mouse(0)) + i, r
NEXT i
FOR i = 0 TO 3
 POKE VARPTR(Mouse(0)) + 1, i
 CALL absolute(c, VARPTR(Mouse(0)))   ' Run machine code
NEXT i

END SUB

SUB SetupPatterns (Patterns)
FOR P = 1 TO Patterns
 FOR i = 1 TO 100
  READ Pattern(P, i)
 NEXT i
NEXT P
END SUB

SUB SetupSprites (NumOfSprites)
FOR S = 1 TO NumOfSprites
 Sprites(S).X = RND * 640
 Sprites(S).Y = RND * 480
 Sprites(S).Mode = (RND * 3) + 1
 Sprites(S).Colour = (RND * 15) + 1
NEXT S
END SUB

