[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]

    {
    Here is my unit for a screen saver - totally self contained with mouse support
    as well (Moving the mouse will reset the screensaver time delay as well, and
    placing the mouse in top right corner will blank the screen!)
    }
    unit blanker;

    interface

    const
    blank_screen     : boolean=true;            {True=blank the screen.         }
    blank_screen_now : boolean=false;           {True=blank screen immediately. }
    count            : integer = 0;             {To keep track of our calls.    }
    screen_cond      : boolean=false;           {True=screen is blanked.        }

    var
     rows,columns:byte;

    function mouseinbox(x1,y1,x2,y2,butt:word):boolean;

    implementation

    uses dos,bmouse;   { NOTE : bmouse is in MOUSE.SWG.  SWAG SUPPORT TEAM }

    var
     OldInt9       : Procedure;
     OldInt1c      : pointer;
     ExitSave      : pointer;
     r             : Registers;
     loop          : byte;
     x             : array[1..30] of byte;
     y             : array[1..30] of byte;
     xystar        : array[1..30] of char;

    {$F+}

    {****************************************************************************}
    {*                                                                          *}
    {*                            MouseinBox Procedure                          *}
    {*                                                                          *}
    {****************************************************************************}
    function mouseinbox(x1,y1,x2,y2,butt:word):boolean;
    var
     a1, b1, c : word ;
    begin
     ms_read(a1,b1,c);
     a1:=(a1 div 8) + 1;
     b1:=(b1 div 8) + 1;
     if ((a1>=x1) and (a1<=x2) and (b1>=y1) and (b1<=y2) and (c=butt)) then
        mouseinbox:=true
     else
        mouseinbox:=false;
    end;

    {****************************************************************************}
    {*                                                                          *}
    {*                       Draw the stars on video page 1                     *}
    {*                                                                          *}
    {****************************************************************************}
    Procedure stars;
    begin
     for loop:=1 to 30 do
     begin
        if ((random(80)<10) and (ord(xystar[loop])=15)) then
        begin
           xystar[loop]:=' ';
        end;
        if ((random(80)<5) and (xystar[loop]='ù')) then
        begin
           xystar[loop]:=chr(15);
        end;
        if ((random(80)<5) and (xystar[loop]='ú')) then
        begin
           xystar[loop]:='ù';
        end;
        if ((random(80)<20) and (xystar[loop]=' ') and (x[loop]=0) and
    (y[loop]=0)) then
        begin
           x[loop]:=random(rows);
           y[loop]:=random(columns);
           xystar[loop]:='ú';
        end;
     end;
     for loop:=1 to 30 do
     begin
        r.ah:=$02;
        r.bh:=$01;
        r.dh:=x[loop];
        r.dl:=y[loop];
        intr($10,r);

        r.al:=ord(xystar[loop]);
        r.ah:=$09;
        r.bl:=7;
        r.bh:=$01;
        r.cx:=01;
        intr($10,r);
        if xystar[loop]=' ' then
        begin
           x[loop]:=0;
           y[loop]:=0;
        end;
     end;
    end;

    {****************************************************************************}
    {*                                                                          *}
    {*                       Initialize the stars Procedure                     *}
    {*                                                                          *}
    {****************************************************************************}
    Procedure starsinit;
    begin
     for loop:=1 to 20 do xystar[loop]:=' ';
     stars;
    end;

    {****************************************************************************}
    {*                                                                          *}
    {*                        Check timer & blank the screen                    *}
    {*                                                                          *}
    {****************************************************************************}
    procedure blank; interrupt;
                                                {This will be called every clock}
                                                {tick by hardware interrupt $08.}
    begin
     if screen_cond then stars;
     asm cli end;
     if blank_screen then inc(count);
     if ((blank_screen_now) and (blank_screen)) then count:=180;
     if (count >= 180) then                    {Ticks till Screen is blanked.  }
                                                {Time is 18.2 TICKS/SEC, or 1092}
                                                {Per minute, so                 }
                                                {2 Mins = 2184,                 }
                                                {3 Mins = 3276,                 }
                                                {4 Mins = 4368,                 }
                                                {5 Mins = 5460,                 }
                                                {6 Mins = 6552,                 }
                                                {7 Mins = 7644,                 }
                                                {8 Mins = 8736,                 }
                                                {9 Mins = 9828,                 }
                                                {10 Mins = 10920,               }
                                                {20 Mins = 21840,               }
                                                {30 Mins = 32760, which is      }
                                                {maximum limit of Integer       }
                                                {variable used.                 }
     begin
        count       := 0;                       {Equality check and assignment  }
                                                {faster than mod.               }
        asm
        mov AX,$02                              {Turn mouse off.                }
        Int $33

        mov ah,$03                              {Turn the cursor off            }
        mov bh,$00
        int $10
        or ch,$20
        mov ah,$01
        int $10

        mov ah,$05                              {Swaps to video page 1          }
        mov al,$01
        int $10
        end;
        if not screen_cond then starsinit;
        screen_cond:=true;
     end
     else
     begin
        asm
        mov ax,$0006                            {Check for Mouse Button press.  }
        int $33
        cmp bx,0
        je @Test2
        mov count,0
     @test2:
        mov ax,$000b                            {Check for mouse movement.      }
        int $33
        cmp cx,0
        jz @test3
        mov count,0
     @test3:
        cmp dx,0
        jz @test4
        mov count,0
     @test4:
        end;
        if ((count=0) and (screen_cond)) then
        begin
           asm
           mov ah,$05                           {Restore the first video page   }
           mov al,$00;
           int $10

           mov ah,$03                           {Turn the cursor on             }
           mov bh,$00
           int $10
           and ch,$DF
           mov ah,$01
           int $10

           mov AX,$01                           {Turn mouse on                  }
           Int $33
           end;
           screen_cond:=false;
        end;
     end;
     asm
     sti
     pushf                                      {Push flags to set up for IRET. }
     call OldInt1c;                             {Call old ISR entry point.      }
     end;
    end;

    {****************************************************************************}
    {*                                                                          *}
    {*                         New Interrupt 9 Procedure                        *}
    {*                                                                          *}
    {****************************************************************************}
    Procedure NewInt9; Interrupt;
    Begin
     blank_screen_now:=false;
     if (mouseinbox(80,1,80,1,0))=true then
     asm
     mov ax,0004
     mov cx,630
     mov dx,1
     int $33
     end;
     count:=-1;                                 {Set to -1 because the blank    }
                                                {procedure will increment before}
                                                {it tests, so to get it to 0, it}
                                                {must be set to -1.             }
     asm
     pushf                                      {Push flags to set up for IRET. }
     call OldInt9;                              {Call old ISR entry point.      }
     end;
    End;

    {****************************************************************************}
    {*                                                                          *}
    {*                  Reset everything at the end of the unit                 *}
    {*                                                                          *}
    {****************************************************************************}
    procedure ClockExitProc;
                                                {This procedure is VERY         }
                                                {important as you have hooked an}
                                                {interrupt and therefore if this}
                                                {is omitted when the unit is    }
                                                {terminated your system will    }
                                                {crash in an unpredictable and  }
                                                {possibly damaging way.         }
    begin
     ExitProc := ExitSave;
     SetIntVec($1c,OldInt1c);                   {This "unhooks" the timer vector}
     SetIntVec($09, Addr(OldInt9));             {This restores normal keyboard  }
                                                {routines.                      }

    end;
    {$F-}

    {****************************************************************************}
    {*                                                                          *}
    {*                        Unit Initializing procedure                       *}
    {*                                                                          *}
    {****************************************************************************}
    procedure Initialise;
    var
     mode : byte absolute $40:$49;
    begin
     asm
     mov ah,$05                                 {Swap to video page 1, clear the}
     mov al,$01                                 {screen by scrolling it, then   }
     int $10                                    {return to video page 0.        }

     mov ah,$06
     mov al,$00
     mov bx,$00
     int $10

     mov ah,$05                                 {Restore the first video page   }
     mov al,$00
     int $10
     end;
     GetIntVec($09, Addr(OldInt9));             {These two lines activate the   }
     SetIntVec($09, Addr(NewInt9));             {new keyboard routine handler.  }
     GetIntVec($1c,OldInt1c);                   {Get old timer vector & save it.}
     ExitSave := ExitProc;                      {Save old exit procedure.       }
     ExitProc := @ClockExitProc;                {Setup a new exit procedure.    }
     SetIntVec($1c,@blank);                     {Hook the timer vector to the   }
                                                {new procedure.                 }
    end;

    {****************************************************************************}
    {*                                                                          *}
    {*                           Main program starts here                       *}
    {*                                                                          *}
    {****************************************************************************}
    begin
     Initialise;
     Rows:=(mem[$0040:$0084]) + 1;              {Find the size from memory      }
     Columns:=mem[$0040:$004a];
     if rows   =0 then rows   :=25;             {If it could not find anything  }
     if columns=0 then columns:=80;             {assume 25*80 mode.             }
    end.

[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]