Comment
==========================================================

WORM.INC Copyright 1991 by Marc Perkel

This is a sample of an external screen blanker for MarxMenu. It is
similar to the worm blankers on Novell file servers.

To use this program add the line INCLUDE 'WORM.INC' in your menu.

When MarxMenu decides to blank the screen it calls BlankScreenProgram.
When MarxMenu decides it's ready to unblank the screen it sets UnBlank
to true.

Thus commands like UseNovPassword, LockWord, and BlankTime will work
with your screen blanker.

When using and external screen blanker allong with IdleProgram, MarxMenu
will shut off calls to your IdleProgram when the BlankScreenProgram
starts. Thus, you will have to call your IdleProgram routines fron your
BlankScreenProgram if you want them to run.

==========================================================
EndComment

Var
  WormData
  WormColor
  WormSpeed
  WormHook
  WormLen = 4
  TargetWormLen
  Direction
  Duration
  WSeg

Qualifier X Y Col

;----- This tells MarxMenu to RunWorm when it is time to blank the screen

BlankScreenProgram = Loc RunWorm
WormHook = Loc TapeBackup

Var T1 T2

T1[1,1] = 2
T1[1,2] = 0
T1[2,1] = 2
T1[2,2] = -1
T1[3,1] = 1
T1[3,2] = -1
T1[4,1] = 0
T1[4,2] = -1
T1[5,1] = -1
T1[5,2] = -1
T1[6,1] = -2
T1[6,2] = -1
T1[7,1] = -2
T1[7,2] = 0
T1[8,1] = -2
T1[8,2] = 1
T1[9,1] = -1
T1[9,2] = 1
T1[10,1] = 0
T1[10,2] = 1
T1[11,1] = 1
T1[11,2] = 1
T1[12,1] = 2
T1[12,2] = 1

T2[10] = 0
T2[5] = 1
T2[4] = 2
T2[3] = 3
T2[2] = 4
T2[1] = 5
T2[6] = 6
T2[11] = 7
T2[12] = 8
T2[13] = 9
T2[14] = 10
T2[15] = 11

if ColorScreen
   Loop 30
      WSeg[LoopIndex] = 'ÛÛ'
   EndLoop
else
   WSeg = Set ['ÛÛ','²²','±±','°°']
endif

TargetWormLen = WormLen

;----- End of Initialization

Procedure StartWorm
   NewWormSpeed
   Loop WormLen
      WormData[LoopIndex].X = LoopIndex * 2 + 40
      WormData[LoopIndex].Y = 12
      WormData[LoopIndex].Col = NextWormColor
   EndLoop
EndProc


Procedure MoveWorm
var DeltaX DeltaY WormSeg
   ResetDuration
   while Duration > 0
      WormSeg = WormLen
      if TargetWormLen > WormLen
         WormLen = WormLen + 1
         WormSeg = WormSeg + 1
      else
         GotoXY(WormData[WormSeg].X,WormData[WormSeg].Y)
         Write '  '
         if TargetWormLen < WormLen
            WormLen = WormLen - 1
            WormSeg = WormSeg - 1
            GotoXY(WormData[WormSeg].X,WormData[WormSeg].Y)
            Write '  '
         endif
      endif

      while WormSeg > 1
         WormData[WormSeg] = WormData[WormSeg - 1]
         GotoXY(WormData[WormSeg].X,WormData[WormSeg].Y)
         TextColor WormData[WormSeg].Col Black
         Write WSeg[WormSeg]
         WormSeg = WormSeg - 1
      endwhile

      DeltaX = T1[Direction + 1,1]
      DeltaY = T1[Direction + 1,2]
      if (WormData[1].X + DeltaX < 1) or (WormData[1].X + DeltaX + 1 >= ScreenWidth)
         DeltaX = DeltaX * -1
         NewWormSpeed
      endif
      if (WormData[1].Y + DeltaY < 1) or (WormData[1].Y + DeltaY > ScreenHeight)
         DeltaY = DeltaY * -1
         NewWormSpeed
      endif
      Direction = T2[DeltaY * 5 + DeltaX + 8]
      WormData[1].X = WormData[1].X + DeltaX
      WormData[1].Y = WormData[1].Y + DeltaY
      WormData[1].Col = NextWormColor

      GotoXY(WormData[1].X,WormData[1].Y)
      TextColor WormData[1].Col Black
      Write WSeg[1]

      if UnBlank then Return
      Wait WormSpeed
      Duration = Duration - 1
   EndWhile
EndProc


Procedure NextWormColor
   WormColor = WormColor + 1 mod 7
   if ColorScreen
      Return WormColor + 9
   else
      Return 7
   endif
EndProc


Procedure NewWormSpeed
   WormSpeed = Random mod 20 + 7
   if ScrollLock then WormSpeed = WormSpeed / 2
   if ColorScreen then TargetWormLen = 30 / WormSpeed + 3
   Duration = 0
EndProc


Procedure ResetDuration
   Duration = Random mod 3 + WormLen - 1
EndProc


Procedure NewVector
var A
   A = Random mod 188
   if A = 0 then Return 6
   if A <= 2 then Return 5
   if A <= 4 then Return 7
   if A <= 8 then Return 4
   if A <= 12 then Return 8
   if A <= 20 then Return 3
   if A <= 28 then Return 9
   if A <= 44 then Return 2
   if A <= 60 then Return 10
   if A <= 92 then Return 1
   if A <= 124 then Return 11
   Return 0
EndProc


Procedure RunWorm
   StartWorm
   Direction = 6
   while not UnBlank
      MoveWorm
      Direction = Direction + NewVector mod 12

      ;--- this runs tape backup at 11:30 pm

      Run WormHook

   EndWhile
EndProc


;----- This is an example of how to run a tape at 11:30 pm

Procedure TapeBackup
var BackupTime

   ;--- Must be my server

   if NovDefaultServer <> 'TYME' then Return

   ;--- Must be Station with Tape Drive

   if NovStationAddress <> '250:329C5' then Return

   ;--- Must be on WeekDays

   if (DayOfWeek = 0) or (DayOfWeek = 6) then Return

   ;--- Run it at BackupTime

   BackupTime = TimeOf('11:30pm')
   if (Now < BackupTime) or (Now > (BackupTime + 30)) then Return

   ;--- Runs TAPE.MNU

   Bat 'MARX TAPE'
   exitmenu

EndProc
