{$D+,E+,G+,N+,X+,Y+} (*) Simple SnowFall (*) Program SnowFall; Uses Dos,MGUnit; Const BackGrndColor = 0; LightSnow = 255; DarkSnow = 254; Type tScreen = Array [0..63999] Of Byte; pScreen = ^tScreen; vP=array[0..255,0..2] of byte; Var PCX_File:File of char; Manufacturer:byte; Version:shortint; encoding:shortint; x,y, width,height, horz_res,vert_res:word; vScreen:pScreen; vPal:^vP; gd,gm:integer; Mmemory:Pointer; (*) FOR PCX (*) i,c : Word; vScr,SB : pScreen; h,m,s,s1,hn,mn,sn,s1n:word; DF : Boolean; Cnt : Byte; frames:word; sec:double; (*) *------------------* Procedure And Functions *-----------------------* (*) Procedure Read_Header; var c:char; ex:boolean; begin ex:=true; Read(PCX_File,c); Manufacturer:=ord(c); if Manufacturer<>10 then begin write('Error: wrong file.'); Ex:=False; end; Read(PCX_File,c); version:=ord(c); case version of 0:writeln('Ver. 2.5 PaintBrush'); 2:writeln('Ver. 2.8 Pallette'); 3:writeln('Ver. 2.8 Without Pallette'); 5:writeln('Ver. 3.0 or greater'); else begin writeln('Wrong version.'); ex:=false; end; end; read(PCX_File,c); encoding:=ord(c); if encoding=1 then writeln('RLE Encoding') else begin writeln('Wrong encoding'); Ex:=false; end; read(PCX_File,c); x:=ord(c); read(PCX_File,c); y:=ord(c); writeln('The coordinates of the upper left corner is (',x,';',y,').'); read(PCX_File,c); width:=ord(c); read(PCX_File,c); height:=ord(c); writeln('Image Height Is ',height,' and width ',width,'.'); read(PCX_File,c); horz_res:=ord(c); read(PCX_File,c); vert_res:=ord(c); writeln('Vertical rezolution is ',vert_res,' and horizontal is ',horz_res,'.'); end; Procedure Read_Main; var count,num,color,n:word; c:char; begin seek(PCX_File,128); count:=0; While (count<=64000) do begin Read(PCX_File,c); n:=ord(c); if (n>=192) and (N<=255) then begin num:=n-192; read(PCX_File,c); color:=ord(c); for n:=0 to num-1 do vScreen^[count+n]:=color; inc(count,num); end else begin vScreen^[count]:=n; inc(count); end; end; end; Procedure Pal_Read; var count:word;c:char; begin seek(PCX_File,FileSize(PCX_File)-256*3); count:=0; while (count<256) do begin Read(PCX_File,c); vPal^[count,0]:=ord(c) shr 2; Read(PCX_File,c); vPal^[count,1]:=ord(c) shr 2; Read(PCX_File,c); vPal^[count,2]:=ord(c) shr 2; inc(count); end; end; Function CalcTime(a,b,c,d,a1,b1,c1,d1:word):double; var dh,dm,ds,ds1:integer; begin dh:=a1-a; dm:=b1-b; ds:=c1-c; ds1:=d1-d; if ds1<0 then begin inc(ds1,60); dec(ds); end; if ds<0 then begin inc(ds,60); dec(dm); end; if dm<0 then begin inc(dm,60); dec(dh); end; CalcTime:=((dh*60+dm)*60+ds)+(ds1/60); end; (*) Set Needed Mode (*) Procedure SetMode(Mode : Byte); Assembler; asm Mov AH,0 Mov AL,[Mode] Int 10h end; (*) Sets Red, Green and Blue Components Of The Current Color (*) Procedure SetRGB(C, R, G, B : Byte); Assembler; asm Mov DX, 3C8h Mov AL, [C] Out DX, AL Inc DX Mov AL, [R] Out DX, AL Mov AL, [G] Out DX, AL Mov AL, [B] Out DX, AL end; (*) Clears The Screen In VGA 320x200x256 (*) Procedure Cls(Color : Byte); Assembler; Asm Push DS Push $A000 Pop ES Mov AL, [Color] Mov AH, AL Mov CX, 64000/2 Rep StoSw Pop DS End; (*) Approximates The Number For Pallete (*) Function Color(I : Byte; Seed : Word) : Byte; Begin Color := Round(63*Abs(Sin(I*Pi/Seed))) End; (*) Copies The Buffer To The Screen (*) Procedure Flip; Assembler; Asm Push DS Les DI, vScr Mov DS, SEGA000 Xor SI, SI Mov AX, 0A000h Mov ES, AX Xor DI, DI Mov CX, 16000 Db $66 Rep MovSw Pop DS End; (*) Wait For The Vertical RetRace (*) Procedure WaitRetRace; Begin While Port[$3da] And $08 = 0 Do end; (*) Main Procedure Of Falling Snow (*) Procedure Fall1; Var C, D : Integer; l,r, dl, dn, dr : Boolean; Begin For I := 63999-320 DownTo 0 Do Begin If (vScr^[I]>0) Then Begin c:=vScr^[i]; vScr^[i]:=0; dl:=vScr^[i+319]=0; dn:=vScr^[i+320]=0; dr:=vScr^[i+321]=0; if not dl and not dn and not dr then d:=0 else if dl and dn and dr then begin d:=random(4); case d of 0: d:=319; 1: d:=320; 2: d:=321; 3: d:=1; 4: d:=-1; end; end else if dl and dn and not dr then begin d:=random(3); case d of 0: d:=319; 1: d:=320; 2: d:=1; 3: d:=-1; end; end else if dl and not dn and dr then begin d:=random(3); case d of 0: d:=319; 1: d:=321; 2: d:=1; 3: d:=-1; end; end else if not dl and dn and dr then begin d:=random(3); case d of 0: d:=320; 1: d:=321; 2: d:=1; 3: d:=-1; end; end else if dl and not dn and not dr then d:=319 else if not dl and not dn and dr then d:=321 else if not dl and dn and not dr then d:=320; {if (ParamCount<2) or ((ParamCount=1) and (ParamStr(1)='ACID')) then} > Вот от сюда закоментарить if (vScr^[i+d]>0) and (vScr^[i+d]<250) then begin vScr^[i]:=c; continue; end; > и до сюда. case c of DarkSnow : if DF then if (d=0) or (i+d>63999-320) then vScr^[i]:=LightSnow else vScr^[i+d]:=c else vScr^[i]:=c; LightSnow: if d=0 then vScr^[i]:=LightSnow else vScr^[i+d]:=c else vScr^[i]:=c; end; end; End End; Procedure ShowPicture; var i:Word; begin for i:=0 to 64000 do If vScreen^[i]>0 then vScr^[i]:=vScreen^[i]; end; (*) *-------------------------* Main Body *------------------------------* (*) Begin new(vScreen); FillChar(vScreen^,64000,0); new(vPal); FillChar(vPal^,256*3,0); assign(PCX_File,'hny1.pcx'); reset(PCX_File); Read_Main; Pal_Read; Close(PCX_File); SetMode($13); for i:=0 to 255 do SetRGB(i,vPal^[i,0],vPal^[i,1],vPal^[i,2]); Dispose(vPal); (*) Prepares The Buffer (*) New(vScr); FillChar(vScr^,64000,0); SegA000 := Seg(vScr^); Randomize; Cls(BackGrndColor); (*) Prepares Pallete (*) SetRGB(254,Color(110,512),Color(110,512),Color(110,512)); SetRGB(255,Color(195,512),Color(195,512),Color(195,512)); ShowPicture; GetTime(h,m,s,s1); frames:=0; (*) Main Falling (*) cnt:=0; Repeat DF:=False; if cnt=0 then inc(cnt) else begin Df:=True; Cnt:=0; end; (*) Puts Leading Flakes (*) For I := 0 To 319 Do Begin C := Random(170); Case c Of 1: vScr^[I] := LightSnow; 2: vScr^[I] := DarkSnow; End End; Fall1; Flip; inc(frames); Until Port[$60] = 1; GetTime(hn,mn,sn,s1n);sec:=CalcTime(h,m,s,s1,hn,mn,sn,s1n); (*) ShutDown The Buffer And Returns Back To The Text Screen (*) Dispose(vScr);Dispose(vScreen);SetMode($3); writeln(frames/sec:2:5,' fps'); (*) GodBye (*) Writeln('Coded By Mike Korablin Jr. (MMK)',#10#13, 'Fido : 2:5025/2000.7@FidoNet.Org AKA 2:5025/40.48@FidoNet.Org'#10#13, 'E-Mail : mmk@archiv.vrn.ru'); (*) The End :'''( (*) End.