home *** CD-ROM | disk | FTP | other *** search
/ PC Underground / UNDERGROUND.ISO / doom / source / dungeon.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1995-02-05  |  9.9 KB  |  515 lines

  1. {----------------------------------------------------------------------------
  2.   Vector DUNGEON
  3.   Copyright (c) 1994,95 by J.E. Hoffmann
  4.   All rights reserved
  5.  ----------------------------------------------------------------------------}
  6. {$A+,B-,D-,E-,F-,G+,I-,L-,N-,O-,P-,Q-,R-,S-,T-,V-,X+,Y-}
  7. {$M $4000,$60000,$60000}
  8. program __DUNGEON__;
  9.  
  10.  
  11.  
  12. uses Crt,_Keyb,_Math,_Matrix,_VGApas,_Frame;
  13.  
  14.  
  15.  
  16. {$I FX_DOOM.PAH}
  17.  
  18.  
  19. const
  20.   zClipPlane = $5*$200;
  21.  
  22.  
  23.  
  24. procedure GetCrossing(A,B :T3D; var C :T3D);
  25. var
  26.   L1,L2 :LongInt;
  27. begin
  28.   L1 :=zClipPlane-A[2];
  29.   L2 := B[2]-A[2];
  30.   if L2= 0 then begin
  31.     C := A;
  32.     C[2] :=$5*$200;
  33.     exit;
  34.   end;
  35.   C[0] := FixDiv(FixMul(L1,B[0]-A[0]),L2) +A[0];
  36.   C[1] := FixDiv(FixMul(L1,B[1]-A[1]),L2) +A[1];
  37.   C[2] := zClipPlane;
  38. end;
  39.  
  40.  
  41.  
  42. var
  43.   OldExit :Pointer;
  44.  
  45. procedure NewExit; far;
  46. begin
  47.   ExitProc := OldExit;
  48.   DoneFrameHandler;
  49.   Done13h;
  50. end;
  51.  
  52.  
  53.  
  54. type
  55.   TProject = RECORD
  56.     P  :T2D;
  57.     Visible :Boolean;
  58.     _res :array[1..3] of Byte;
  59.   end;
  60.  
  61.   PPointList = ^TPointList;
  62.   TPointList = array[0..2447] of T3D;
  63.  
  64.   PProjectList = ^TProjectList;
  65.   TProjectList = array[0..2447] of TProject;
  66.  
  67.   PMappingList = ^TMappingList;
  68.   TMappingList = array[0..2447] of T2D;
  69.  
  70.   PColorList = ^TColorList;
  71.   TColorList = array[0..2447] of Byte;
  72.  
  73.  
  74.   PFace = ^TFace;
  75.   TFace = RECORD
  76.     Count   :Integer;
  77.     texture :Integer;
  78.     List    :array[0..255] of Word;
  79.   end;
  80.  
  81.   PFaceList = ^TFaceList;
  82.   TFaceList = array[0..2447] of PFace;
  83.  
  84.  
  85.   PZEntry = ^TZEntry;
  86.   TZEntry = RECORD
  87.     z  :LongInt;
  88.     P  :PFace;
  89.   end;
  90.  
  91.   PZList = ^TZList;
  92.   TZList = array[0..2047] of TZEntry;
  93.  
  94.  
  95. const
  96.   PointDef :array[0..3] of T2D = (
  97.     (0,0),
  98.     (319,0),
  99.     (319,199),
  100.     (0,199)
  101.   );
  102.  
  103.  
  104. var
  105.   M         :TMatrix;
  106.   rx,ry,rz  :Integer;
  107.   Textures  :array[0..2] of Pointer;
  108.   DAC       :TDACBlock;
  109.   t      :T3D;
  110.  
  111.   PCount :Integer;
  112.   VL     :PPointList;
  113.   TL     :PPointList;
  114.   PL     :PProjectList;
  115.   FCount :Integer;
  116.   FL     :PFaceList;
  117.   ZL     :PZList;
  118.  
  119.  
  120. procedure CxyTexturedPoly(P,T :Pointer; Count :Word; Texture :Pointer); far; external;
  121. {$L CXYTPOLY.OBJ}
  122.  
  123.  
  124. procedure DrawFace(F :PFace);
  125. var
  126.   Buffer  :array[0..15] of T2D;
  127.   i,j,
  128.   p,q,l,h :Integer;
  129.   P2,P1   :T2D;
  130.   V       :T3D;
  131.   Clip    :Boolean;
  132.  
  133.   procedure Calc;
  134.   begin
  135.     with F^ do begin
  136.       GetCrossing(TL^[List[i]], TL^[List[h]], V);
  137.       Project(V,Buffer[j]);
  138.     end;
  139.   end;
  140.  
  141. begin
  142.   Clip := false;
  143.   with F^ do begin
  144.     j := 0;
  145.     i := 0;
  146.     h := Count-1;
  147.  
  148.     if PL^[List[0]].Visible then begin
  149.       while PL^[List[i]].Visible do begin
  150.         Buffer[j] := PL^[List[i]].P;
  151.         Inc(j);
  152.         Inc(h);
  153.         if h >= Count then h := 0;
  154.         Inc(i);
  155.         if i >= Count then break;
  156.       end;
  157.  
  158.       if i < Count then begin
  159.         Clip := true;
  160.         Calc;
  161.         Inc(j);
  162.  
  163.         while not PL^[List[i]].Visible do begin
  164.           Inc(i);
  165.           if i >= Count then i := 0;
  166.           Inc(h);
  167.           if h >= Count then h := 0;
  168.         end;
  169.         Calc;
  170.         Inc(j);
  171.  
  172.         if i <> 0 then begin
  173.           while PL^[List[i]].Visible do begin
  174.             Buffer[j] := PL^[List[i]].P;
  175.             Inc(j);
  176.             Inc(h);
  177.             if h >= Count then h := 0;
  178.             Inc(i);
  179.             if i >= Count then break;
  180.           end;
  181.         end;
  182.       end;
  183.     end
  184.     else begin
  185.       Clip := true;
  186.       while not PL^[List[i]].Visible do begin
  187.         Inc(i);
  188.         if i >= Count then break;
  189.       end;
  190.       if i < Count then begin
  191.         h := i-1;
  192.         Calc;
  193.         Inc(j);
  194.         while PL^[List[i]].Visible do begin
  195.           Buffer[j] := PL^[List[i]].P;
  196.           Inc(j);
  197.           Inc(h);
  198.           if h >= Count then h := 0;
  199.           Inc(i);
  200.           if i >= Count then i := 0;
  201.         end;
  202.         Calc;
  203.         Inc(j);
  204.       end
  205.     end;
  206.     VecSub2D(Buffer[1],Buffer[0],P1);
  207.     VecSub2D(Buffer[2],Buffer[0],P2);
  208.     if LongInt(P1[y])*P2[x]-LongInt(P1[x])*P2[y] <= 0 then begin
  209.       if not Clip then begin
  210.         CxyTexturedPoly(@Buffer,@PointDef,j,Textures[Texture])
  211.       end;
  212.     end;
  213.   end;
  214. end;
  215.  
  216.  
  217.  
  218. procedure InitZList;
  219. var
  220.   i :Integer;
  221. begin
  222.   for i := 0 to FCount-1 do ZL^[i].P := FL^[i]
  223. end;
  224.  
  225.  
  226.  
  227. procedure UpdateZList;
  228. var
  229.   i,j :Integer;
  230.   _z  :LongInt;
  231.   F   :PFace;
  232. begin
  233.   for i := 0 to FCount-1 do begin
  234.     with ZL^[i].P^ do begin
  235.       _z:=List[0];
  236.       for j:=1 to Count-1 do Inc(_z,TL^[List[j],2]);
  237.       _z:= _z div Count;
  238.     end;
  239.     ZL^[i].z:=_z;
  240.   end;
  241. end;
  242.  
  243.  
  244.  
  245. procedure SortZList(l, r: Integer);
  246. var
  247.   i,
  248.   j :Integer;
  249.   x :LongInt;
  250.   S :TZEntry;
  251. begin
  252.   i := l;
  253.   j := r;
  254.   x := ZL^[(l+r) shr 1].z;
  255.   repeat
  256.     while ZL^[i].z < x do Inc(i);
  257.     while ZL^[j].z > x do Dec(j);
  258.     if i <= j then begin
  259.       S := ZL^[i];
  260.       ZL^[i] := ZL^[j];
  261.       ZL^[j] := S;
  262.       Inc(i);
  263.       Dec(j);
  264.     end;
  265.   until i > j;
  266.   if l < j then SortZList(l, j);
  267.   if i < r then SortZList(i, r);
  268. end;
  269.  
  270.  
  271.  
  272. procedure TransformPoints(M :TMatrix);
  273. var
  274.   i :Integer;
  275.   V :T3D;
  276. begin
  277.   for i := 0 to PCount-1 do begin
  278.     Transform(VL^[i],M,TL^[i]);
  279.     if TL^[i][2]<zClipPlane then PL^[i].Visible:=false
  280.     else begin
  281.       PL^[i].Visible:=true;
  282.       Project(TL^[i],PL^[i].P);
  283.     end;
  284.   end;
  285. end;
  286.  
  287.  
  288. procedure ShowWorld;
  289. var
  290.   i :Integer;
  291. begin
  292.   if KeyPressed then begin
  293.     while KeyPressed do ReadKey;
  294.     halt(0);
  295.   end;
  296.   ShowVBuffer;
  297.   UpdateZList;
  298.   SortZList(0, FCount-1);
  299.   MakeMatrix(t[0],t[1],t[2], $200,$1B0,$200, rx,ry,rz, M);
  300.   TransformPoints(M);
  301.   for i := FCount-1 downto 0 do DrawFace(ZL^[i].P);
  302. end;
  303.  
  304.  
  305. procedure DOOM_PART;
  306. var
  307.   i :Word;
  308. begin
  309.   t[0] := 0;
  310.   t[1] := -6*$200;
  311.   t[2] := -30*$200;
  312.   rx := 0;
  313.   ry := 0;
  314.   rz := 0;
  315.   FC:= 0;
  316.   i := 0;
  317.   while FC < 512 do begin
  318.     ry := FC shr 2;
  319.     ShowWorld;
  320.   end;
  321.   Dec(FC,512);
  322.   while FC < 1024 do begin
  323.     ry := 512 shr 2-FC shr 2;
  324.     ShowWorld;
  325.   end;
  326.   Dec(FC,1024);
  327.  
  328.   while FC < 512 do begin
  329.     rz := (FC shr 1);
  330.     ry := -128+FC shr 1;
  331.     rx := FC shr 1;
  332.     ShowWorld;
  333.   end;
  334.   Dec(FC,512);
  335.  
  336.   rx := 256;
  337.   while FC < 512 do begin
  338.     rz := 256-FC shr 1;
  339.     ry := 128-FC shr 1;
  340.     ShowWorld;
  341.   end;
  342.   Dec(FC,512);
  343.  
  344.   rz := 0;
  345.   ry := -128;
  346.   while FC < 512 do begin
  347.     rz := -FC;
  348.     rx := 256-FC shr 1;
  349.     ShowWorld;
  350.   end;
  351.   Dec(FC,512);
  352.  
  353.   rx := 0;
  354.   while FC < 4096-512+256 do begin
  355.     rz := -512-FC;
  356.     t[0] := FC;
  357.     t[2] := -$3C00+FC*$14;
  358.     ShowWorld;
  359.   end;
  360.   Dec(FC,4096-512+256);
  361.  
  362.   t[0] := 4096-256;
  363.   while FC < 896 do begin
  364.     rz := -256+FC shr 1;
  365.     ry := -128-FC;
  366.     t[2] := -$3C00+(4096-256)*$14+FC*17;
  367.     ShowWorld;
  368.   end;
  369.   t[2] := -$3C00+(4096-256)*$14+896*17;
  370.   Dec(FC,896);
  371.  
  372.   ry := -1024;
  373.   while FC < 512 do begin
  374.     t[0] := 4096-256+FC*$15*2;
  375.     rz := 192-FC;
  376.     ShowWorld;
  377.   end;
  378.   Dec(FC,512);
  379.  
  380.   while FC < 1048 do begin
  381.     t[0] := 4096-256+(512+FC)*$15*2;
  382.     t[1] := -6*$200-FC*9;
  383.     rz := 192-512-FC;
  384.     ShowWorld;
  385.   end;
  386.   Dec(FC,1048);
  387. end;
  388.  
  389.  
  390.  
  391. procedure LoadTexture(TEX :String; var P :Pointer);
  392. var
  393.   f :file;
  394. begin
  395.   GetMem(P,64000);
  396.   Assign(f,TEX);
  397.   Reset(f,1);
  398.   if IOResult <> 0 then begin
  399.     writeln('[ERROR]: File not found...');
  400.     halt(1);
  401.   end;
  402.   BlockRead(f,P^,64000);
  403.   Close(f);
  404. end;
  405.  
  406.  
  407.  
  408. procedure LoadPal(var DAC :TDACBlock; PAL :String);
  409. var
  410.   f :file;
  411. begin
  412.   Assign(f,PAL);
  413.   Reset(f,1);
  414.   BlockRead(f,DAC,3*256);
  415.   Close(f);
  416. end;
  417.  
  418.  
  419. procedure LoadVectorData;
  420. var
  421.   f :Text;
  422.   s :String;
  423.   i :Integer;
  424.   r :Real;
  425.   v :Integer;
  426. begin
  427.   PCount:=0;
  428.   FCount:=0;
  429.   New(VL);
  430.   New(TL);
  431.   New(PL);
  432.   New(FL);
  433.   New(ZL);
  434.   Assign(f,'DUNGEON.FCE');
  435.   Reset(f);
  436.   if IOResult <> 0 then begin
  437.     writeln('[ERROR]: Opening vector data failed...');
  438.     halt(1);
  439.   end;
  440.   while not eof(f) do begin
  441.     readln(f,s);
  442.     if s='[POINT]' then begin
  443.       for i:=0 to 2 do begin
  444.         readln(f,r);
  445.         VL^[PCount][i]:=round(r*$200);
  446.       end;
  447.       Inc(PCount);
  448.     end
  449.     else
  450.     if s='[FACE]' then begin
  451.       readln(f,v);
  452.       Getmem(FL^[FCount],4+v*2);
  453.       FL^[FCount]^.Count:=v;
  454.       for i:=0 to v-1 do begin
  455.         readln(f,FL^[FCount]^.List[i]);
  456.       end;
  457.       readln(f,s);
  458.       if s='[TEXTURE]' then begin
  459.         readln(f,FL^[FCount]^.Texture);
  460.       end
  461.       else begin
  462.         writeln('[ERROR]: Bad vector data...');
  463.         halt;
  464.       end;
  465.       Inc(FCount);
  466.     end
  467.     else begin
  468.       writeln('[ERROR]: Bad vector data...');
  469.       halt;
  470.     end;
  471.   end;
  472.   Close(f);
  473.   InitZList;
  474. end;
  475.  
  476.  
  477. begin
  478.   ClrScr;
  479.   writeln('-------------------------------------------------------------------------------');
  480.   writeln(' Vector dungeon (from the UNEATABLE megademo by THE COEXiSTENCE)');
  481.   writeln('-------------------------------------------------------------------------------');
  482.   writeln;
  483.   writeln(' Copyright (c) 1994,95 by J.E. Hoffmann');
  484.   writeln(' All rights reserved');
  485.   writeln;
  486.   writeln('-------------------------------------------------------------------------------');
  487.   writeln;
  488.   writeln(' YOU ARE USING THIS SOFTWARE AT YOUR OWN RISK!');
  489.   writeln(' IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR');
  490.   writeln(' CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,');
  491.   writeln(' DATA OR PROFITS!');
  492.   writeln;
  493.   writeln('-------------------------------------------------------------------------------');
  494.   writeln;
  495.   writeln(' (Press return)');
  496.   readln;
  497.   LoadVectorData;
  498.   TexXSize := 320;
  499.   TexYSize := 200;
  500.   LoadTexture('FLOOR.RAW',Textures[0]);
  501.   LoadTexture('TEXTURE.RAW',Textures[1]);
  502.   GetMem(Textures[2],64000);
  503.   FillChar(Textures[2]^,64000,0);
  504.   LoadPal(DAC,'FLOOR.PAL');
  505.   Init13h;
  506.   InitVBuffer;
  507.   ClearScreen(0);
  508.   SetDACBlock(0,256,DAC);
  509.   InitFrameHandler;
  510.   OldExit := ExitProc;
  511.   ExitProc := @NewExit;
  512.   DOOM_PART;
  513. end.
  514.  
  515.