[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]