{*
 Ukazkovy program pro prulet hvezdokupou
 Reseno simulaci 3D prostoru
 Pro int21h napsal BOby (<)2006
*}

program hvezdy;

uses crt;

const COUNT=800;
      SPEED=2;

type star=record
      x,y,z:integer;{Soradnice (barva se vypocitava ze vzdalenosti)}
     end;

var stars:array[1..COUNT] of star;
    i:word;{Citac}

{* Procedury pro praci s modem $13 *}
{*    Muzete nahradit vlastnimi    *}
procedure InitGraph;assembler;
asm
 mov ax,0013h {00=funkce na zmenu modu;13h=320x200x256}
 int 10h
end;
procedure CloseGraph;assembler;
asm
 mov ax,0003h {03h=80x25x16}
 int 10h
end;
procedure setcolor(i,r,g,b:byte);
begin
 {Nastaveni barvy pres port.
  Je to rychlejsi nez pres preruseni}
 port[$3c8]:=i;
 port[$3c9]:=r;
 port[$3c9]:=g;
 port[$3c9]:=b;
end;
procedure putpixel(x,y:word;c:byte);
begin
 {Zapis barvu do obrazove pameti. Proste putpixel}
 mem[$a000:x+y*320]:=c; { $a000=Video pamet pro mod $13}
end;

procedure putpixel3d(x,y,z:integer;c:byte);
var x2d,y2d:word; {Prevede hodnoty 3d sourad. systemu na rovinu (3D->2D)}
Begin
 x2d:=(x*512) div (512+z)+320 div 2; {Osy jsou uprostred}
 y2d:=(y*320) div (512+z)+200 div 2;
 if (((x2d>0) and (x2d<320)) and ((y2d>0) and (y2d<200))) then{Okraje}
  putpixel(x2d,y2d,c);
End;

Begin
 Randomize;
 InitGraph;

 {Zavedeni palety. Od nejsvetlejsi po nejtmavejsi odstin (proto 256-t)}
 for i:=1 to 256 do
  setcolor(i,(256-i) div 4,(256-i) div 4,(256-i) div 4);

 {Naplneni pole hvezdami}
 for i:=1 to COUNT do
  begin {Tohle byla metoda zkus a zmen}
   stars[i].x:=random(320);
   stars[i].y:=random(200);
   stars[i].z:=-500+random(800);
  end;

 repeat{Hlavni cyklus}
  for i:=1 to COUNT do
   begin
    putpixel3d(stars[i].x,stars[i].y,stars[i].z,0);{Nejdriv smazeme}
    stars[i].z:=stars[i].z-SPEED;
    if (stars[i].z<-500) then
     stars[i].z:=255;
    putpixel3d(stars[i].x,stars[i].y,stars[i].z,(stars[i].z+500) div 3);{Vykreslime}
   end;
 until keypressed;
 readkey;
 CloseGraph;
End.
