[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]
{
> I've seen few times an effect which fades the DOS screen before demo or
> something, how's it done?
> And how can I freeze DOS screen to memory so that I can write it again
> after demo or game has ended?
> And I want to know other that kind of 'effects' (or what ever they are
> called..)..
Here's some bits & pieces from a VGA library I'm writing... note that the fades
only work on VGA....
}
{$G+} {Yes, it does unfortunately use 286 opcodes to eliminate snow. Sorry.}
Program VGA_Stuff;
Uses Crt;
Type
CharAttr=Record {How a character looks in screen memory}
Ch:Char; {The character to display}
Attr:Byte; {The foreground+(background*16). bright backgrounds=flashing}
End;
TextScreen=Array[1..25,1..80] Of CharAttr;
{This represents 1 screen. Note the Y,X order}
DAC_Trio=Record
Red,Green,Blue:Byte;
End; {One pallette register. Note that it's always in that order}
Var
Physical_TScreen:TextScreen Absolute $B800:0; {The real screen}
Starting_TScreen:TextScreen; {Another screen, in memory}
Procedure WaitForRetrace;
{Waits for vertical retrace. This is to assure the same speed across all PCs,
and to eliminate interference. Waits at most 1/70th of a second.}
Begin
Asm
MOV DX,$3DA;
@Wait1:
IN AL,DX
TEST AL,8 {retrace hapening?}
JNZ @Wait1 {Yep, wait for it to end}
@Wait2:
IN AL,DX
TEST AL,8 {Retrace happening?}
JZ @Wait2 {nope, wait to finish}
End
End;
Procedure SetPal(Var P; Start:Byte; Count:Word);
{P is an array of DAC_Trio's, set up with the colours we want.
The start is the first colour to set, the count is how many. Note that there's
only 256 registers, so count should be no more than 256. Also, they will wrap
round; starting at 128 & count=256 will set the register 128 to the first trio,
and so forth, till the last trio at 127.}
Begin
WaitForRetrace; {To eliminate snow.}
Asm
MOV DX,$3C8
MOV AL,Start
OUT DX,AL
INC DX
MOV BX,DS
LDS SI,P
MOV CX,Count
ADD CX,Count
ADD CX,Count
REP OUTSB
MOV DS,BX
End;
End;
Procedure GetPal(Var P; Start:Byte; Count:Word);
{Gets a number of pallette registers. P should be an array of DAC_Trio's, start
should be the first one to get, and count should be the number of registers to
get.}Begin
Asm
MOV DX,$3C7
MOV AL,Start
OUT DX,AL
INC DX
INC DX
MOV BX,ES
LES DI,P
MOV CX,Count
ADD CX,Count
ADD CX,Count
REP INSB
MOV ES,BX
End;
End;
Procedure Fade_Out;
{Gets the current pallette & fades it out.}
Var
Pal:Array[0..255] Of Dac_Trio;
Loop1,Loop2:Byte;
Begin
GetPal(Pal,0,255);
For Loop1:=1 To 64 Do
Begin
For Loop2:=0 To 255 Do
Begin
If Pal[Loop2].Red>0 Then
Dec(Pal[Loop2].Red);
If Pal[Loop2].Green>0 Then
Dec(Pal[Loop2].Green);
If Pal[Loop2].Blue>0 Then
Dec(Pal[Loop2].Blue);
End;
WaitForRetrace;
{Put WaitForRetrace; here to slow it down to suit. Each one slows it down
one screenframe}
SetPal(Pal,0,255);
End;
End;
Procedure Fade_In(Var P);
{Fades the screen in from black to whatever colours are set in P. P should be
an array of DAC_Trio's}Var
NewPal:Array[0..255] Of Dac_Trio Absolute P;
Pal:Array[0..255] Of Dac_Trio;
Loop1,Loop2:Byte;
Begin
FillChar(Pal,SizeOf(Pal),0); {Set to black}
SetPal(Pal,0,256);
For Loop1:=63 DownTo 0 Do
Begin
For Loop2:=0 To 255 Do
Begin
If NewPal[Loop2].Red>Loop1 Then
Inc(Pal[Loop2].Red);
If NewPal[Loop2].Green>Loop1 Then
Inc(Pal[Loop2].Green);
If NewPal[Loop2].Blue>Loop1 Then
Inc(Pal[Loop2].Blue);
End;
{Put WaitForRetrace; here to slow it down to suit. Each one slows it down
one screenframe}
WaitForRetrace;
SetPal(Pal,0,255);
End;
End;
Var Loop:Word;
Orig_Pal:Array[0..255] Of Dac_Trio;
Begin
Starting_TScreen:=Physical_TScreen; {Make a copy of the origonal screen}
GetPal(Orig_Pal,0,256); {Make a copy of origonal pallette}
For Loop:=1 To 4000 Do
Mem[$B800:Loop]:=Random(127); {Fill screen with garbage!}
Fade_Out;
Physical_TScreen:=Starting_TScreen; {Restore origonal screen}
Fade_In(Orig_Pal); {Fade in to origonal colours}
End.
[Back to SCREEN SWAG index] [Back to Main SWAG index] [Original]