Program Dimension3;
Uses
  mygraph,
  Types,
  Inertia,
  mode13h,
  pcx,
  Crt;


Var
  View : ViewObject;   { The View System }
  Obj  : VectorObject; { A vector object }
  uk:pointer;
  pal:palette;
  vadr,vel,vadr2: word;
  timer,xpos,ypos,zpos,timer2:integer;
  rotx,roty,rotz:integer;
  decrem:word;
  stop:boolean;


Procedure Flip2; Assembler;
Asm
  Push  ds
  Push  es
  Les   di,virtualpage
  Lds   si,uk
  Mov   cx,64000/4
  db 66h; Rep   Movsw
  Pop   es
  Pop   ds
End;

procedure ending;
begin
  FreeView(View);         { Free the view's allocated memory }
  FreeVectorObject(Obj);  { free the vector object's allocated memory }
  FreeIntensityTable;     { free the intensity table from memory }
  FreeTexture(0);         { Free the phong map }
  setmode(3);
  halt;
end;

procedure WaitRetrace; assembler;
label
  l1, l2;
asm
    mov dx,3DAh
l1:
    in al,dx
    and al,08h
    jnz l1
l2:
    in al,dx
    and al,08h
    jz  l2
end;

Procedure SetPalette2;
var I:integer;
begin
 for i:= 0 to 255 do SetPal(i,ActivePal[i,1],ActivePal[i,2],ActivePal[i,3]);
end;

procedure fadein;
var a,b:integer;
begin
for b:=1 to 64 do
 begin
   for a:= 0 to 255 do
    begin
     If StorePal[a,1] > ActivePal[a,1] then
      activepal[a,1]:=ActivePal[a,1]+1;
     If StorePal[a,2] > ActivePal[a,2] then
      activepal[a,2]:=ActivePal[a,2]+1;
     If StorePal[a,3] > ActivePal[a,3] then
      activepal[a,3]:=ActivePal[a,3]+1;
    end;
  SetPalette2;
  delay(33);
 end;
end;

procedure fade2(dir:byte);
var a:integer;
begin
if dir=1 then
 begin
   for a:= 0 to 255 do
    begin
     If StorePal[a,1] > ActivePal[a,1] then
      activepal[a,1]:=ActivePal[a,1]+1;
     If StorePal[a,2] > ActivePal[a,2] then
      activepal[a,2]:=ActivePal[a,2]+1;
     If StorePal[a,3] > ActivePal[a,3] then
      activepal[a,3]:=ActivePal[a,3]+1;
    end;
  SetPalette2;
 end;
if dir=2 then
 begin
  for a:=0 to 255 do
   begin
    if activepal[a,1]>0 then
     activepal[a,1]:=ActivePal[a,1]-1;
    if activepal[a,2]>0 then
     activepal[a,2]:=ActivePal[a,2]-1;
    if activepal[a,3]>0 then
     activepal[a,3]:=ActivePal[a,3]-1;
   end;
   setpalette2;
  end;
end;


procedure fadeout;
var a,b:integer;
begin
for b:=1 to 64 do
 begin
  for a:=0 to 255 do
   begin
    if activepal[a,1]>0 then
     activepal[a,1]:=ActivePal[a,1]-1;
    if activepal[a,2]>0 then
     activepal[a,2]:=ActivePal[a,2]-1;
    if activepal[a,3]>0 then
     activepal[a,3]:=ActivePal[a,3]-1;
   end;
   setpalette2;
   DELAY(33);
  end;
end;

{==================================================== }
procedure rotator(poc:integer;dir:boolean;move:byte);
begin
rotx:=random(5);
roty:=random(10);
for timer:=1 to poc do
  begin
    flip2;
    SetAbsoluteLocation(Obj, xpos, ypos, 1200);
    if move=1 then inc(ypos,2);
    if move=2 then dec(ypos,2);
    decrem:=1;
    if dir=true then
     begin
      inc(rotz,decrem);
     end
     else
      begin
       dec(rotz,decrem);
      end;
    SetDeltaRotation(Obj, rotx,roty,rotz);
    AddtoRenderList(View, Obj);
    Render(View, VirtualPage);
    waitretrace;
    delay(10);
    Flip;
    if port[$60]=$01 then stop:=true;
    if stop then ending;
  end;
end;
{==================================================== }

{==================================================== }
procedure rotator2(poc:integer;dir:boolean;move:byte);
begin
rotx:=random(5);
roty:=random(5);
for timer:=1 to poc do
  begin
    SetAbsoluteLocation(Obj, xpos, ypos, zpos);
    if move=1 then inc(zpos,2);
    if move=2 then dec(zpos,2);
    decrem:=1;
    if dir=true then inc(rotz,decrem)
     else
      begin
       dec(rotz,decrem);
      end;
    SetDeltaRotation(Obj, rotx,roty,rotz);
    AddtoRenderList(View, Obj);
    RotateLightSource(View, 0, 2, 0, 2); { rotate the first light source }
    RotateLightSource(View, 1, 2, 2, 4); { rotate the first light source }
    Render(View, VirtualPage);
    waitretrace;
    delay(10);
    Flip;
    if port[$60]=$01 then stop:=true;
    if stop then ending;
  end;
end;
{==================================================== }

 Begin
If (LoadPalette('NEW-2.PAL', 0) <> I_OK)       { load the palette }
  Then Begin
    Writeln('Error loading Palette.');
    Halt(0);
  End;


If (LoadPCXFile('new-2.pcx',uk,pal,vel,0) <> 0) then
      Begin
      Writeln('Error loading picture');
      Halt(1);
      end;

If (LoadIntensityTable('NEW-2.IT', 0) <> I_OK) { load intensity table }
    Then Begin
      Writeln('Error loading Intensity table.');
      Halt(0);
    End;
  If (LoadGVO(Obj, 'TORUS.GVO', 0) <> I_OK)         { load the vector object }
    Then Begin
      Writeln('Error loading TORUS object.');
      Halt(0);
    End;

  If (InitView(View, 1000) <> I_OK) { init the view }
    Then Begin
      Writeln('Error Initializing view.');
      Halt(0);
    End;
  Setmode($13);                { Set graphics mode }
  SetPalette(GlobalPalette);   { Set the palette }

  xpos:=0; ypos:=600;
  SetAbsoluteLocation(Obj, xpos, ypos, Obj.Radius * 5); { Set the object's location }
  PushLightSource(View, 0, 0, -1);  { Add a light source }

  SetSurface(Obj, smooth);
  SetShading(Obj, gouraud);
  SetBaseColor(Obj,60);      { set the object's color }

  getpalette;
  nullpalette;
  setpalette2;

  flip2;
  flip;
  fadein;

{========================rotate torus part===========================}
  randomize;
  for timer2:=1 to 3 do
  begin
    rotator(30,true,2);
    rotator(30,false,2);
    rotator(20,false,2);
    rotator(20,true,2);
  end;
  randomize;
  ypos:=0;
  rotx:=0;roty:=0;rotz:=0;
  for timer2:=1 to 5 do
   begin
    rotator(35,true,0);
    rotator(35,false,0);
    rotator(15,true,0);
    rotator(50,false,0);
    rotator(35,true,0);
   end;
  randomize;
  for timer2:=1 to 3 do
  begin
    rotator(30,true,2);
    rotator(30,false,2);
    rotator(20,false,2);
    rotator(20,true,2);
  end;
{=END======================rotate torus part===========================}

  FreeView(View);         { Free the view's allocated memory }
  FreeVectorObject(Obj);  { free the vector object's allocated memory }
  FreeIntensityTable;     { free the intensity table from memory }
  fadeout;

{----------------------NEXT PART------------------------}

 If (LoadIntensityTable('COPPRENV.IT', 0) <> I_OK)
 Then Begin
      Writeln('Error loading Intensity table.');
      Halt(0);
    End;

 If (LoadPCXTexture(1, 'COPPRENV.PCX', 0) <> I_OK)
    Then Begin
      Writeln('Error loading texture.');
      Halt(0);
    End;

 GetTexturePalette(1);


If (LoadGVO(Obj, 'ROCK1.GVO', 0) <> I_OK)         { load the vector object }
    Then Begin
      Writeln('Error loading object.');
      Halt(0);
    End;


If (InitView(View, 500) <> I_OK)
    Then Begin
      Writeln('Error Initializing view.');
      Halt(0);
    End;



  SetMode($13);              { Set graphics mode }
  SetPalette(GlobalPalette); { Set the palette }

  getpalette;
  nullpalette;
  setpalette2;



  SetSurface(Obj, texture);   { set texture surface }
  SetShading(Obj, gouraud);   { set gouraud rendering for object }
  SetObjectTexture(Obj,1);

  SetAbsoluteLocation(Obj, 0, 0, 230); { Set the object's location }


  PushLightSource(View, 0, 0, -1);  { Add a light source }
  PushLightSource(View, 1, 0, 0);   { Add another light source }

  xpos:=0;ypos:=0;
  rotx:=4;roty:=6;rotz:=5;
  zpos:=230;

{========================rotate rock part===========================}
  for timer2:=1 to 64  do
    begin
     SetAbsoluteLocation(Obj, 0, 0, zpos); { Set the object's location }
     SetDeltaRotation(Obj, rotx, roty, rotz);
     AddtoRenderList(View, Obj);
     Render(View, VirtualPage);
     fade2(1);
     RotateLightSource(View, 0, 2, 4, 2); { rotate the first light source }
     RotateLightSource(View, 1, 1, 2, 2); { rotate the first light source }
     waitretrace;
     Flip;
     if port[$60]=$01 then break;
    end;

    rotator2(10,true,1);
    rotator2(10,false,1);
    rotator2(10,false,1);
    rotator2(10,true,1);

  for timer2:=1 to 4 do
   begin
    rotator2(40,true,1);
    rotator2(40,false,0);
    rotator2(20,true,1);
    rotator2(60,false,2);
    rotator2(40,true,0);
   end;

    rotator2(10,true,2);
    rotator2(10,false,2);
    rotator2(10,false,2);
    rotator2(10,true,2);

   for timer2:=1 to 64  do
    begin
     SetAbsoluteLocation(Obj, 0, 0, zpos); { Set the object's location }
     SetDeltaRotation(Obj, rotx, roty, rotz);
     AddtoRenderList(View, Obj);
     Render(View, VirtualPage);
     fade2(2);
     RotateLightSource(View, 0, 2, 4, 2); { rotate the first light source }
     RotateLightSource(View, 1, 1, 2, 2); { rotate the first light source }
     waitretrace;
     Flip;
     if port[$60]=$01 then break;
    end;
{=====END================rotate rock part===========================}

  FreeView(View);         { Free the view's allocated memory }
  FreeVectorObject(Obj);  { free the vector object's allocated memory }
  FreeIntensityTable;     { free the intensity table from memory }

  FreeTexture(0);         { Free the phong map }

  SetMode($03);           { return to text mode }
End.
