home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 16 / CD_ASCQ_16_0994.iso / maj / swag / graphics.swg < prev    next >
Text File  |  1994-08-29  |  692KB  |  4 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00137         GRAPHICS ROUTINES                                                 1      05-28-9313:47ALL                      SEAN PALMER              DOTSPIN.PAS              IMPORT              22     ╓ÿ. program dotspin;ππvar inPort1:word;πprocedure waitRetrace;assembler;asmπ mov dx,inPort1; {find crt status reg (input port #1)}π@L1: in al,dx; test al,8; jnz @L1;  {wait for no v retrace}π@L2: in al,dx; test al,8; jz @L2; {wait for v retrace}π end;ππconstπ tableWriteIndex=$3C8;π tableDataRegister=$3C9;ππprocedure setColor(color,r,g,b:byte);assembler;asm {set DAC color}π mov dx,tableWriteIndex; mov al,color; out dx,al; inc dx;π mov al,r; out dx,al; mov al,g; out dx,al; mov al,b;out dx,al;π end; {write index now points to next color}ππ{plot a pixel in mode $13}πprocedure plot(x,y:word);Inline(π  $5E/                   { pop si  ;y}π  $5F/                   { pop di  ;x}π  $B8/$00/$A0/           { mov ax,$A000}π  $8E/$C0/               { mov es,ax}π  $B8/$40/$01/           { mov ax,320}π  $F7/$E6/               { mul si}π  $01/$C7/               { add di,ax}π  $26/$F6/$15);          {es: not byte[di]}ππprocedure plot4(x,y:word);const f=60;beginπ plot(x+f,y);π plot(199+f-x,199-y);π plot(199+f-y,x);π plot(y+f,199-x);π end;ππprocedure click;assembler;asmπ in al,$61; xor al,2; out $61,al;π end;ππconst nDots=21;ππvarπ dot:array[0..nDots-1]of recordπ  x,y,sx,sy:integer;π  end;ππfunction colorFn(x:integer):byte;beginπ colorFn:=63-(abs(100-x)div 2);π end;ππprocedure moveDots;var i:word;beginπ for i:=0 to nDots-1 do with dot[i] do beginπ  plot4(x,y);π  inc(x,sx);inc(y,sy);π  if(word(x)>200)then beginπ   sx:=-sx;inc(x,sx);click;π   end;π  if(word(y)>199)then beginπ   sy:=-sy;inc(y,sy);click;π   end;π  plot4(x,y);π  end;π waitRetrace;waitRetrace;waitRetrace;{waitRetrace;}π setcolor(255,colorFn(dot[0].x),colorFn(dot[3].x),colorFn(dot[6].x));π end;ππprocedure drawdots;var i:word;beginπ for i:=0 to nDots-1 do with dot[i] do plot4(x,y);π end;ππprocedure initDots;var i,j,k:word;beginπ j:=1;k:=1;π for i:=0 to nDots-1 do with dot[i] do beginπ  x:=100;y:=99;π  sx:=j;sy:=k;π  inc(j);if j>=k then begin j:=1;inc(k); end;π  end;π end;ππfunction readKey:char;Inline(π  $B4/$07/               {mov ah,7}π  $CD/$21);              {int $21}ππfunction keyPressed:boolean;Inline(π  $B4/$0B/               {mov ah,$B}π  $CD/$21/               {int $21}π  $24/$FE);              {and al,$FE}ππbeginπ inPort1:=memw[$40:$63]+6;π port[$61]:=port[$61]and (not 1);π setcolor(255,60,60,63);π initDots;π asm mov ax,$13; int $10; end;π drawDots;π repeat moveDots until keypressed;π readkey;π drawDots;π asm mov ax,3; int $10; end;π end.πππ * OLX 2.2 * Printers do it without wrinkling the sheets.ππ--- Maximus 2.01wbπ * Origin: >>> Sun Mountain BBS <<< (303)-665-6922 (1:104/123)π                                                                                                                     2      05-28-9313:47ALL                      SWAG SUPPORT TEAM        MCGATUT.TXT              IMPORT              40     ╓S                             MCGA Graphics Tutorialπ                                 Lesson #1π                                by Jim CookππI'm not sure how this online tutorial will be received, but with yourπcomments and feedback I plan on creating a full-blown animation package. Thisπgraphics library will be available to the public domain and will contain theπfollowing abilities:ππ                Setting/Reading Pixelsπ                Drawing linesπ                Saving/Restoring areas of the screenπ                Displaying PCX/LBM files to the screenπ                Spriting (Display picture with transparent areas)π                Palette control (Smooth fades to black)π                Page flippingππBefore we're done, you will have the tools to produce programs with rich,πeven photo-realistic (for the resolution) images on your PC.  The necessaryπhardware is a VGA card and monitor that's it.  I'll be using Turbo Pascalπversion 6.0.  Please holler if that will be a problem.  I'm using it toπcreate inline assembly.  My alternatives are inline code (yuk) or linking inπexternal assembly.  For speed (and actually ease) the latter is better.  If Iπreceive three complaints against 6.0, I'll use external assembly.ππ                                What is MCGA?ππMulti-Color Graphics Array is the video card that IBM built into it's Modelπ25 and 30 PS/2's.  It subsequently became a subset of the standard VGAπadapter card.  It has the distiction of being the first card (excludingπTarga and other expensive cards) to display 256 colors at once on theπcomputer screen.  To us that meant cool games and neat pictures.  The MCGAπaddapter has added two new video modes to the PC world:ππ                Mode $11        640x480x2 colorsπ                Mode $13        320x200x256 colorsππObviously, we will deal with mode $13.  If we wanted to deal with twoπcolors, we'd be programming a CGA.  So much for the history lesson...let'sπdive in.ππI've created a unit, MCGALib, that will contain all of our MCGA routines.πThe first two procedures we will concern ourselves with are setting theπgraphics mode and setting a pixel.  The MCGALib is followed by a testπprogram that uses the two procedures:ππUnit MCGALib;ππinterfaceππProcedure SetGraphMode (Num:Byte);πProcedure SetPixel     (X,Y:Integer;Color:Byte);ππimplementationππvarπ  ScreenWide  :  Integer;π  ScreenAddr  :  Word;ππProcedure SetGraphMode (Num:Byte);πbeginπ  asmπ    mov al,Numπ    mov ah,0π    int 10hπ    end;π  Case Num ofπ    $13 : ScreenWide := 320;π    end;π  ScreenAddr := $A000;πend;π{πFunction PixelAddr (X,Y:Word) : Word;πbeginπ  PixelAddr := Y * ScreenWide + X;πend;ππProcedure SetPixel (X,Y:Integer;Color:Byte);πvarπ  Ofs    :  Word;πbeginπ  Ofs := PixelAddr (X,Y);π  Mem [ScreenAddr:Ofs] := Color;πend;π}ππProcedure SetPixel (X,Y:Integer;Color:Byte);πbeginπ  asmπ    push dsπ    mov  ax,ScreenAddrπ    mov  ds,axππ    mov  ax,Yπ    mov  bx,320π    mul  bxπ    mov  bx,Xπ    add  bx,axππ    mov  al,Colorπ    mov  byte ptr ds:[bx],alπ    pop  dsπ    end;πend;ππBeginπEnd.ππThis is the test program to make sure it's working...ππProgram MCGATest;ππusesπ  Crt,Dos,MCGALib;ππvarπ  Stop,π  Start  :  LongInt;π  Regs   :  Registers;ππFunction Tick : LongInt;πbeginπ  Regs.ah := 0;π  Intr ($1A,regs);π= egs.cx hl 16  Rgs.dx;πend;ππProcedure Control;πvarπ  I,J :  Integr;beginπ  Start := ic;π  Fr I := 0 to 199 doπ  For J  SetPixe (J,I,Random(256));π Stop := Tick;πend;ππPocdure Closing;πvarπ  Ch    :  Chr;πbeginπ  Repet Until Keypressed;π  While Keypressed do Ch:= Reake;π  TextMode (3);πook '(Stop-Start),' ticks or ,(Stop-Start)/182:4:3,'π seconds!');πnd;ππProcedure Init;πbeginπ  SetGaphMode ($13);π Randoiz;πend;ππBeginπ Initπ  Control;π  Cosing;πe where these listings coul get unbearably long in time.  I'lπexplore a few ays I can get this information to ya'll without takingup tooπmuch pace. Iwould like you tomake sue this routine works, ust in caseπyou ou graphis card. You may notce two SetPxelπprocedures in the MCGALib, one is commented out.  Remove he comments,πcomment up the uncommented SetPixel and run the test program aain.  Noticeπthe speed degradation.  Linking in raw assembly will eve improve upon theπspeed of the inline assembly.πPlease take the time to study each procedure and ASK ANY QUESTIONS tht youπmay have, even if it doesn't relate to the graphics routines.  I'm cetain Iπdo not want to get pulled off track by any discussions about STYLE,ur critiqueπ for others to learn rom.ππ                              Coming next timeππI think a discussio of video memory is paramount.  Possibly vertical andπhorizontal lines, if spce permits.ππHappy grafxπjimππ--- QuickBBS 2.75π * Origin: Quantum Leap.. (512)333-5360  HST/DS (1:387/307)π                                                                                                                                                                                                                                                     3      07-16-9306:46ALL                      SWAG SUPPORT TEAM        Simulate Star Field      IMPORT              28     ╓{ π{Program to simulate travel through a star field - try a different MaxStar}πusesπ  TpCrt, TpInline, Graph;    {OpInline used for HiWord only}πconstπ  MaxStar = 50;                        {num stars}π  MaxHistory = 3;                      {points per streak, = 2**n -1, note mask on line #59}πtypeπ  T_HistoryPoint = recordπ                     hX, hY : Integer;π                   end;π  T_Star = recordπ             X, Y       : LongInt;           {star position}π             DX, DY     : LongInt;         {delta}π             DXPositive,π             DYPositive : Boolean;π             Speed      : Word;π             History    : array[0..MaxHistory] of T_HistoryPoint; {Position history}π             HistIndex  : Byte;π           end;π  T_StarArray = array[1..MaxStar] of T_Star;πvarπ  Gd,π  Gm,π  i,π  j       : Integer;ππ  Color   : Word;ππ  A       : T_StarArray;π  BoundX,π  BoundY,π  CenterX,ππ  CenterY : LongInt;ππ  Angle   : Real;ππ  Shift   : Byte;ππBEGINπ  Gd := Detect;π  InitGraph(Gd, Gm, '\turbo\tp');π  if GraphResult <> grOk thenπ    Halt(1);π  Color := GetMaxColor;π  BoundX := GetMaxX * 65536;π  BoundY := GetMaxY * 65536;π  CenterX := GetMaxX * 32768;π  CenterY := GetMaxY * 32768;π  FillChar(A, SizeOf(A), $FF);π  Randomize;π  {Background}π  for i := 1 to 1500 doπ    PutPixel(Random(GetMaxX), Random(GetMaxY), Color);π  {Stars}π  repeatπ    for i := 1 to MaxStar doπ      with A[i] doπ        beginπ          if (X < 0) or (X > BoundX) or (Y < 0) or (Y > BoundY) thenπ            beginπ            {Position is off-screen, go back to center, new angle}π              Angle := 6.283185 * Random;π              Speed := Random(2000) + 1000;π              DX := Round(Speed * Sin(Angle));π              DY := Round(Speed * Cos(Angle));π              X := 300 * DX + CenterX;π              Y := 300 * DY + CenterY;π              DXPositive := DX > 0;π              DYPositive := DY > 0;π              DX := Abs(DX);π              DY := Abs(DY);π            {Erase all of old line segment}π              for j := 0 to MaxHistory doπ                with History[j] doπ                  PutPixel(hX, hY, 0);π            endπ          elseπ            begin               {Plot point}π              Inc(HistIndex);                {Next slot in history}π              HistIndex := HistIndex and $03; { <-- change for new MaxHistory!}π              with History[HistIndex] doπ                beginπ                  PutPixel(hX, hY, 0);         {Erase inner dot of line segment}π                  hX := HiWord(X);π                  hY := HiWord(Y);π                  PutPixel(hX, hY, Color);     {New outer dot of line segment}π                end;π        {Next point}π              if DXPositive thenπ                Inc(X, DX)π              elseπ                Dec(X, DX); {Add delta}π              if DYPositive thenπ                Inc(Y, DY)π              elseπ                Dec(Y, DY);π              case Speed ofπ                1000..1300 : Shift := 9;π                1300..1600 : Shift := 8;π                1600..2100 : Shift := 7;π                2100..2700 : Shift := 6;π                2700..2900 : Shift := 5;π                2900..3000 : Shift := 4;π              end;π              Inc(DX, DX shr Shift);         {Increase delta to accelerate}π              Inc(DY, DY shr Shift);π            end;π        end;π  until KeyPressed;π  ReadLn;π  CloseGraph;πEND.ππ                                                         4      07-16-9306:47ALL                      SWAG SUPPORT TEAM        A simple Star Field      IMPORT              11     ╓≥µ πprogram stars;ππconstπ  maxstars = 200;ππvar star  : array[0..maxstars] of word;π    speed : array[0..maxstars] of byte;π    i     : word;ππprocedure create;πbeginπ  for i := 0 to maxstars doπ    beginπ    star[i] := random(320) + random(200) * 320;π    speed[i] := random(3) + 1;π    if mem[$a000:star[i]] = 0 thenπ      mem[$a000:star[i]] := 100;π  end;πend;ππProcedure moveit; assembler;πasmπ     xor   bp,bpπ     mov   ax,0a000hπ     mov   es,axπ     lea   bx,starπ     lea   si,speedπ     mov   cx,320ππ@l1: mov   di,[bx]π     mov   al,es:[di]π     cmp   al,100π     jne   @j1π     xor   al,alπ     stosbπ@j1: mov   al,[si]π     xor   ah,ahπ     add   [bx],axπ     mov   ax,bxπ     xor   dx,dxπ     div   cxπ     mul   cxπ     mov   dx,bxπ     sub   dx,axπ     cmp   dx,319π     jle   @j3π     sub   [bx],cxπ@j3: mov   di,[bx]π     mov   al,es:[di]π     or    al,alπ     jnz   @j2π     mov   al,100π     stosbπ@j2: add   bx,2π     inc   siπ     inc   bpπ     cmp   bp,maxstarsπ     jle   @l1πend;ππbeginπ  asmπ    mov   ax,13hπ    int   10hπ    call  createπ@l1:π    mov   dx,3dahπ@r1:π    in    al,dxπ    test  al,8π    je    @r1π    call moveitπ    in   al,60hπ    cmp  al,1π    jne  @l1;π  end;πend.ππ                                                                      5      07-16-9306:47ALL                      SWAG SUPPORT TEAM        A Color Star Field       IMPORT              29     ╓æ/ {-------------------------- SCHNIPP -----------------------------}ππ{STARSCROLL.PAS geaenderte Fassung  }ππ{$A+,B-,D-,E-,F+,I+,L-,N-,O-,R-,S-,V-}π{$M 64000,0,655360}ππUSES crt,graph,BGIDriv;                 {ich binde die Treiber ein}ππCONST MaxStars=500;                     {auf meinem 386-25er muss ich inπ                                        der geaenderten Fassung schon 500π                                        Sterne eintragen, damit es nur nochπ                                        ein wenig schneller ist als die alteπ                                        Fassung mit 100 Sternen ;-)}ππTYPE Punkt=ARRAY[1..3] OF INTEGER;     {Siehe ganz unten Move()}ππVARπ   gd,gm,mpx,mpy,scal,a,b,e:integer;π   Stars1,Stars:ARRAY[1..MaxStars] OF Punkt;ππ   mx,my,m2x,m2y,sop,                   {siehe Init}π   act:INTEGER;ππPROCEDURE dpunkt( x,y,z, Col:integer);πVAR n:INTEGER;π  BEGINπ   n:=z+e;ππ   {n=Nenner, nur einmal berechnen, geht schneller}ππ   PutPixel(mpx+ (scal*x div n),mpy+ (scal*y div n),col);ππ                 {hier nur integer-operationen}π  END;ππPROCEDURE dline( x1,y1,z1,x2,y2,z2:integer);πVAR n1,n2:INTEGER;π  BEGINπ   n1:=z1+e;n2:=z2+e;  {n1=Nenner fuer 1.Punkt, n2=Nenner fuer 2.Punkt}ππ   Line(mpx+(scal*(x1 div n1)),mpy+(scal*(y1 div n1)),π        mpx+(scal*(x2 div n2)),mpy+(scal*(y2 div n2)));ππ      {Nix mit Round(xxx / nX), dauert zu lange: Integer ->Real ->Integer}π  END;ππPROCEDURE Init;πbeginπ act:=1;π e:=1;π scal := 2;ππ mx:=getmaxx;     {damit man es auch in EgaLo oder anderen GModes}π m2x:=mx shr 1;   {betreiben kann, alle Werte abhaengig von MaximalX und}π my:=getmaxy;     {MaximalY}π m2y:=my shr 1;π mpx:=m2x;π mpy:=m2y-(mpy shr 1);ππ sop:=sizeof(punkt);  {Schreibt sich leichter :-) }πend;ππBEGINπ  Randomize;π  gd:=ega;π  gm:=egahi;ππ  if RegisterBGIdriver(@EgaVgaDriverProc) < 0 then halt(255);ππ  InitGraph(gd,gm,'');  {oder InitGraph(gd,gm,'PathToDriver');}π  Init;π  FOR a:=0 TO 15 DO  SetRGBPalette(a,a*3,a*3,a*3);π  FOR a:=1 TO MaxStars DOπ    BEGINπ      Stars[a,1]:=Random(mx)-m2x;π      Stars[a,2]:=Random(my)-m2y;π      Stars[a,3]:=Random(30)+1;π    END;ππ  Move(Stars,Stars1,SoP*MaxStars);      {man sollte Stars1 initialisieren}π                                        {wenn man es benutzt}π  SetColor(15);π  SetVisualPage(act);ππ  {AB hier kommt es auf Geschwindigkeit an}ππ  REPEATπ            {IF act=0 THEN act:=1 ELSE act:=0; dauert zu lange, deshalb:}π            {wenn (act)=1 -> act:=1-(1) = 0  wenn (act)=0 -> act:=1-(0)=1}π    act:=1-act;ππ    SetActivePage(act);π    FOR a:= 1 TO MaxStars DOπ    BEGINπ      Stars[a,3]:=Stars[a,3]-1;π      IF stars[a,3]= 0 THENπ      BEGINπ        Stars[a,1]:=Random(mx)-m2x;π        Stars[a,2]:=Random(my)-m2y;π        Stars[a,3]:=30;π      END;π      dpunkt(Stars[a,1],Stars[a,2],Stars[a,3],15-(stars[a,3] shr 1));ππ                        {round(xxx/2) dauert zu lange {shr 1 = div 2 }π    END;π    SetVisualPage(act);ππ    act:=1-act;   {s.o.}ππ    SetActivePage(act);π    FOR a:=1 TO MaxStars DOπ    BEGINπ      dpunkt(Stars1[a,1],Stars1[a,2],Stars1[a,3],0);ππ      {Wenn man Stars1 nicht initialisierst kommt es schon mal vor, dassπ       man einen Division by Zero Error beim ersten beim 1. Aufruf erhaelt}ππ      move(stars[a],stars1[a],sop);ππ      {nicht einzeln uebertragen, Move ist schneller, deshalb auch Type Punkt}ππ    END;ππ    act:=1-act; {s.o.}ππ  UNTIL KeyPressed;ππ  closegraph;          {Nicht vergessen !!!! ;-) }πEND.ππ{------------------------- SCHNAPP --------------------------------------}ππ                                                        6      08-23-9309:18ALL                      SEAN PALMER              FAST Mode 13h Line Draw  IMPORT              29     ╓√£ {π===========================================================================π BBS: Beta ConnectionπDate: 08-20-93 (09:59)             Number: 2208πFrom: SEAN PALMER                  Refer#: NONEπ  To: ALL                           Recvd: NO  πSubj: FAST mode 13h Li (Part 1)      Conf: (232) T_Pascal_Rπ---------------------------------------------------------------------------πHey! Here's THE fastest mode 13h bresenham's line drawing function ever.π(I think...prove me wrong, please!!)ππIt's written for TP 6 or better, uses BASM. If you don't know assembly, justπput it in a unit and don't worry about how it works. If you do, fine.πSome good optimizations in there...ππHave fun! If anyone wants the mostly-pascal equivalent, let me know.πIt's still fast.ππ{by Sean Palmer}π{public domain}ππvar color:byte;ππprocedure line(x,y,x2,y2:word);assembler;asm {mode 13}π mov ax,$A000π mov es,axπ mov bx,xπ mov ax,yπ mov cx,x2π mov si,y2π cmp ax,siπ jbe @NO_SWAP   {always draw downwards}π xchg bx,cxπ xchg ax,siπ@NO_SWAP:π sub si,ax         {yd (pos)}π sub cx,bx         {xd (+/-)}π cld               {set up direction flag}π jns @H_ABSπ neg cx      {make x positive}π stdπ@H_ABS:π mov di,320π mul diπ mov di,axπ add di,bx   {di:adr}π or si,siπ jnz @NOT_Hπ{horizontal line}π cldπ mov al,colorπ inc cxπ rep stosbπ jmp @EXITπ@NOT_H:π or cx,cxπ jnz @NOT_Vπ{vertical line}π cldπ mov al,colorπ mov cx,siπ inc cxπ mov bx,320-1π@VLINE_LOOP:π stosbπ add di,bxπ loop @VLINE_LOOPπ jmp @EXITπ@NOT_V:π cmp cx,si    {which is greater distance?}π lahf         {then store flags}π ja @H_INDπ xchg cx,si   {swap for redundant calcs}π@H_IND:π mov dx,si    {inc2 (adjustment when decision var rolls over)}π sub dx,cxπ shl dx,1π shl si,1     {inc1 (step for decision var)}π mov bx,si    {decision var, tells when we need to go secondary direction}π sub bx,cxπ inc cxπ push bp      {need another register to hold often-used constant}π mov bp,320π mov al,colorπ sahf         {restore flags}π jb @DIAG_Vπ{mostly-horizontal diagonal line}π or bx,bx     {set flags initially, set at end of loop for other iterations}π@LH:π stosb        {plot and move x, doesn't affect flags}π jns @SH      {decision var rollover in bx?}π add bx,siπ loop @LH   {doesn't affect flags}π jmp @Xπ@SH:π add di,bpπ add bx,dxπ loop @LH   {doesn't affect flags}π jmp @Xπ@DIAG_V:π{mostly-vertical diagonal line}π or bx,bx    {set flags initially, set at end of loop for other iterations}π@LV:π mov es:[di],al   {plot, doesn't affect flags}π jns @SV          {decision var rollover in bx?}π add di,bp        {update y coord}π add bx,siπ loop @LV         {doesn't affect flags}π jmp @Xπ@SV:π scasb   {sure this is superfluous but it's a quick way to inc/dec x coord!}π add di,bp        {update y coord}π add bx,dxπ loop @LV         {doesn't affect flags}π@X:π pop bpπ@EXIT:π end;ππvar k,i,j:word;πbeginπ asm mov ax,$13; int $10; end;π for k:=0 to 31 do beginπ  i:=k*10;π  j:=k*6;π  color:=14;π  line(159,99,i,0);π  color:=13;π  line(160,99,319,j);π  color:=12;π  line(160,100,319-i,199);π  color:=11;π  line(159,100,0,199-j);π  i:=k*9;π  j:=k*5;π  color:=6;π  line(i,0,159,99);π  color:=5;π  line(319,j,160,99);π  color:=4;π  line(319-i,199,160,100);π  color:=3;π  line(0,199-j,159,100);π  end;π Readln;π asm mov ax,3; int $10; end;π end.ππ... I'm not unemployed, I'm indefinitely leisured.π___ Blue Wave/QWK v2.12π---π * deltaComm Online 919-481-9399 - 10 linesπ * PostLink(tm) v1.06  DELTA (#22) : RelayNet(tm) HUBπ                                                                                                                         7      08-27-9319:57ALL                      STEVE CONNET             3D Rotations             IMPORT              22     ╓U╜ {πSTEVE CONNETππOkay, here's the equations For 3D rotations...ππx,y,z are the coordinates of the point you want to rotate.πrx,ry,rz are the amount of rotation you want (in degrees) For x,y,zπ}ππ  x1 := round(cos(rad(ry)) * x  - sin(rad(ry)) * z);π  z1 := round(sin(rad(ry)) * x  + cos(rad(ry)) * z);π  x  := round(cos(rad(rz)) * x1 + sin(rad(rz)) * y);π  y1 := round(cos(rad(rz)) * y  - sin(rad(rz)) * x1);π  z  := round(cos(rad(rx)) * z1 - sin(rad(rx)) * y1);π  y  := round(sin(rad(rx)) * z1 + cos(rad(rx)) * y1);ππ{πBecause in Turbo Pascal, COS and SIN require radians For the argument,πI wrote a short Function called RAD() that converts degrees into radiansπ(I find degrees much easier to visualize)π}ππ  Function Rad(i : Integer) : Real;π  beginπ    Rad := i * (Pi / 360);π  end;ππ{πOf course, since most computers don't have 3D projection screens <G>,πuse these equations to provide a sense of perspective to the Object,πbut With 2D coordinates you can plot on a screen.ππx,y,z are from the equations above, and xc,yc,zc are the center pointsπfor the Object that you are rotating... I recommend setting xc,yc at 0,0πbut zc should be very high (+100).π}π  x2 := trunc((xc * z - x * zc) / (z - zc));π  y2 := trunc((yc * z - y * zc) / (z - zc));ππ{πAlternatively, if you don't want to bother With perspective, just dropπthe z values, and just plot the (x,y) instead.πππTo use these equations, pick a 3D Object and figure out what the 3Dπcoordinates are For each point on the Object.  You will have to have someπway to let the computer know which two points are connected.  For theπcube that I did, I had one Array For the points and one For each faceπof the cube.  That way the computer can draw connecting lines For eachπface With a simple for-loop.π}ππTypeπ  FaceLoc  = Array [1..4] of Integer;π  PointLoc = Recordπ    x, y, z : Integer;π  end;ππConstπ  face_c : Array [1..6] of faceloc =(π    (1,2,3,4),π    (5,6,2,1),π    (6,5,8,7),π    (4,3,7,8),π    (2,6,7,3),π    (5,1,4,8));ππ  point_c : Array [1..8] of pointloc =(π    (-25, 25, 25),π    ( 25, 25, 25),π    ( 25,-25, 25),π    (-25,-25, 25),π    (-25, 25,-25),π    ( 25, 25,-25),π    ( 25,-25,-25),π    (-25,-25,-25));π{πThere you go.  I'm not going to get much more complicated For now.  if youπcan actually get these equations/numbers to work (and I haven't forgottenπanything!) leave me another message, and I'll give you some advice forπfilling in the sides of the Object (so that you can only see 3 sides atπonce) and some advice to speed things up abit.  if you have any problemsπwith whats here, show some other people, and maybe as a collective you canπfigure it out.  Thats how I got this one started!π}π              8      08-27-9320:02ALL                      THOMAS GROFF             Endpoints of  PIE SegmentIMPORT              10     ╓0╘ {πTHOMAS GROFFππ> would like a unit to return the endpoints of a PIE segment. You couldπ> always draw the arc invisibly and then use the GetArcCoords() procedureπ> provided in the graph unit and save yourself some time.π}ππprogram getlegs;πusesπ  graph;πvarπ  pts3    : arccoordstype; { <---- Necessary to declare this type var. }π  rad,π  startang,π  endang,π  x, y,π  gd, gm  : integer;πbeginπ  gd := detect;π  InitGraph(gd,gm,'e:\bp\bgi');π  cleardevice;π  x := 100;π  y := 100;π  startang := 25;π  endang   := 130;π  rad      := 90;ππ  setcolor(getbkcolor);  {  <------ Draw arc in background color. }π  arc(x, y, startang, endang, rad);π  GetArcCoords(pts3);  {  <----- This is what you want, look it up! }π  setcolor(white);     {  <----- Show your lines now.}π  line(pts3.x, pts3.y, pts3.xstart, pts3.ystart);π  line(pts3.x, pts3.y, pts3.xend, pts3.yend);π  outtextxy(50, 150, 'Press enter to see your original arc when ready...');ππ  readln;π  setcolor(yellow);π  arc(x, y, startang, endang, rad);π  outtextxy(50, 200, 'Press enter stop demo.');π  readln;π  closegraph;πend.π                                                                     9      08-27-9320:03ALL                      STEPHEN CHEOK            ASM Fading               IMPORT              11     ╓Q╦ {πSTEPHEN CHEOKππ> Could you post the fade out source?π}ππPROCEDURE DimDisplay(delayfactor : INTEGER); ASSEMBLER;ππ{ Total time to fade out in seconds = ((DelayFactor+1)*MaxIntensity) / 1000 }ππCONSTπ  MaxIntensity = 45;π {MaxIntensity = 63;}ππVARπ  DACTable : Array [0..255] OF RECORDπ               R, G, B : BYTE;π             END;πASMπ  PUSH   DSπ  MOV    AX, SSπ  MOV    ES, AXπ  MOV    DS, AXππ { Store colour information into DACTable }ππ  LEA    DX, DACTableπ  MOV    CX, 256π  XOR    BX, BXπ  MOV    AX, 1017hπ  INT    10hππ  MOV    BX, MaxIntensityππ { VGA port 3C8h: PEL address register, (colour index,π increments automatically after every third write)π VGA port 3C9h: PEL write register (R, G, B) }ππ  CLDπ @1:π  LEA    SI, DACTableπ  MOV    DI, SIπ  MOV    CX, 3*256π  XOR    AX, AXπ  MOV    DX, 3C8hπ  OUT    DX, ALπ  INC    DXππ { Get colour value, decrement it and update the table }ππ @2:π  LODSBπ  OR     AX, AXπ  JZ     @3π  DEC    AXπ @3:π  STOSBπ  OUT    DX, ALπ  LOOP   @2ππ { Delay before next decrement of R, G, B values }ππ  PUSH   ESπ  PUSH   BXπ  MOV    AX, DelayFactorπ  PUSH   AXπ  CALL   Delayπ  POP    BXπ  POP    ESππ  DEC    BXπ  OR     BX, BXπ  JNZ    @1π  POP    DSπEND;  { DimDisplay }πππ                                                      10     08-27-9320:14ALL                      RANDY PARKER             Including BGI in EXE     IMPORT              23     ╓ S {πRANDY PARKERππ> Does anyone out there knwo how you can compile a Program using one ofπ> Borland's BGI units for grpahics and not have to distribute the BGIπ> file(s) with the EXE?ππ   First, convert the BGI and CHR files to .OBJ files (object) by usingπBINOBJ.EXE.  You may just want to clip out the following and name it as a batchπfile.ππ   BINOBJ.EXE goth.chr goth gothicfontprocπ   BINOBJ.EXE litt.chr litt smallfontprocπ   BINOBJ.EXE sans.chr sans sansseriffontprocπ   BINOBJ.EXE trip.chr trip triplexfontprocπ   BINOBJ.EXE cga.bgi cga cgadriverprocπ   BINOBJ.EXE egavga.bgi egavga egavgadriverprocπ   BINOBJ.EXE herc.bgi herc hercdriverprocπ   BINOBJ.EXE pc3270.bgi pc3270 pc3270driverprocπ   BINOBJ.EXE at.bgi att attdriverprocππ   You should now have the following files:ππ     ATT.OBJ, CGA.OBJ, EGAVGA.OBJ GOTH.OBJ HERC.OBJ LITT.OBJ PC3270.OBJ,π     SANS.OBJ, TRIP.OBJ.π}ππunit GrDriver;ππinterfaceππuses Graph;ππimplementationππprocedure ATTDriverProc;    External; {$L ATT.OBJ}πprocedure CGADriverProc;    External; {$L CGA.OBJ}πprocedure EGAVGADriverProc; External; {$L EGAVGA.OBJ}πprocedure HercDriverProc;   External; {$L HERC.OBJ}πprocedure PC3270DriverProc; External; {$L PC3270.OBJ}ππprocedure ReportError(s : string);πbeginπ  writeln;π  writeln(s, ': ', GraphErrorMsg(GraphResult));π  Halt(1);πend;ππbeginπ  if RegisterBGIdriver(@ATTDriverProc) < 0 thenπ    ReportError('AT&T');π  if RegisterBGIdriver(@CGADriverProc) < 0 thenπ    ReportError('CGA');π  if RegisterBGIdriver(@EGAVGADriverProc) < 0 thenπ    ReportError('EGA-VGA');π  if RegisterBGIdriver(@HercDriverProc) < 0 thenπ    ReportError('Hercules');π  if RegisterBGIdriver(@PC3270DriverProc) < 0 thenπ    ReportError('PC-3270');πend.πππunit GrFont;ππinterfaceππusesπ  Graph;ππimplementationππprocedure GothicFontProc;    External; {$L GOTH.OBJ}πprocedure SansSerifFontProc; External; {$L SANS.OBJ}πprocedure SmallFontProc;     External; {$L LITT.OBJ}πprocedure TriplexFontProc;   External; {$L TRIP.OBJ}ππprocedure ReportError(s : string);πbeginπ  writeln;π  writeln(s, ' font: ', GraphErrorMsg(GraphResult));π  halt(1)πend;ππbeginπ  if RegisterBGIfont(@GothicFontProc) < 0 thenπ    ReportError('Gothic');π  if RegisterBGIfont(@SansSerifFontProc) < 0 thenπ    ReportError('SansSerif');π  if RegisterBGIfont(@SmallFontProc) < 0 thenπ    ReportError('Small');π  if RegisterBGIfont(@TriplexFontProc) < 0 thenπ    ReportError('Triplex');πend.ππ{πBy using the 2 units above, you should be able to include any video driverπof font (that were listed) by simply insertingππUsesπ  GrFont, GrDriver, Graph;ππinto your graphic files.ππI got this out of a book name Mastering Turbo Pascal 6, by Tom Swan. It's anπexcellent book that covers from Turbo 4.0 to 6.0, basics to advanced subjects.πHope it works for you.π}π                                 11     08-27-9320:16ALL                      WILBER VAN LEIJEN        Very Large Graphic Image IMPORT              15     ╓≡ {πWILBERT VAN LEIJENππ> I am looking for a way to get an Image into a pointer (besides arrays)π> and write it to my disk. I am using arrays right now, and works fine, butπ> When  I get big images I run out of mem fast...  :: IBUF : array [1..30000]π> of byte; getimage(x1,y1,x2,y2,IBUF); repeat Write(f,IBUF[NUM]); num:=num+1;π> until num=sizeof(ibuf);π> This works as long as I dont try to grab a large image.ππThese "large images" are in fact stored in "planes", chunks of up to 64 kByteπin size. You must understand the VGA architecture to store these in a file.πThe only VGA video mode that keeps all data (from the programmer's point ofπview) into a single data space is mode 13h (320x200 with 256 colours): a simpleπarray [1..200, 1..320] of Byte.  The other video modes require you to accessπthe VGA hardware: take for example 640x480 by 16 colours: 4 planes of 38,400πbytes (Red, Green, Blue and Intensity).  Together with the colour informationπas returned by BIOS call INT 10h/AX=1012h they make up the picture.ππHere's how you select a plane:π}ππProcedure SwitchBitplane(plane : Byte); Assembler;ππASMπ  MOV   DX, 3C4hπ  MOV   AL, 2π  OUT   DX, ALπ  INC   DXπ  MOV   AL, planeπ  OUT   DX, ALπend;ππ{πAssume the video mode to be 12h (640x480/16 colours), BitplaneSize = 38400, andπBitplane is an Array[0..3] of pointer to an array [1..38400] of Byte:π}π      For i := 0 to 3 Doπ        Beginπ          SwitchBitplane(1 shl i);π          Move(Bitplane[i]^, Ptr($A000, $0000)^, BitplaneSize);π        end;π{πThis is a snippet of code lifted from my VGAGRAB package; a TSR that dumpsπgraphic information (any standard VGA mode) to a disk file by pressingπ<PrtScr>, plus a few demo programs written in TP - with source code.  Availableπon FTP sites.π}π                                  12     08-27-9320:18ALL                      RAPHAEL VANNEY           Display Text in Graphics IMPORT              11     ╓h# {πRAPHAEL VANNEYππ*You mean displaying Text While in Graphics mode :-) ?ππ> Yup. Already got a suggestion on using 640x480 With 8x8 font, so ifπ> you have any other one please do tell.. ttyl...ππSure. Just call the BIOS routines to display Characters With a "standard"πlook. By standard look, I mean they look like they were Characters inπText mode.ππOkay, here is the basic Procedure to display a String (Works in any Text/πGraphics mode) :π}ππProcedure BIOSWrite(Str : String; Color : Byte); Assembler;πAsmπ  les  di, Strπ  mov  cl, es:[di]     { cl = longueur chane }π  inc  di              { es:di pointe sur 1er caractre }π  xor  ch, ch          { cx = longueur chane }π  mov  bl, Color       { bl:=coul }π  jcxz @ExitBW         { sortie si Length(s)=0 }π @BoucleBW:π  mov  ah, 0eh         { sortie TTY }π  mov  al, es:[di]     { al=caractre  afficher }π  int  10h             { et hop }π  inc  di              { caractre suivant }π  loop @BoucleBWπ @ExitBW:πend ;ππ{πI'm not sure how to manage the background color in Graphics mode ; maybeπyou should experiment With values in "coul", there could be a magic bitπto keep actual background color.π}ππ                                                                                                                              13     08-27-9320:18ALL                      SEAN PALMER              Bit Map scaler           IMPORT              18     ╓┤ò {πSEAN PALMERππWell, I got a wild hair up my butt and decided to convert thatπbitmap scaler I posted into an inline assembler procedure (mostly)πIt's now quite a bit faster...ππby Sean Palmerπpublic domainπ}ππ{bitmaps are limited to 256x256 (duh)}ππtypeπ  fixed = recordπ    case boolean ofπ      true  : (w : longint);π      false : (f, i : word);π    end;ππconstπ  bmp : array [0..3, 0..3] of byte =π    ((0, 1, 2, 3),π     (1, 2, 3, 4),π     (2, 3, 4, 5),π     (3, 4, 5, 6));πvarπ  bmp2 : array [0..63, 0..63] of byte;π  i, j : integer;ππprocedure scaleBitmap(var bitmap; x, y : byte; x1, y1, x2, y2 : word);πvarπ  s, w, h    : word;  {xSkip,width,height}π  sx, sy, cy : fixed; {xinc, yinc, ySrcPos}πbeginπ  w    := x2 - x1 + 1;π  h    := y2 - y1 + 1;π  sx.w := x * $10000 div w;π  sy.w := y * $10000 div h;π  s    := 320-w;π  cy.w := 0;π  asmπ    push dsπ    mov  ds, word ptr bitmap+2;π    mov  ax, $A000π    mov  es, ax  {setup screen seg}π    cldπ    mov  ax, 320π    mul  y1π    add  ax, x1π    mov  di, ax {calc screen adr}π   @L2:π    mov  ax, cy.iπ    mul  xπ    mov  bx, axπ    add  bx, word ptr bitmap {offset}π    mov  cx, wπ    mov  si, 0     {fraction of src adr (bx.si)}π    mov  dx, sx.fπ   @L:π    mov  al, [bx]π    stosbπ    add  si, dxπ    adc  bx, sx.i    {if carry or sx.i<>0, new source pixel}π    loop @Lπ    add  di, s     {skip to next screen row}π    mov  ax, sy.fπ    mov  bx, sy.iπ    add  cy.f, axπ    adc  cy.i, bxπ    dec  word ptr hπ    jnz  @L2π    pop  dsπ  end;πend;ππbeginπ  for i := 0 to 63 do   {init bmp2}π    for j := 0 to 63 doπ      bmp2[j, i] := j + (i xor $19) + 32;π  asmπ    mov ax, $13π    int $10π  end;   {init vga mode 13h}π  for i := 2 to 99 do                 {test bmp}π    scaleBitMap(bmp, 4, 4, 0, 0, i * 2 - 1, i * 2 - 1);π  for i := 99 downto 2 doπ    scaleBitMap(bmp, 4, 4, 0, 0, i * 2 - 1, 197);π  for i := 1 to 66 do                 {test bmp2}π    scaleBitMap(bmp2, 64, 64, 0, 0, i * 2 - 1, i * 3 - 1);π  for i := 66 downto 1 doπ    scaleBitMap(bmp2, 64, 64, 0, 0, i * 2 - 1, i * 2 - 1 + 66);π  asmπ    mov ax, $3π    int $10π  end;      {restore text mode}πend.π                                                  14     08-27-9320:25ALL                      MICHAEL NICOLAI          Drawing Graphic Circles  IMPORT              23     ╓êX {πMICHAEL NICOLAIπππThe basic formula (and quickest) For drawing a circle is: x^2 + y^2 = r^2.πThe r stands For radius (half the diameter). You know this formula, i amπsure. A guy called Phytagoras set i up very long ago to calculate theπhypotenuse of a given triangle. (there has to be a 90° angel between a and b)πππ                   |\π                   | \π                 a |  \ c      c^2 = a^2 + b^2π                   |   \π                   |____\ππ                     bππRemember?ππNow look at this:        ...|     a quater of the circleπ                       ..   |π                      . ____|yπ                     . |\   |π                    .  | \  |π                    .  | r\ |π                    .  |   \|π               --------------------------π                    r  x    |0π                            |π                            |πππr is given and take 0 - r as a starting point For x. Then all you have to doπis to calculate y and plot the point.ππ    y = sqrt((r * r) - (x * x))      sqrt : square rootππAfter each calculation x is increased Until it has reached 0. Then oneπquarter of the circle is drawn. The other three quarters are symmetrical.ππI have written a short Program For you to draw a circle in 320x200x256πGraphics mode. When you key in some values please remember that NO errorπchecking will be done. x has to be between 0 and 319, and y between 0 andπ199. The radius must not be greater than x and y.ππExample: x : 160; y : 100; r : 90ππWhen you start this Program you will not get correct circles because inπGraphics mode ONE pixel is not square!!! You have to calculate an aspectπratio to get nice looking circles.π}ππProgram circle;ππUsesπ  Crt, Dos;ππVarπ  regs    : Registers;π  x0, y0  : Word;π  x, y, R : Real;π  temp    : Real;π  c       : Char;ππProcedure putpixel(x, y : Word; color : Byte);πbeginπ  mem[$A000: (y * 320 + x)] := color;πend;ππbeginπ  ClrScr;π  Writeln('Enter coordinates of middle-point :');π  Writeln;π  Write('x : '); readln(x0);π  Write('y : '); readln(y0);π  Writeln;π  Write('Enter radius :'); readln(R);ππ  { Switch to 320x200x256 }ππ  regs.ax := $0013;π  intr($10, regs);ππ  x := (-1) * R;  { go from 0 - R to 0 }π  temp := R * R;π  Repeatπ    y := sqrt(temp - (x * x));π    putpixel((x0 + trunc(x)), (y0 - trunc(y)), 15); { 4.th quadrant }π    putpixel((x0 - trunc(x)), (y0 - trunc(y)), 15); { 1.st quadrant }π    putpixel((x0 + trunc(x)), (y0 + trunc(y)), 15); { 3.rd quadrant }π    putpixel((x0 - trunc(x)), (y0 + trunc(y)), 15); { 2.nd quadrant }π    x := x + 0.1; { change this if you want coarse or fine circle. }π  Until (x >= 0.0);π  c := ReadKey;  { wait For keypress. }ππ  { Switch back to Textmode. }ππ  regs.ax := $0003;π  intr($10, regs);πend.π                                                                      15     08-27-9320:25ALL                      MICHAEL NICOLAI          More Graphic Circles     IMPORT              25     ╓s {πMICHAEL NICOLAIππ>does someone have a circle routine For the 320x200x256 mode.π>I need one using the Assembler...  (FAST) ( or isn't that possible)π>I doesn't need to be very perfect, if it has the shape of a circle,π>I'm satisfied.ππI don't have any Asm-Program yet but i got the same question some time ago.ππOk then, let's do some math:ππThe basic formula (and quickest?) For drawing a circle is: x^2 + y^2 = r^2.πThe r stands For radius (half the diameter). You know this formula, i amπsure. A guy called Phytagoras set i up very long ago to calculate theπhypotenuse of a given triangle.ππ                   |\π                   | \π                 a |  \ c      c^2 = a^2 + b^2π                   |   \π                   |____\ππ                     bπRemember?ππNow look at this:        ...|     a quater of the circleπ                       ..   |π                      . ____|yπ                     . |\   |π                    .  | \  |π                    .  | r\ |π                    .  |   \|π               --------------------------π                    r  x    |0π                            |π                            |ππr is given and take 0 - r as a starting point For x. Then all you have to doπis to calculate y and plot the point.ππ    y = sqrt((r * r) - (x * x))      sqrt : square rootππAfter each calculation x is increased Until it has reached 0. Then oneπquarter of the circle is drawn. The other three quarters are symmetrical.ππI have written a short Program For you to draw a circle in 320x200x256πGraphics mode. When you key in some values please remember that NO errorπchecking will be done. x has to be between 0 and 319, and y between 0 andπ199. The radius must not be greater than x and y.ππExample: x : 160; y : 100; r : 90ππWhen you start this Program you will not get correct circles because inπGraphics mode ONE pixel is not square!!! You have to calculate an aspectπratio to get nice looking circles.π}ππProgram circle;ππUsesπ  Crt, Dos;ππVarπ  regs    : Registers;π  x0, y0  : Word;π  x, y, R : Real;π  temp    : Real;π  c       : Char;ππProcedure putpixel(x, y : Word; color : Byte);πbeginπ  mem[$A000 : (y * 320 + x)] := color;πend;ππbeginπ ClrScr;π Writeln('Enter coordinates of middle-point :');π Writeln;π Write('x : ');π readln(x0);π Write('y : ');π readln(y0);π Writeln;π Write('Enter radius :');π readln(R);ππ { Switch to 320x200x256 }ππ regs.ax := $0013;π intr($10, regs);ππ x := (-1) * R;  { go from 0 - R to 0 }π temp := R * R;π Repeatπ   y := sqrt(temp - (x * x));π   putpixel((x0 + trunc(x)), (y0 - trunc(y)), 15); { 4.th quadrant }π   putpixel((x0 - trunc(x)), (y0 - trunc(y)), 15); { 1.st quadrant }π   putpixel((x0 + trunc(x)), (y0 + trunc(y)), 15); { 3.rd quadrant }π   putpixel((x0 - trunc(x)), (y0 + trunc(y)), 15); { 2.nd quadrant }π   x := x + 0.1; { change this if you want coarse or fine circle. }π Until (x >= 0.0);π c := ReadKey;  { wait For keypress. }ππ { Switch back to Textmode. }ππ regs.ax := $0003;π intr($10, regs);πend.π                                                                       16     08-27-9320:25ALL                      MIKE BURNS               Another Circle Routine   IMPORT              11     ╓ r {πMIKE BURNSππ> does someone have a circle routine for the 320x200x256 mode. I need oneπ> using the assembler...  (FAST) ( or isn't that possible) I doesn't need toπ> be very perfect, if it has the shape of a circle, I'm satisfied.π}ππPROCEDURE SWAP(VAR A, B : Integer);πVarπ  X : Integer;πBeginπ  X := A;π  A := B;π  B := X;πEnd;ππVarπ  SCR : Array [0..199, 0..319] of Byte Absolute $A000 : $0000;ππPROCEDURE Circle(X, Y, Radius : Word; Color: Byte);πVARπ  a, af, b, bf,π  target, r2   : Integer;πBeginπ  Target := 0;π  A  := Radius;π  B  := 0;π  R2 := Sqr(Radius);ππ  While a >= B DOπ  Beginπ    b:= Round(Sqrt(R2 - Sqr(A)));π    Swap(Target, B);π    While B < Target Doπ    Beginπ      Af := (120 * a) Div 100;π      Bf := (120 * b) Div 100;π      SCR[x + af, y + b] := color;π      SCR[x + bf, y + a] := color;π      SCR[x - af, y + b] := color;π      SCR[x - bf, y + a] := color;π      SCR[x - af, y - b] := color;π      SCR[x - bf, y - a] := color;π      SCR[x + af, y - b] := color;π      SCR[x + bf, y - a] := color;π      B := B + 1;π    End;π    A := A - 1;π  End;πEnd;ππbeginπ  Asmπ    Mov ax, $13π    Int $10;π  end;ππ  Circle(50, 50, 40, $32);π  Readln;ππ  Asmπ    Mov ax, $03π    Int $10;π  end;πend.ππππππ                                                            17     08-27-9320:28ALL                      SEAN PALMER              Simple coppering routine IMPORT              29     ╓¼E {πSEAN PALMERππ>Okay, I've got this small problem porting one of my assembler routinesπ>into pascal.  It's a simple coppering routine (multiple setting of theπ>same palette register for trippy effects :), and i can't seem to use itπ>in my code..  I'll post the code here now (it's fairly short), and ifπ>someone could help me out here, i'd be most grateful - since myπ>assembler/pascal stuff isn't too great..ππI imported it, but couldn't get it to work (several problems in theπsource) and in the process of getting it to work (for one thing I didn'tπknow what it was supposed to accomplish in the first place) I added aπfew things to it and this probably isn't what you wanted it to look likeπbut it wouldn't be hard to do now that it's in TP-acceptable form.ππI also added one other small palette flipper that's kind of neat.π}ππ{$G+}πusesπ  crt;ππprocedure copperBars(var colors; lines : word; regNum, count : byte); assembler;πvarπ  c2 : byte;πasmπ{π  okay, Colors is a pointer to the variable array ofπ  colours to use (6bit rgb values to pump to the dac)π  Lines is the number of scanlines on the screen (for syncing)π  RegNum is the colour register (DAC) to use.π  valid values are 0-255. that should explain that one.π  Count is the number of cycles updates to do before it exits.π}π  push dsππ  mov  ah, [RegNum]π  mov  dx, $3DA   {vga status port}π  mov  bl, $C8    {reg for DAC}π  cliπ  cldππ @V1:π  in   al, dxπ  test al, 8π  jz   @V1 {vertical retrace}π @V2:π  in   al, dxπ  test al, 8π  jnz  @V2ππ  mov  c2, 1π  mov  di, [lines]ππ @UPDATER:π  mov  bh, c2π  inc  c2π  lds  si, [colors]π                {now,just do it.}π @NIKE:π  mov  cx, 3π  mov  dl, $DAππ @H1:π  in   al, dxπ  and  al, 1π  jz   @H1  {horizontal retrace}ππ  mov  al, ah  {color}π  mov  dl, blπ  out  dx, alπ  inc  dxπ  rep  outsb              {186 instruction...}ππ  mov  dl, $DAπ @H2:π  in   al, dxπ  and  al, 1π  jnz  @H2;ππ  dec  diπ  jz   @Xπ  dec  bhπ  jnz  @NIKEπ  jmp  @UPDATERπ @X:π  dec  countπ  jnz  @V1π  sti                    {enable interrupts}πEnd;ππprocedure freakout0(lines : word; count : byte); assembler;πasmπ  mov dx, $3DA   {vga status port}π  cliπ  cldππ @V1:π  (* in   al, dxπ     test al, 8π     jz   @V1 {vertical retrace}π  @V2:π     in   al, dxπ     test al, 8π     jnz  @V2π  *)ππ  mov di,[lines]ππ @L:π  mov  dl, $C8π  mov  al, 0  {color}π  out  dx, alπ  inc  dxπ  mov  al, bhπ  out  dx, alπ  add  al, 20π  out  dx, alπ  out  dx, alπ  add  bh, 17π  mov  dl, $DAπ  in   al, dxπ  test al, 1π  jz   @L;  {until horizontal retrace}ππ  dec  diπ  jnz  @Lππ  mov  dl, $DAπ  dec  countπ  jnz  @V1π  sti                    {enable interrupts}πEnd;ππconstπ pal : array [0..3 * 28 - 1] of byte =π   (2,4,4,π    4,8,8,π    6,12,12,π    8,16,16,π    10,20,20,π    12,24,24,π    14,28,28,π    16,32,32,π    18,36,36,π    20,40,40,π    22,44,44,π    24,48,48,π    26,52,52,π    26,52,52,π    28,56,56,π    28,56,56,π    30,60,60,π    30,60,60,π    30,60,60,π    33,63,63,π    33,63,63,π    33,63,63,π    33,63,63,π    33,63,63,π    30,60,60,π    28,56,56,π    26,52,52,π    24,48,48);ππvarπ  i : integer;ππbeginπ  asmπ    mov ax, $13π    int $10π  end;π  for i := 50 to 149 doπ    fillchar(mem[$A000 : i * 320 + 50], 220, 1);ππ  repeatπ    copperBars(pal, 398, 0, 8);  {398 because of scan doubling}π  until keypressed;π  readkey;ππ  repeatπ    freakout0(398, 8);  {398 because of scan doubling}π  until keypressed;π  readkey;ππ  asmπ    mov ax, 3π    int $10π  end;πend.π                                                                                                                   18     08-27-9321:03ALL                      CHRIS BEISEL             Screen Fades             IMPORT              18     ╓▐╬ {πCHRIS BEISELππI've gotten many compliments on these two fade routines (a few goodπprogrammers thought they were asm!)... plus, I made them so you can fadeπpart on the palette also... It's very smooth on my 486, as well as 386'sπand 286's at friends houses...ππ        set up in your type declarationsπ                rgbtype=recordπ                    red,green,blue:byte;π                end;π                rgbarray[0..255] of rgbtype;ππ        and in your var declarations have something likeπ                rgbpal:rgbarray;ππ        and set your colors in that...π}πprocedure fadein(fadepal : rgbarray; col1, col2 : byte);πvarπ  lcv,π  lcv2 : integer;π  tpal : rgbarray;πbeginπ  for lcv := col1 to col2 doπ  beginπ    TPal[lcv].red   := 0;π    TPal[lcv].green := 0;π    TPal[lcv].blue  := 0;π  end;π  for lcv := 0 to 63 doπ  beginπ    for lcv2:=col1 to col2 doπ    beginπ      if fadepal[lcv2].red > TPal[lcv2].red thenπ        TPal[lcv2].red := TPal[lcv2].red + 1;π      if fadepal[lcv2].green > TPal[lcv2].green thenπ        TPal[lcv2].green := TPal[lcv2].green + 1;π      if fadepal[lcv2].blue > TPal[lcv2].blue thenπ        TPal[lcv2].blue := TPal[lcv2].blue+1;ππ      setcolor(lcv2, TPal[lcv2].red, TPal[lcv2].green, TPal[lcv2].blue);π    end;π    refresh;π  end;πend;ππ{*******************************************************************}ππprocedure fadeout(fadepal : rgbarray; col1, col2 : byte);πvarπ  lcv,π  lcv2 : integer;π  TPal : rgbarray;πbeginπ  for lcv := col1 to col2 doπ  beginπ    TPal[lcv].red   := 0;π    TPal[lcv].green := 0;π    TPal[lcv].blue  := 0;π  end;π  for lcv := 0 to 63 doπ  beginπ    for lcv2 := col1 to col2 doπ    beginπ      if fadepal[lcv2].red > TPal[lcv2].red thenπ        fadepal[lcv2].red := fadepal[lcv2].red - 1;π      if fadepal[lcv2].green > TPal[lcv2].green thenπ        fadepal[lcv2].green := fadepal[lcv2].green - 1;π      if fadepal[lcv2].blue > TPal[lcv2].blue thenπ        fadepal[lcv2].blue := fadepal[lcv2].blue - 1;ππ      setcolor(lcv2, fadepal[lcv2].red, fadepal[lcv2].green, fadepal[lcv2].blue);π    end;π    refresh;π  end;πend;ππ{*******************************************************************}ππ          19     08-27-9321:25ALL                      ANDRE JAKOBS             Graphic FX Unit          IMPORT              318    ╓º {πI hope you can do something With these listingsπI downloaded from a BBS near me....πThis File contains:  Program VGA3dπ                     Unit DDFigsπ                     Unit DDVarsπ                     Unit DDVideoπ                     Unit DDProcsπJust break it in pieces on the cut here signs......ππif you need some Units or Programs (or TxtFiles) on Programming the Adlib/πSound-Blaster or Roland MPU-401, just let me know, and i see if i can digπup some good listings.....πBut , will your game also have Soundblaster/adlib fm support and SoundπBlaster Digitized Sound support, maybe even MPU/MT32? support....πAnd try to make it as bloody as you can (Heads exploding etc..)(JOKE)ππI hope i you can complete your game (i haven't completed any of my games yet)πAnd i like a copy of it when it's ready......ππPlease leave a message if you received this File.ππ  Andre Jakobsπ    MicroBrain Technologies Inc.π        GelderlandLaan 9π          5691 KL   Son en Breugelπ            The Netherlands............π}πππProgram animatie_van_3d_vector_grafics;ππUsesπ  Crt,π  ddvideo,π  ddfigs,π  ddprocs,π  ddVars;ππVarπ  Opal : paletteType;ππProcedure wireframe(pro : vertex2Array);π{ Teken een lijnen diagram van gesloten voorwerpen met vlakken }πVarπ  i, j, k,π  v1, v2  : Integer;πbeginπ  For i :=  1 to ntf DOπ  beginπ    j := nfac[i];π    if j <> 0 thenπ    beginπ      v1 := faclist[ facfront[j] + size[j] ];π      For k :=  1 to size[j] DOπ      beginπ        v2 := faclist[facfront[j] + k];π        if (v1<v2) or (super[i] <> 0 ) thenπ          linepto(colour[j], pro[v1], pro[v2])π        v1 := v2;π      end;π    end;π  end;πend;ππProcedure hidden(pro : vertex2Array);π{ Display van Objecten als geheel van de projectiepunten van pro }π{ b is een masker voor de kleuren }πVarπ  i,  col : Integer;ππ  Function signe( n : Real) : Integer;π  beginπ    if n >0 thenπ      signe := -1π    elseπ    if n <0 thenπ      signe := 1π    elseπ      signe := 0;π  end;ππ  Function orient(f : Integer; v : vertex2Array) : Integer;π  Varπ    i, ind1,π    ind2, ind3 : Integer;π    dv1, dv2   : vector2;π  beginπ    i := nfac[f];π    if i = 0 thenπ      orient := 0π    elseπ    beginπ      ind1   := faclist[facfront[i] + 1];π      ind2   := faclist[facfront[i] + 2];π      ind3   := faclist[facfront[i] + 3];π      dv1.x  := v[ind2].x - v[ind1].x;π      dv1.y  := v[ind2].y - v[ind1].y;π      dv2.x  := v[ind3].x - v[ind2].x;π      dv2.y  := v[ind3].y - v[ind2].y;π      orient := signe(dv1.x * dv2.y - dv2.x * dv1.y);π    end;π  end;ππ  Procedure facetfill(k : Integer);π  Varπ    v           : vector2Array;π    i, index, j : Integer;π  beginπ    j := nfac[k];π    For i :=  1 to size[j] DOπ    beginπ      index := faclist[facfront[j] + i];π      v[i]  := pro[index];π    end;π    fillpoly(colour[k], size[j], v);π    polydraw(colour[k] - 1, size[j], v);π  end;ππ  Procedure seefacet(k : Integer);π  Varπ    ipt, supk : Integer;π  beginπ    facetfill(k);π    ipt := firstsup[k];π    While ipt <> 0 DOπ    beginπ      supk := facetinfacet[ipt].info;π       facetfill(supk);π      ipt := facetinfacet[ipt].Pointer;π    end;π  end;ππ{ hidden Programmacode }πbeginπ  For i := 1 to nof DOπ  if super[i] = 0 thenπ    if orient(i, pro) = 1 thenπ      seefacet(i);πend;ππProcedure display;πVarπ  i : Integer;πbeginπ  {observe}π  For i := 1 to nov DOπ    transform(act[i], Q, obs[i]);ππ  {project}π  ntv := nov;π  ntf := nof;π  For i := 1 to ntv DOπ  beginπ    pro[i].x := obs[i].x;π    pro[i].y := obs[i].y;π  end;ππ  {drawit}π  switch := switch xor 1;π  hidden(pro);π  Scherm_actief(switch);π  Virscherm_actief(switch xor 1);π  wisscherm(prevpoints, $a000, $8a00);π  wis_hline(prevhline, $8a00);π  prevpoints := points;prevhline := hline;π  points[0]  := 0;π  hline[0]   := 0;πend;ππProcedure anim3d;πVarπ  A, B, C, D, E, F,π  G, H, I, J, QE, P    : matrix4x4;π  zoom, inz, inzplus   : Real;π  angle, angleinc,π  beta, betainc, frame : Integer;π  huidigpalette        : paletteType;ππ  { Kubus Animatie : Roterende kubus }π  Procedure kubus;π  beginπ    angle    := 0;π    angleinc := 9;π    beta     := 0;π    betainc  := 2;π    direct.x := 9;π    direct.y := 2;π    direct.z := -3;π    findQ;π    cubesetup(104);π    frame := 0;ππ    While (NOT (KeyPressed)) and (frame < 91) doπ    beginπ      frame   := frame + 1;π      xyscale := zoom * 2 * sinus(beta);π      rot3(1, trunc(angle/2), Qe);π      rot3(2, angle, P);π      mult3(P, Qe, P);π      cube(P);π      display;π      angle := angle + angleinc;π      beta  := beta + betainc;π      nov   := 0;π    end;π  end;ππ  {Piramides Animatie : Scene opgebouwd uit twee Piramides en 1 Kubus }π  Procedure Piramides;π  beginπ    frame   := 0;π    angle   := 0;π    beta    := 0;π    betainc := 2;π    scale3(4.0, 0.2, 4.0, C);π    cubesetup(90);π    cube(P);ππ    scale3(2.5, 4.0, 2.5, D);π    tran3(2.0, -0.2, 2.0, E);π    mult3(E, D, F);π    pirasetup(34);π    piramid(P);ππ    scale3(2.0, 4.0, 2.0, G);π    tran3(-3.0, -0.2, 0.0, H);π    mult3(H, G, I);π    pirasetup(42);π    piramid(P);ππ    E := Q;π    nov := 0;ππ    While (NOT (KeyPressed)) and (frame < 18) doπ    beginπ      frame   := frame + 1;π      xyscale := zoom * 2 * sinus(beta);ππ      rot3(2, angle, B);ππ      mult3(B, C, P);π      cube(P);ππ      mult3(B, F, P);π      piramid(P);ππ      mult3(B, I, P);π      piramid(P);ππ      display;ππ      angle := angle + angleinc;π      beta  := beta + betainc;π      nov   := 0;π     end;ππ     frame := 0;π     angleinc := 7;ππ     While (NOT (KeyPressed)) and (frame < 75) doπ     beginπ       frame := frame + 1;ππ       rot3(2, angle, B);ππ       mult3(B, C, P);π       cube(P);ππ       mult3(B, F, P);π       piramid(P);ππ       mult3(B, I, P);π       piramid(P);ππ       display;ππ       angle := angle + angleinc;π       nov   := 0;π     end;ππ     frame := 0;π     beta := 180-beta;ππ     While (NOT (KeyPressed)) and (frame < 19) doπ     beginππ       frame := frame + 1;ππ       xyscale := zoom * 2 * sinus(beta);π       rot3(2, angle, B);ππ       mult3(C, B, P);π       cube(P);ππ       mult3(B, F, P);π       piramid(P);ππ       mult3(B, I, P);π       piramid(P);ππ       display;ππ       angle := angle + angleinc;π       beta  := beta  + betainc;π       nov   := 0;π    end;π  end;ππ  { Huis_animatie4 : Figuur huis roteert en "komt uit de lucht vallen" }π  Procedure huisval;π  beginπ    xyscale  := zoom;π    nof      := 0;π    nov      := 0;π    last     := 0;π    angle    := 1355;π    angleinc := -7;π    frame    := 0;ππ    huissetup;ππ    zoom     := 0.02;π    Direct.x := 30;π    direct.y := -2;π    direct.z := 30;π    findQ;ππ    While (NOT (KeyPressed)) and (frame < 40) doπ    beginπ      frame := frame + 1;π      zoom  := zoom + 0.01;π      Scale3(zoom, zoom, zoom, Qe);π      tran3(0, (-7 / zoom) + frame / 1.8, 0, A);π      mult3(Qe, A, C);π      rot3(2, angle, B);π      mult3(C, B, P);π      huis(P);π      display;π      angle := angle + angleinc;π      nov   := 0;π    end;ππ    frame   := 0;π    beta    := angle;π    betainc := angleinc;ππ    While (NOT (KeyPressed)) and (frame < 15) doπ    beginπ      frame := frame + 1;ππ      rot3(2, beta, B);π      mult3(B, Qe, P);π      mult3(P, A, P);π      huis(P);ππ      display;ππ      beta    := beta + betainc;π      betainc := trunc(betainc + (7 / 15));π      nov     := 0;π    end;ππ    frame := 0;ππ    While (NOT (KeyPressed)) and (frame < 30) doπ    beginπ      frame    := frame + 1;π      direct.z := direct.z - (frame * (20 / 70));π      findQ;π      huis(P);π      display;π      nov := 0;π    end;ππ    frame := 0;π    zoom  := 1;ππ    While (NOT (KeyPressed)) and (frame < 31) doπ    beginπ      frame := frame + 1;π      mult3(B, Qe, P);π      scale3(zoom, zoom, zoom, C);π      mult3(P, A, P);π      mult3(P, C, P);π      huis(P);π      display;π      zoom := zoom - 1 / 30;π      nov  := 0;π    end;ππ    zoom := xyscale;π  end;ππ  { Ster Animatie : Roterende ster als kubus met 4 piramides }π  Procedure Sterrot;π  beginπ    xyscale  := zoom;π    frame    := 0;π    angle    := 0;π    angleinc := 9;π    beta     := 0;π    betainc  := 2;π    nof      := 0;π    last     := 0;π    nov      := 0;ππ    stersetup(140);π    scale3(0, 0, 0, P);π    ster(P, 4);ππ    Direct.x := 30;π    direct.y := -2;π    direct.z := 30;π    findQ;π    E := Q;ππ    While (NOT (KeyPressed)) and (frame < 90) doπ    beginπ      frame   := frame + 1;π      xyscale := zoom * 1.7 * sinus(beta);π      rot3(1, Round(angle/5), A);π      mult3(A, E, Q);π      rot3(2, angle, P);π      ster(P, 4);π      display;π      angle := angle + angleinc;π      beta  := beta  + betainc;π      nov   := 0;π    end;π  end;ππbeginπ  eye.x := 0;π  eye.y := 0;π  eye.z :=  0;π  zoom  := xyscale;π  Repeatπ    nov  := 0;π    nof  := 0;π    last := 0;π    Kubus;π    Piramides;π    Huisval;π    Sterrot;π  Until KeyPressed;πend;ππ{ _______________Hoofd Programma --------------------- }ππbeginπ  nov  := 0;π  nof  := 0;π  last := 0;π  start('pira', 15,  Opal);ππ  points[0]     := 0;π  prevpoints[0] := 0;π  hline[0]      := 0;π  prevhline[0]  := 0;ππ  anim3D;ππ  finish(Opal);π  Writeln('Coded by ...... " De Vectorman "');π  Writeln;πend.πππ{ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ }ππUnit ddfigs;ππInterfaceππUsesπ  DDprocs, DDVars;ππConstπ  cubevert : Array [1..8] of vector3 =π    ((x :  1; y :  1; z :  1),π     (x :  1; y : -1; z :  1),π     (x :  1; y : -1; z : -1),π     (x :  1; y :  1; z : -1),π     (x : -1; y :  1; z :  1),π     (x : -1; y : -1; z :  1),π     (x : -1; y : -1; z : -1),π     (x : -1; y :  1; z : -1));ππ  cubefacet : Array [1..6, 1..4] of Integer =π    ((1, 2, 3, 4),π     (1, 4, 8, 5),π     (1, 5, 6, 2),π     (3, 7, 8, 4),π     (2, 6, 7, 3),π     (5, 8, 7, 6));ππ  piravert  : Array [1..5] of vector3 =π    ((x :  0; y :  1; z :  0),π     (x :  1; y :  0; z : -1),π     (x : -1; y :  0; z : -1),π     (x : -1; y :  0; z :  1),π     (x :  1; y :  0; z :  1));ππ  pirafacet : Array [1..5, 1..3] of Integer =π    ((1, 2, 3),π     (1, 3, 4),π     (1, 4, 5),π     (1, 5, 2),π     (5, 4, 3));ππ  huisvert  : Array[1..59] of vector3 =π    ((x : -6; y :  0; z :  4), (x :  6; y : 0; z :  4),π     (x :  6; y :  0; z : -4),π     (x : -6; y :  0; z : -4), (x : -6; y : 8; z :  4), (x :  6; y : 8; z :  4),π     (x :  6; y : 11; z :  0), (x :  6; y : 8; z : -4), (x : -6; y : 8; z : -4),π     (x : -6; y : 11; z :  0), (x : -4; y : 1; z :  4), (x : -1; y : 1; z :  4),π     (x : -1; y :  3; z :  4), (x : -4; y : 3; z :  4), (x : -4; y : 5; z :  4),π     (x : -1; y :  5; z :  4), (x : -1; y : 7; z :  4), (x : -4; y : 7; z :  4),π     (x :  0; y :  0; z :  4), (x :  5; y : 0; z :  4), (x :  5; y : 4; z :  4),π     (x :  0; y :  4; z :  4), (x :  1; y : 5; z :  4), (x :  4; y : 5; z :  4),π     (x :  4; y :  7; z :  4), (x :  1; y : 7; z :  4), (x :  6; y : 5; z : -1),π     (x :  6; y :  5; z : -3), (x :  6; y : 7; z : -3), (x :  6; y : 7; z : -1),π     (x :  5; y :  1; z : -4), (x :  2; y : 1; z : -4), (x :  2; y : 3; z : -4),π     (x :  5; y :  3; z : -4), (x :  5; y : 5; z : -4), (x :  2; y : 5; z : -4),π     (x :  2; y :  7; z : -4), (x :  5; y : 7; z : -4), (x :  1; y : 0; z : -4),π     (x : -1; y :  0; z : -4), (x : -1; y : 3; z : -4), (x :  0; y : 4; z : -4),π     (x :  1; y :  3; z : -4), (x : -2; y : 1; z : -4), (x : -5; y : 1; z : -4),π     (x : -5; y :  3; z : -4), (x : -2; y : 3; z : -4), (x : -2; y : 5; z : -4),π     (x : -5; y :  5; z : -4), (x : -5; y : 7; z : -4), (x : -2; y : 7; z : -4),π     (x : -6; y :  0; z :  1), (x : -6; y : 0; z :  3), (x : -6; y : 3; z :  3),π     (x : -6; y :  3; z :  1), (x : -6; y : 5; z :  1), (x : -6; y : 5; z :  3),π     (x : -6; y :  7; z :  3), (x : -6; y : 7; z :  1));ππ  huissize  : Array [1..19] of Integer =π    (4, 4, 5, 4, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4);ππ  huissuper : Array [1..19] of Integer =π    (0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3, 4, 4, 4, 4, 4, 6, 6);ππ  huisfacet : Array [1..79] of Integer =π    ( 1,  2,  6,  5,π      5,  6,  7, 10,π      2,  3,  8,  7,π      6,  3,  4,  9,π      8,  8,  9, 10,π      7,  4,  1,  5,π     10,  9,  4,  3,π      2,  1, 11, 12,π     13, 14, 15, 16,π     17, 18, 19, 20,π     21, 22, 23, 24,π     25, 26, 27, 28,π     29, 30, 31, 32,π     33, 34, 35, 36,π     37, 38, 39, 40,π     41, 42, 43, 44,π     45, 46, 47, 48,π     49, 50, 51, 52,π     53, 54, 55, 56,π     57, 58, 59);ππ  stervert : Array [1..6] of vector3 =π    ((x :  1; y :  0; z :  0),π     (x :  0; y :  1; z :  0),π     (x :  0; y :  0; z :  1),π     (x :  0; y :  0; z : -1),π     (x :  0; y : -1; z :  0),π     (x : -1; y :  0; z :  0));ππProcedure cubesetup(c : Integer);πProcedure cube(P : matrix4x4);πProcedure pirasetup(c : Integer);πProcedure piramid(P : matrix4x4);πProcedure huissetup;πProcedure huis(P : matrix4x4);πProcedure hollow(P1 : matrix4x4);πProcedure stersetup(col : Integer);πProcedure ster(P : matrix4x4; d : Real);πProcedure ellips(P : matrix4x4; col : Integer);πProcedure goblet(P : matrix4x4; col : Integer);ππImplementationππProcedure cubesetup(c : Integer);π{ zet kubusdata in facetlist van de scene}πVarπ  i, j : Integer;πbeginπ  For i :=  1 to 6 DOπ  beginπ    For j := 1 to 4 DOπ      faclist[last + j] := cubefacet[i, j] + nov;π    nof := nof + 1;π    facfront[nof] := last;π    colour[nof]   := c;π    nfac[nof]     := nof;π    super[nof]    := 0;π    firstsup[nof] := 0;π    size[nof]     := 4;π    last := last + size[nof];π  end;πend;ππProcedure cube(P : matrix4x4);πVarπ  i, j : Integer;πbeginπ  For i :=  1 to 8 DOπ  beginπ    nov := nov + 1;π    transform(cubevert[i], P, act[nov]);π  end;πend;ππProcedure pirasetup(c : Integer);πVarπ  i, j : Integer;πbeginπ  For i :=  1 to 5 DOπ  beginπ    For j := 1 to 3 DOπ      faclist[last + j] := pirafacet[i, j] + nov;π    nof := nof + 1;π    facfront[nof] := last;π    size[nof]     := 3;π    last          := last + size[nof];π    colour[nof]   := c;π    nfac[nof]     := nof;π    super[nof]    := 0;π    firstsup[nof] := 0;π  end;ππ  size[nof] := 4;π  faclist[facfront[nof] + 4] := 2 + nov;π  last := last + 1;πend;ππProcedure piramid(P : matrix4x4);πVarπ  i, j : Integer;πbeginπ  For i :=  1 to 5 DOπ  beginπ    nov := nov + 1;π    transform(piravert[i], P, act[nov]);π  end;πend;πππProcedure huissetup;πVarπ  i, j,π  host,π  nofstore : Integer;πbeginπ  For i := 1 to 79 DOπ    faclist[last + i] := huisfacet[i] + nov;ππ  nofstore := nof;ππ  For i := 1 to 19 DOπ  beginπ    nof           := nof + 1;π    facfront[nof] := last;π    size[nof]     := huissize[i];π    last          := last + size[nof];π    nfac[nof]     := nof;ππ    if (i = 2) or (i = 5) thenπ      colour[nof] := 111π    elseπ    if i = 7 thenπ      colour[nof] := 20π    elseπ    if i < 8 thenπ      colour[nof] := 42π    elseπ      colour[nof] := 25;ππ    super[nof] := huissuper[i];π    firstsup[nof] := 0;ππ    if super[nof] <> 0 thenπ    beginπ      host := super[nof] + nofstore;π      super[nof] := host;π      pushfacet(firstsup[host], nof);π    end;π  end;π  For i  :=  1 to 59 DOπ    setup[i] := huisvert[i];πend;ππProcedure huis(P : matrix4x4);πVarπ  i : Integer;πbeginπ  For i := 1 to 59 DOπ  beginπ    nov := nov + 1;π    transform(setup[i], P, act[nov]);π  end;πend;πππProcedure hollow(P1 : matrix4x4);πVarπ  A, B,π  P, P2 : matrix4x4;π  i     : Integer;πbeginπ  For i := 1 to 8 DOπ  beginπ    tran3(4.0 * cubevert[i].x, 4.0 * cubevert[i].y, 4.0 * cubevert[i].z, P2);π    mult3(P1, P2, P);π    cube(P);π  end;ππ  For i := 1 to 4 DOπ  beginπ    scale3(3.0, 1.0, 1.0, A);π    tran3(0.0, 4.0 * cubevert[i].y, 4.0 * cubevert[i].z, B);π    mult3(A, B, P2);mult3(P1, P2, P);π    cube(P);π    scale3(1.0, 3.0, 1.0, A);π    tran3(4.0 * cubevert[i].y, 0.0, 4.0 * cubevert[i].z, B);π    mult3(A, B, P2);mult3(P1, P2, P);π    cube(P);π    scale3(1.0, 1.0, 3.0, A);π    tran3(4.0 * cubevert[i].z, 4.0 * cubevert[i].y, 0.0, B);π    mult3(A, B, P2);mult3(P1, P2, P);π    cube(P);π  end;πend;ππProcedure stersetup(col : Integer);πVarπ  i, j,π  v1, v2 : Integer;πbeginπ  For i := 1 to 6 DOπ  beginπ    v1 := cubefacet[i, 4] + nov;π    For j := 1 to 4 DOπ    beginπ      v2  := cubefacet[i, j] + nov;π      nof := nof + 1;π      faclist[last + 1] := v1;π      faclist[last + 2] := v2;π      faclist[last + 3] := nov + 8 + i;π      facfront[nof]     := last;π      size[nof] := 3;ππ      last := last + size[nof];π      colour[nof] := col;π      nfac[nof]   := nof;π      super[nof]  := 0;π      firstsup[nof] := 0;π      v1 := v2;π    end;π  end;πend;ππProcedure ster(P : matrix4x4; d : Real);πVarπ  i, j,π  v1, v2 : Integer;π  A, S   : matrix4x4;πbeginπ  For i :=  1 to 8 DOπ  beginπ    nov := nov + 1;π    transform(cubevert[i], P, act[nov]);π  end;ππ  scale3(D, D, D, A);π  mult3(A, P, S);ππ  For i := 1 to 6 DOπ  beginπ    nov := nov + 1;π    transform(stervert[i], S, act[nov]);π  end;πend;ππProcedure ellips(P : matrix4x4; col : Integer);πVarπ  v : vector2Array;π  theta,π  thetadiff,π  i : Integer;πbeginπ  theta := -90;π  thetadiff := -9;π  For i :=  1 to 21 DOπ  beginπ    v[i].x := cosin(theta);π    v[i].y := sinus(theta);π    theta  := theta + thetadiff;π  end;π  bodyofrev(P, col, 21, 20, v);πend;ππProcedure goblet(P : matrix4x4; col : Integer);πConstπ  gobletdat : Array [1..12] of vector2 =π    ((x :  0; y : -16),π     (x :  8; y : -16),π     (x :  8; y : -15),π     (x :  1; y : -15),π     (x :  1; y :  -2),π     (x :  6; y :  -1),π     (x :  8; y :   2),π     (x : 14; y :  14),π     (x : 13; y :  14),π     (x :  7; y :   2),π     (x :  5; y :   0),π     (x :  0; y :   0));ππVarπ  gobl : vector2Array;π  i    : Integer;πbeginπ  For i := 1 to 12 DOπ    gobl[i] := gobletdat[i];π  bodyofrev(P, col, 12, 20, gobl)πend;ππbegin;πend.πππ{ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ }ππUnit ddprocs;ππInterfaceππUsesπ  DDVars;ππConstπ  maxv = 200;π  maxf = 400;π  maxlist = 1000;π  vectorArraysize  = 32;π  sizeofpixelArray = 3200;π  sizeofhlineArray = 320 * 4;ππTypeπ  vector2      = Record x, y : Real; end;π  vector3      = Record x, y, z : Real; end;π  pixelvector  = Record x, y : Integer; end;π  pixelArray   = Array [0..sizeofpixelArray] of Integer;π  hlineArray   = Array [0..sizeofhlineArray] of Integer;π  vector3Array = Array [1..vectorArraysize] of vector3;π  matrix3x3    = Array [1..3, 1..3] of Real;π  matrix4x4    = Array [1..4, 1..4] of Real;π  vertex3Array = Array [1..maxv] of vector3;π  vertex2Array = Array [1..maxv] of vector2;π  vector2Array = Array [1..vectorArraysize ] of vector2;π  facetArray   = Array [1..maxf] of Integer;π  facetlist    = Array [1..maxlist] of Integer;ππConstπ  EenheidsM : matrix4x4 =π    ((1, 0, 0, 0),π     (0, 1, 0, 0),π     (0, 0, 1, 0),π     (0, 0, 0, 1));πVarπ  Q           : matrix4x4;π  eye, direct : vector3;π  nov, ntv,π  ntf, nof,π  last        : Integer;π  setup,π  act, obs    : vertex3Array;π  pro         : vertex2Array;π  faclist     : facetlist;π  colour,π  size,π  facfront,π  nfac,π  super,π  firstsup    : facetArray;π  points,π  prevpoints  : pixelArray;π  hline,π  prevhline   : hlineArray;ππProcedure tran3(tx, ty, tz : Real; Var A : matrix4x4);πProcedure scale3(sx, sy, sz : Real; Var A : matrix4x4);πProcedure rot3(m : Integer; theta : Integer; Var A : matrix4x4);πProcedure mult3(A, B : matrix4x4; Var C : matrix4x4);πProcedure findQ;πProcedure genrot(phi : Integer; b, d : vector3; Var A : matrix4x4);πProcedure transform(v : vector3; A : matrix4x4; Var w : vector3);πProcedure extrude(P : matrix4x4; d : Real; col, n : Integer;π                  v : vector2Array);πProcedure bodyofrev(P : matrix4x4; col, nvert, nhoriz : Integer;π                    v : vector2Array);πProcedure polydraw(c, n : Integer; poly : vector2Array);πProcedure linepto(c : Integer; pt1, pt2 : vector2);πProcedure WisScherm(punten : pixelArray; SchermSeg, VirSeg : Word);πProcedure fillpoly(c, n : Integer; poly : vector2Array);πProcedure Wis_Hline(hline_ar : hlineArray; virseg : Word);ππImplementationππProcedure tran3(tx, ty, tz : Real; Var A : matrix4x4);π{ zet matrix A op punt tx, ty, tz }πbeginπ  A := EenheidsM;π  A[1, 4] := -tx;π  A[2, 4] := -ty;π  A[3, 4] := -tz;πend;ππProcedure scale3(sx, sy, sz : Real; Var A : matrix4x4);π{ zet matrix A om in schaal van sx, sy, sz }πbeginπ  A := EenheidsM;π  A[1, 1] := sx;π  A[2, 2] := sy;π  A[3, 3] := sz;πend;ππProcedure rot3(m : Integer; theta : Integer; Var A : matrix4x4);π{ roteer matrix A om m: 1=x-as; 2=y-as; 3=z-as met hoek theta (in graden)}πVarπ  m1, m2 : Integer;π  c, s   : Real;πbeginπ  A  := EenheidsM;π  m1 := (m MOD 3) + 1;π  m2 := (m1 MOD 3) + 1;π  c  := cosin(theta);π  s  := sinus(theta);π  A[m1, m1] := c;π  A[m2, m2] := c;π  A[m1, m2] := s;π  A[m2, m1] := -s;πend;ππProcedure mult3(A, B : matrix4x4; Var C : matrix4x4);π{ vermenigvuldigd matrix A en B naar matrix C }πVarπ  i, j, k : Integer;π  ab      : Real;πbeginπ  For i := 1 to 4 doπ    For j :=  1 to 4 doπ    beginπ      ab := 0;π      For k := 1 to 4 doπ        ab := ab + A[i, k] * B[k, j];π      C[i, j] := ab;π    end;πend;ππProcedure findQ;π{ Bereken de Observatie-matrix 'Q' voor een punt in de ruimte }πVarπ  E, F, G,π  H, U    : matrix4x4;π  alpha,π  beta,π  gamma   : Integer;π  v, w    : Real;πbeginπ  tran3(eye.x, eye.y, eye.z, F);ππ  alpha := angle(-direct.x, -direct.y);π  rot3(3, alpha, G);ππ  v :=  sqrt( (direct.x * direct.x) + (direct.y * direct.y));π  beta := angle(-direct.z, v);π  rot3(2, beta, H);ππ  w :=  sqrt( (v * v) + (direct.z * direct.z));π  gamma := angle( -direct.x * w,  direct.y * direct.z);π  rot3(3, gamma, U);ππ  mult3(G, F, Q);π  mult3(H, Q, E);π  mult3(U, E, Q);πend;ππProcedure genrot (phi : Integer; b, d : vector3; Var A : matrix4x4);πVarπ  F, G, H,π  W, FI, GI,π  HI, S, T  : matrix4x4;π  v         : Real;π  beta,π  theta     : Integer;πbeginπ  tran3(b.x, b.y, b.z, F);π  tran3(-b.x, -b.y, -b.z, FI);π  theta := angle(d.x, d.y);π  rot3(3, theta, G);π  rot3(3, -theta, GI);π  v := sqrt(d.x * d.x + d.y * d.y);π  beta := angle(d.z, v);π  rot3(2, beta, H);π  rot3(2, -beta, HI);π  rot3(2, beta, H);π  rot3(2, -beta, HI);π  rot3(3, phi, W);π  mult3(G, F, S);π  mult3(H, S, T);π  mult3(W, S, T);π  mult3(HI, S, T);π  mult3(GI, T, S);π  mult3(FI, S, A);πend;ππProcedure transform(v : vector3; A : matrix4x4; Var w : vector3);π{ transformeer colomvector 'v' uit A in colomvector 'w'}πbeginπ  w.x := A[1, 1] * v.x + A[1, 2] * v.y + A[1, 3] * v.z + A[1, 4];π  w.y := A[2, 1] * v.x + A[2, 2] * v.y + A[2, 3] * v.z + A[2, 4];π  w.z := A[3, 1] * v.x + A[3, 2] * v.y + A[3, 3] * v.z + A[3, 4];πend;ππProcedure extrude(P : matrix4x4; d : Real; col, n : Integer;π                  v : vector2Array);π{ Maakt van een 2d-figuur een 3d-figuur }π{ vb: converteert 2d-letters naar 3d-letters }πVarπ  i, j,π  lasti : Integer;π  v3    : vector3;πbeginπ  For i := 1 to n DOπ  beginπ    faclist[last + i] := nov + i;π    faclist[last + n + i] := nov + 2 * n + 1 - i;π  end;π  facfront[nof + 1] := last;π  facfront[nof + 2] := last + n;π  size[nof + 1] := n;π  size[nof + 2] := n;π  nfac[nof + 1] := nof + 1;π  nfac[nof + 2] := nof + 2;π  super[nof + 1] := 0;π  super[nof + 2] := 0;π  firstsup[nof + 1] := 0;π  firstsup[nof + 2] := 0;π  colour[nof + 1] := col;π  colour[nof + 2] := col;π  last  := last + 2 * n;π  nof   := nof + 2;π  lasti := n;ππ  For i := 1 to n DOπ  beginπ    faclist[last + 1] := nov + i;π    faclist[last + 2] := nov + lasti;π    faclist[last + 3] := nov + n + lasti;π    faclist[last + 4] := nov + n + i;π    nof := nof + 1 ;π    facfront[nof] := last;π    size[nof]     := 4;π    nfac[nof]     := nof;π    super[nof]    := 0;π    firstsup[nof] := 0;π    colour[nof]   := col;π    last  := last + 4;π    lasti := i;π  end;π  For i :=  1 To n DOπ  beginπ    v3.x := v[i].x;π    v3.y := v[i].y;π    v3.z := 0.0;π    nov  := nov + 1;π    transform(v3, P, act[nov]);π    v3.z := -d;π    transform(v3, P, act[nov + n]);π  end;π  nov := nov + n;πend;ππProcedure bodyofrev(P : matrix4x4; col, nvert, nhoriz : Integer;π                    v : vector2Array);π{ maakt een "rond" figuur van een 2-dimensionale omlijning van het figuur }πVarπ  theta,π  thetadiff,π  i, j, newnov : Integer;π  c, s         : Array [1 .. 100] of Real;π  index1,π  index2       : Array [1 .. 101] of Integer;πbeginπ  theta := 0;π  thetadiff := trunc(360 / nhoriz);ππ  For i := 1 to nhoriz DOπ  beginπ    c[i]  := cosin(theta);π    s[i]  := sinus(theta);π    theta := theta + thetadiff;π  end;π  newnov := nov;ππ  if abs(v[1].x) < epsilon  thenπ  beginπ    newnov := newnov + 1;π    setup[newnov].x := 0.0;π    setup[newnov].y := v[1].y;π    setup[newnov].z := 0.0;π    For i := 1 to nhoriz + 1 DOπ      index1[i] := newnov;π  endπ  elseπ  beginπ    For i := 1 to nhoriz DOπ    beginπ      newnov := newnov + 1;π      setup[newnov].x := v[1].x * c[i];π      setup[newnov].y := v[1].y;π      setup[newnov].z := -v[1].x * s[i];π      index1[i] := newnov;π    end;π    index1[nhoriz + 1] := index1[i];π  end;ππ  For j :=  2 to nvert DOπ  beginπ    if abs(v[j].x) < epsilon thenπ    beginπ      newnov := newnov + 1;π      setup[newnov].x := 0.0;π      setup[newnov].y := v[j].y;π      setup[newnov].z := 0.0;π      For i := 1 to nhoriz + 1 DOπ        index2[i] := newnov;π    endπ    elseπ    beginπ      For i := 1 To nhoriz DOπ      beginπ        newnov := newnov + 1;π        setup[newnov].x :=  v[j].x * c[i];π        setup[newnov].y :=  v[j].y;π        setup[newnov].z := -v[j].x * s[i];π        index2[i] := newnov;π      end;π      index2[nhoriz + 1] := index2[1];π    end;ππ    if index1[1] <> index1[2] thenπ      if index2[1] = index2[2] thenπ      beginπ        For i := 1 to nhoriz DOπ        beginπ          nof := nof + 1; size[nof] := 3;π          facfront[nof] := last;π          faclist[last + 1] := index1[i + 1];π          faclist[last + 2] := index2[i];π          faclist[last + 3] := index1[i];π          last := last + size[nof];π          nfac[nof]     := nof;π          colour[nof]   := col;π          super[nof]    := 0;π          firstsup[nof] := 0;π        end;π      endπ      elseπ      beginπ        For i := 1 to nhoriz DOπ        beginπ          nof := nof + 1;π          size[nof] := 4;π          facfront[nof] := last;π          faclist[last + 1] := index1[i + 1];π          faclist[last + 2] := index2[i + 2];π          faclist[last + 3] := index2[i];π          faclist[last + 4] := index1[i];π          last := last + size[nof];π          nfac[nof]     := nof;π          colour[nof]   := col;π          super[nof]    := 0;π          firstsup[nof] := 0;π        end;π      endπ      elseπ      if index2[1] <> index2[2] thenπ        For i := 1 to nhoriz DOπ        beginπ          nof := nof + 1;π          size[nof] := 3;π          facfront[nof] := last;π          faclist[last + 1] := index2[i + 1];π          faclist[last + 2] := index2[i];π          faclist[last + 3] := index1[i];π          last := last + size[nof];π          nfac[nof]     := nof;π          colour[nof]   := col;π          super[nof]    := 0;π          firstsup[nof] := 0;π        end;ππ        For i :=  1 to nhoriz + 1 DOπ          index1[i] := index2[i];π  end;ππ  For i :=  nov + 1 to newnov DOπ    transform(setup[i], P, act[i]);ππ  nov := newnov;ππend;ππProcedure BressenHam( Virseg : Word;          { Adres-> VIRSEG:0 }π                      pnts   : pixelArray;π                      c      : Byte;          { c->     kleur    }π                      p1, p2 : pixelvector);  { vector           } Assembler;πVarπ  x, y, error,π  s1,  s2,π  deltax,π  deltay, i   : Integer;π  interchange : Boolean;π  dcolor      : Word;πAsmπ{  initialize Variables  }π  PUSH   dsπ  LDS    si, pntsπ  MOV    ax, virsegπ  MOV    es, axπ  MOV    cx, 320π  MOV    ax, p1.xπ  MOV    x,  axπ  MOV    ax, p1.yπ  MOV    y, axπ  MOV    dcolor, axππ  MOV    ax, p2.x                { deltax := abs(x2 - x1) }π  SUB    ax, p1.x                { s1 := sign(x2 - x1) }π  PUSH   axπ  PUSH   axπ  CALL   ddVars.signπ  MOV    s1, ax;π  POP    axπ  TEST   ax, $8000π  JZ     @@GeenSIGN1π  NEG    axπ @@GeenSign1:π  MOV    deltax, axπ  MOV    ax, p2.yπ  SUB    ax, p1.yπ  PUSH   axπ  PUSH   axπ  CALL   ddVars.signπ  MOV    s2, axπ  POP    axπ  TEST   ax, $8000π  JZ     @@GeenSign2π  NEG    axπ @@GeenSign2:π  MOV    deltay, axππ { Interchange DeltaX and DeltaY depending on the slope of the line }ππ  MOV    interchange, Falseπ  CMP    ax, deltaxπ  JNG    @@NO_INTERCHANGEπ  XCHG   ax, deltaxπ  XCHG   ax, deltayπ  MOV    interchange, Trueππ @@NO_INTERCHANGE:ππ  { Initialize the error term to compensate For a nonzero intercept }ππ  MOV    ax, deltaYπ  SHL    ax, 1π  SUB    ax, deltaXπ  MOV    error, axππ  { Main loop }π  MOV    ax, 1π  MOV    i, axπ @@FOR_begin:π  CMP    ax, deltaXπ  JG     @@EINDE_FOR_LOOPππ  { Plot punt! }π  MOV   bx, xπ  MOV   ax, yπ  MUL   cxπ  ADD   bx, axπ  MOV   al, cπ  MOV   Byte PTR [es:bx], alπ  INC   [Word ptr ds:si]     { aantal verhogen }π  MOV   ax, [si]π  SHL   ax, 1                { offset berekenen }π  PUSH  siπ  ADD   si, axπ  MOV   [si], bxπ  POP   siππ  { While Loop }π @@W1_begin:π  CMP    error, 0π  JL     @@EINDE_WHILEππ  { if interchange then }ππ  CMP    interchange, Trueπ  JE     @@i_is_tπ  MOV    ax, s2π  ADD    y, axπ  JMP    @@w1_eruitππ @@i_is_t:π  MOV    ax, s1π  ADD    x, axππ @@w1_eruit:π  MOV    ax, deltaxπ  SHL    ax, 1π  SUB    error, axπ  JMP    @@w1_beginππ @@EINDE_WHILE:π  CMP    interchange, Trueπ  JE     @@i_is_t_1π  MOV    ax, s1π  ADD    x, axπ  JMP    @@if_2_eruitππ @@i_is_t_1:π  MOV    ax, s2π  ADD    y, axππ @@if_2_eruit:π  MOV    ax, deltayπ  SHL    ax, 1π  ADD    error, axπ  INC    iπ  MOV    ax, iπ  JMP    @@FOR_beginπ @@Einde_for_loop:π  POP    dsπend;ππProcedure linepto(c : Integer; pt1, pt2 : vector2);πVarπ  p1, p2 : pixelvector;πbeginπ  p1.x := fx(pt1.x);π  p1.y := fy(pt1.y);π  p2.x := fx(pt2.x);π  p2.y := fy(pt2.y);π  BressenHam($a000, points, c,  p1,  p2);πend;ππProcedure WisScherm(punten : pixelArray; SchermSeg , Virseg : Word); Assembler;πAsmπ  PUSH      dsπ  MOV       ax, SchermSegπ  MOV       es, axπ  LDS       bx, puntenπ  MOV       cx, [bx]π  JCXZ      @@NietTekenenπ @@Wis:π  INC       bxπ  INC       bxπ  MOV       si, [bx]π  MOV       di, siπ  PUSH      dsπ  MOV       ax, virsegπ  MOV       ds, axπ  MOVSBπ  POP       dsπ  LOOP      @@Wisπ @@NietTekenen:π  POP       dsπend;ππProcedure polydraw(c, n : Integer; poly : vector2Array);πVarπ  i : Integer;πbeginπ  For i :=  1 to n - 1 doπ    linepto(c, poly[i], poly[i + 1]);π  linepto(c, poly[n], poly[1]);πend;ππProcedure fillpoly(c, n : Integer; poly : vector2Array);πVarπ  scan_table : tabel;π  scanline,π  line,π  offsetx    : Integer;ππ  Procedure Draw_horiz_line(hline_ar  : hlineArray;π                            color     : Byte;π                            lijn      : Word;π                            begin_p   : Word;π                            linelen   : Word); Assembler;π  Asmπ    PUSH  dsπ    MOV   cx, 320π    MOV   ax, 0a000hπ    MOV   es, axπ    MOV   di, begin_pπ    MOV   ax, lijnπ    MUL   cxπ    ADD   di, axπ    PUSH  diπ    MOV   al, colorπ    MOV   cx, linelenπ    PUSH  cxπ    REP   STOSBπ    LDS   si, hline_arπ    INC   [Word ptr ds:si]π    MOV   ax, [si]π    SHL   ax, 1π    SHL   ax, 1π    ADD   si, axπ    POP   bxπ    POP   dxπ    MOV   [si], dxπ    MOV   [si + 2], bxπ    POP   dsπ  end;ππ  Procedure swap(Var x, y : Integer);π  beginπ    x := x + y;π    y := x - y;π    x := x - y;π  end;ππ{πProcedure Calc_x(x1, y1, x2, y2 : Word; Var scan_table : tabel);πVarπ  m_inv,π  xReal : Real;πbeginπ  Asmπ    LDS     dx, scan_tableπ    MOV     ax, y1π    MOV     bx, y2π    CMP     ax, bxπ    JNE     @@NotHorizLineπ    MOV     bx, x1π    SHL     ax, 1π    ADD     ax, dxπ    CMP     bx, [dx]π    JGE     @@Notstorexminπ    MOV     [dx], bxππ   @@Notstorexmin:π    INC     dxπ    MOV     bx, x2π    CMP     bx, [dx]π    JLE     @@Klaarπ    MOV     [dx], bxπ    JMP     @@Klaarππ   @@NotHorizLine:π}ππ  Procedure Calc_x(x1, y1, x2, y2 : Integer; Var scan_table : tabel);π  Varπ    m_inv, xReal : Real;π    i, y, temp   : Integer;π  beginπ    if y1 = y2 thenπ    beginπ      if x2 < x1 thenπ        swap(x1, x2)π      elseπ      beginπ        if x1 < scan_table[y1].xmin thenπ          scan_table[y1].xmin := x1;π        if x2 > scan_table[y2].xmax thenπ          scan_table[y2].xmax := x2;π      end;π    endπ    elseπ    beginπ      m_inv := (x2 - x1) / (y2 - y1);ππ      if y1 > y2 then {swap}π      beginπ        swap(y1, y2);π        swap(x1, x2);π      end;ππ      if x1 < scan_table[y1].xmin thenπ        scan_table[y1].xmin := x1;π      if x2 > scan_table[y2].xmax thenπ        scan_table[y2].xmax := x2;π      xReal := x1; y := y1;ππ      While y < y2 doπ      beginπ        y := y + 1;π        xReal := xReal + m_inv;π        offsetx := round(xReal);π        if xReal < scan_table[y].xmin thenπ          scan_table[y].xmin := offsetx;π        if xReal > scan_table[y].xmax thenπ          scan_table[y].xmax := offsetx;π      end;π    end;π  end;ππbeginπ  scan_table := emptytabel;π  For line := 1 to n - 1 doπ    calc_x(fx(poly[line].x), fy(poly[line].y),π           fx(poly[line + 1].x), fy(poly[line + 1].y), scan_table);ππ  calc_x(fx(poly[n].x), fy(poly[n].y),π         fx(poly[1].x), fy(poly[1].y), scan_table);ππ  scanline := 0;ππ  While scanline < nypix - 1 doπ  beginπ    With Scan_table[scanline] DOπ      if xmax > xmin thenπ        draw_horiz_line(hline, c,  scanline,  xmin,  xmax - xmin + 1);π      scanline := scanline + 1;π  end;πend;ππProcedure  Wis_Hline(hline_ar : hlineArray; virseg : Word); Assembler;πAsmπ  PUSH      dsπ  MOV       ax, 0a000hπ  MOV       es, axπ  LDS       bx, hline_arπ  MOV       cx, [bx]π  JCXZ      @@Niet_tekenenπ  ADD       bx, 4π @@Wis:π  XCHG      cx, dxπ  MOV       si, [bx]π  MOV       cx, [bx + 2]π  MOV       di, siπ  PUSH      dsπ  MOV       ax, virsegπ  MOV       ds, axπ  CLDπ  REP       MOVSBπ  POP       dsπ  XCHG      cx, dxπ  ADD       bx, 4π  LOOP      @@Wisπ @@Niet_tekenen:π  POP       dsπend;ππbeginπend.πππ{ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ }ππUnitπ  ddVars;ππInterfaceππConstπ  pi      = 3.1415926535;π  epsilon = 0.000001;π  rad     = pi / 180;π  nxpix   = 320; { scherm resolutie }π  nypix   = 200;π  maxfinf = 200;ππTypeπ  xmaxymax  = Record xmin, xmax : Integer; end;π  facetinfo = Record info, Pointer : Integer; end;π  tabel     = Array [1..nypix - 1] of xmaxymax;π  sincos    = Array [0..359] of Real;ππVarπ  sinusArray   : sincos;π  cosinusArray : sincos;π  facetinfacet : Array [1..maxfinf] of facetinfo;π  facetfree    : Integer;π  xyscale      : Real;π  emptytabel   : tabel;ππFunction  fx(x : Real) : Integer;πFunction  fy(y : Real) : Integer;πFunction  Sign(I : Integer) : Integer;πFunction  macht(a, n : Real) : Real;πFunction  angle(x, y : Real) : Integer;πFunction  sinus(hoek : Integer) : Real;πFunction  cosin(hoek : Integer) : Real;πProcedure pushfacet(Var stackname : Integer; value : Integer);ππImplementationππFunction fx(x : Real) : Integer;πbeginπ  fx := nxpix - trunc(x * xyscale + nxpix * 0.5 - 0.5);πend;ππFunction fy(y : Real) : Integer;πbeginπ  fy := nypix - trunc(y * xyscale + nypix * 0.5 - 0.5);πend;ππFunction Sign(I : Integer) : Integer; Assembler;πAsmπ  MOV  ax, iπ  CMP  ax, 0π  JGE  @@Zero_or_oneπ  MOV  ax, -1π  JMP  @@Exitππ @@Zero_or_One:π  JE   @@Nulπ  MOV  ax, 1π  JMP  @@Exitππ @@Nul:π  xor  ax, axππ @@Exit:πend;ππFunction macht(a, n : Real) : Real;πbeginπ  if a > 0 thenπ    macht :=  exp(n * (ln(a)))π  elseπ  if a < 0 thenπ    macht := -exp(n * (ln(-a)))π  elseπ    macht := a;πend;ππFunction angle(x, y : Real) : Integer;πbeginπ  if abs(x) < epsilon thenπ    if abs(y) < epsilon thenπ      angle := 0π    elseπ    if y > 0.0 thenπ      angle := 90π    elseπ      angle := 270π  elseπ  if x < 0.0 thenπ    angle := round(arctan(y / x) / rad) + 180π  elseπ    angle := round(arctan(y / x) / rad);πend;ππFunction sinus(hoek : Integer) : Real;πbeginπ  hoek  := hoek mod 360;π  sinus := sinusArray[hoek];πend;ππFunction cosin(hoek : Integer) : Real;πbeginπ  hoek  := hoek mod 360 ;π  cosin := cosinusArray[hoek];πend;ππProcedure pushfacet(Var stackname : Integer; value : Integer);πVarπ  location : Integer;πbeginπ  if facetfree = 0 thenπ  beginπ    Write('Cannot hold more facets');π    HALT;π  endπ  elseπ  beginπ    location  := facetfree;π    facetfree := facetinfacet[facetfree].Pointer;π    facetinfacet[location].info := value;π    facetinfacet[location].Pointer := stackname;π    stackname := location;π  end;πend;ππVarπ  i : Integer;πbeginπ  { vul sinus- en cosinusArray met waarden }π  For i := 0 to 359 DOπ  beginπ    sinusArray[i]   := sin(i * rad);π    cosinusArray[i] := cos(i * rad);π  end;π  { Init facetinfacet }π  facetfree := 1;π  For i :=  1 to maxfinf - 1 DOπ    facetinfacet[i].Pointer := i + 1;ππ  facetinfacet[maxfinf].Pointer := 0;ππ  { Init EmptyTabel }π  For i := 0 to nypix - 1 DOπ  beginπ    Emptytabel[i].xmin := 319;π    Emptytabel[i].xmax := 0;π  end;πend.πππ{ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ }ππUnit ddvideo;ππInterfaceππUsesπ  Dos, DDVars;ππTypeπ  schermPointer = ^schermType;π  schermType    = Array [0..nypix - 1, 0..nxpix - 1] of Byte;π  color         = Record  R, G, B : Byte; end;π  paletteType   = Array [0..255] of color;π  WordArray     = Array [0..3] of Word;π  palFile       = File of paletteType;π  picFile       = File of schermType;ππVarπ  scherm    : schermType Absolute $8A00 : $0000;π  schermptr : schermPointer;π  switch    : Integer;ππProcedure start(Filenaam : String; horiz : Real; Var Oldpal : paletteType);πProcedure finish(Oldpal : paletteType);πProcedure VirScherm_actief(switch : Word);πProcedure Scherm_actief(switch : Word);ππImplementationππProcedure Virscherm_actief(switch : Word); Assembler;πAsmπ  MOV     dx, 3cchπ  MOV     cx, switchπ  JCXZ    @@volgendeπ  in      al, dx             { switch=1 }π  and     al, 0dfhπ  MOV     dx, 3c2hπ  OUT     dx, al             { set even mode }π  JMP     @@Klaarππ @@Volgende:π  in      al, dx             { switch=0 }π  or      al, 20hπ  MOV     dx, 3c2hπ  OUT     dx, al             { set odd mode }ππ @@Klaar:π  MOV     dx, 3dah           { Wacht op Vert-retrace }π  in      al, dx             { Zodat virscherm = invisible }π  TEST    al, 08hπ  JZ      @@Klaarπend;ππProcedure Scherm_actief(switch : Word);πbeginπ  Asmπ   @@Wacht:π    MOV  dx, 3dahπ    in   al, dxπ    TEST al, 01hπ    JNZ  @@Wachtπ  end;π  port[$3d4] := $c;π  port[$3d5] := switch * $80;πend;ππProcedure SetVgaPalette(Var p : paletteType);πVarπ  regs : Registers;πbeginπ  With regs doπ  beginπ    ax := $1012;π    bx := 0;π    cx := 256;π    es := seg(p);π    dx := ofs(p);π  end;π  intr ($10, regs);πend;πππProcedure start(Filenaam : String; horiz : Real; Var Oldpal : paletteType);ππ  Procedure readimage(Filenaam : String; Var pal : paletteType);ππ    Function FileExists(FileName : String) : Boolean;π    Varπ      f : File;π    beginπ      {$I-}π      Assign(f,  FileName);π      Reset(f);π      Close(f);π      {$I + }π      FileExists := (IOResult = 0) and (FileName <> '');π    end;ππ  Varπ    pFile : picFile;π    lFile : palFile;π    a     : Integer;π  beginπ    if (FileExists(Filenaam + '.pal')) andπ       (FileExists(Filenaam + '.dwg')) thenπ    beginπ      assign(lFile, Filenaam + '.pal');π      reset(lFile);π      read(lFile, pal);π      close(lFile);π      assign(pFile, Filenaam + '.dwg');π      reset(pFile);π      read(pFile, schermptr^);π      close(pFile);π    endπ    elseπ    beginπ      Writeln('Palette en Picture bestanden niet gevonden....');π      Halt;π    end;π  end;ππ  Procedure SetVgaMode; Assembler;π  Asmπ    mov  ah, 0π    mov  al, 13hπ    int  $10π  end;ππ  Procedure GetVgaPalette(Var p : paletteType);π  Varπ    regs : Registers;π  beginπ    With regs doπ    beginπ      ax := $1017;π      bx := 0;π      cx := 256;π      es := seg(p);π      dx := ofs(p);π    end;π    intr ($10, regs);π  end;ππVarπ  pal : paletteType;ππbeginπ  getmem(schermptr, sizeof(schermType));π  readimage(Filenaam, pal);π  GetVgaPalette(OldPal);π  SetVgaPalette(pal);π  SetVgaMode;π  move(schermptr^, scherm, nypix * nxpix);π  Virscherm_actief(0);π  move(schermptr^, mem[$A000 : 0], nypix * nxpix);     { blanko scherm }π  VirScherm_actief(1);π  move(schermptr^, mem[$A000 : 0], nypix * nxpix);     { blanko scherm }π  Scherm_actief(1);π  switch  := 0;π  xyscale := (nypix - 1) / horiz;πend;ππProcedure finish(Oldpal : paletteType);ππ  Procedure SetNormalMode; Assembler;π  Asmπ    mov  ah,  0π    mov  al,  3π    int  $10π  end;ππbeginπ  SetVgaPalette(Oldpal);π  SetNormalMode;π  Virscherm_actief(0);π  Freemem(schermptr, sizeof(schermType));πend;ππbeginπend.π                    20     08-27-9321:27ALL                      SWAG SUPPORT TEAM        A Simple Graph Unit      IMPORT              12     ╓÷
  2.  Unit MyGraph;ππInterfaceππTypeπ  ColorValue = Recordπ    Rvalue,π    Gvalue,π    Bvalue : Byte;π  end;ππ  PaleteType = Array [0..255] of ColorValue;ππProcedure palette(tp : paleteType);πProcedure pset(x, y : Integer; c : Byte);πFunction  Point(x, y : Integer) : Byte;πProcedure RotatePalette(Var p : PaleteType; n1, n2, d : Integer);πProcedure SetVga;ππImplementationππUsesπ  Crt, Dos;ππππVarπ  n, x,π  y, c, i : Integer;π  ch      : Char;π  p       : PaleteType;π  image   : File;π  ok      : Boolean;ππProcedure palette(tp : PaleteType);πVarπ  regs : Registers;πbegin { Procedure VGApalette }π  Regs.AX := $1012;π  Regs.BX := 0; { first register to set }π  Regs.CX := 256; { number of Registers to set }π  Regs.ES := Seg(tp);π  Regs.DX := Ofs(tp);π  Intr($10, regs);πend; { Procedure SetVGApalette }ππProcedure Pset(x, y : Integer; c : Byte);πbegin { Procedure PutPixel }π  mem[$A000 : Word(320 * y + x)] := c;πend; { Procedure PutPixel }ππFunction point(x, y : Integer) : Byte;πbegin { Function GetPixel }π  Point := mem[$A000 : Word(320 * y + x)];πend; { Function GetPixel }ππProcedure rotatePalette(Var p : PaleteType; n1, n2, d : Integer);πVarπ  q : PaleteType;πbegin { Procedure rotatePalette }π  q := p;π  For i := n1 to n2 doπ    p[i] := q[n1 + (i + d) mod (n2 - n1 + 1)];π  palette(p);πend; { Procedure rotatePalette }ππProcedure SetVga;πbeginπ  Inline($B8/$13/$00/$CD/$10);πend;ππend.ππ           21     08-27-9321:37ALL                      MARK DIXON               ModeX Code               IMPORT              41     ╓╡ç {πMARK DIXONππUm, have a look at this, and see what you can come up with. It's some code Iπwrote a while back to use mode-x and do double buffering (or page-flipping).π}ππProgram Test_ModeX;ππUsesπ  crt;πππ{ This program will put the VGA card into a MODEX mode (still only 320x200)π  and demonstrate double buffering (page flipping)ππ  This program was written by Mark Dixon, and has been donated to theπ  Public Domain with the exception that if you make use of these routines,π  the author of these routines would appreciate his name mentioned somewhereπ  in the documentation.ππ  Use these routines at your own risk! Because they use the VGA's registers,π  cards that are not 100% register compatible may not function correctly, andπ  may even be damaged. The author will bear no responsability for any actionsπ  occuring as a direct (or even indirect) result of the use of this program.ππ  Any donations (eg Money, Postcards, death threats.. ) can be sent to  :ππ  Mark Dixonπ  12 Finchley Stπ  Lynwood,π  Western Australiaπ  6147ππ  If you have Netmail access, then I can also be contacted on 3:690/660.14ππ  }ππConstπ  Page : Byte = 0;ππVarπ  I, J : Word;πππProcedure InitModeX;π{ Sets up video mode to Mode X (320x200x256 with NO CHAIN4) making availableπ  4 pages of 4x16k bitmaps }πBeginπ  asmπ    mov    ax, 0013h    { Use bios to enter standard Mode 13h }π    int    10hπ    mov    dx, 03c4h    { Set up DX to one of the VGA registers }π    mov    al, 04h      { Register = Sequencer : Memory Modes }π    out    dx, alπ    inc    dx           { Now get the status of the register }π    in     al, dx       { from the next port }π    and    al, 0c7h     { AND it with 11000111b ie, bits 3,4,5 wiped }π    or     al, 04h      { Turn on bit 2 (00000100b) }π    out    dx, al       { and send it out to the register }π    mov    dx, 03c4h    { Again, get ready to activate a register }π    mov    al, 02h      { Register = Map Mask }π    out    dx, alπ    inc    dxπ    mov    al, 0fh      { Send 00001111b to Map Mask register }π    out    dx, al       { Setting all planes active }π    mov    ax, 0a000h   { VGA memory segment is 0a000h }π    mov    es, ax       { load it into ES }π    sub    di, di       { clear DI }π    mov    ax, di       { clear AX }π    mov    cx, 8000h    { set entire 64k memory area (all 4 pages) }π    repnz  stosw        { to colour BLACK (ie, Clear screens) }π    mov    dx, 03d4h    { User another VGA register }π    mov    al, 14h      { Register = Underline Location }π    out    dx, alπ    inc    dx           { Read status of register }π    in     al, dx       { into AL }π    and    al, 0bFh     { AND AL with 10111111b }π    out    dx, al       { and send it to the register }π                        { to deactivate Double Word mode addressing }π    dec    dx           { Okay, this time we want another register,}π    mov    al, 17h      { Register = CRTC : Mode Control }π    out    dx, alπ    inc    dxπ    in     al, dx       { Get status of this register }π    or     al, 40h      { and Turn the 6th bit ON }π    out    dx, al       { to turn WORD mode off }π                        { And thats all there is too it!}π  End;πEnd;πππProcedure Flip;π{ This routine will flip to the next page, and change the value inπ  PAGE such that we will allways be drawing to the invisible page. }πVarπ  OfsAdr : Word;πBeginπ  OfsAdr := Page * 16000;π  asmπ    mov    dx, 03D4hπ    mov    al, 0Dh      { Set the Start address LOW register }π    out    dx, alπ    inc    dxππ    mov    ax, OfsAdrπ    out    dx, al       { by sending low byte of offset address }π    dec    dxπ    mov    al, 0Ch      { now set the Start Address HIGH register }π    out    dx, alπ    inc    dxπ    mov    al, ahπ    out    dx, al       { by sending high byte of offset address }π  End;ππ  Page := 1 - Page;     { Flip the page value.π                          Effectively does a :π                          If Page = 0 then Page = 1 elseπ                          If Page = 1 then Page = 0.       }πEnd;ππππProcedure PutPixel (X, Y : Integer; Colour : Byte );π{ Puts a pixel on the screen at the current page. }πVarπ  OfsAdr : Word;πBEGINπ  OfsAdr := Page * 16000;π  ASMπ    mov    bx, xπ    mov    ax, Yπ    mov    cx, 80     { Since there are now 4 pixels per byte, weπ                        only multiply by 80 (320/4) }π    mul    cxπ    mov    di, axπ    mov    ax, bxπ    shr    ax, 1π    shr    ax, 1π    add    di, axπ    and    bx, 3π    mov    ah, 1π    mov    cl, blπ    shl    ah, clππ    mov    al, 2π    mov    dx, 03C4hππ    mov    bx, $A000π    mov    es, bxπ    add    di, OfsAdrππ    out    dx, ax        { Set plane to address (where AH=Plane) }π    mov    al, Colourπ    mov    es:[di], alπ  end;πend;ππBeginπ  Randomize;π  InitModeX;π  Flip;ππ  For I := 0 to 319 doπ    For J := 0 to 199 doπ      PutPixel(I, J, Random(32) );π  Flip;ππ  For I := 0 to 319 doπ    For J := 0 to 199 doπ      PutPixel(I, J, Random(32) + 32);ππ  Repeatπ    Flip;π    Delay(200);π  Until Keypressed;ππEnd.π                                                                                               22     08-27-9321:52ALL                      MIKE BRENNAN             Rotate Grahic Image      IMPORT              17     ╓Tâ {πMIKE BRENNANππ> I've been trying For some time to get a Pascal Procedure that canπ> SCALE and/or ROTATE Graphic images. if anyone has any idea how to doππ    Here are a couple of Procedures I made For rotating images, 2D and 3D.  Iπbasically had to rotate each dot individually, and then form the image byπconnecting the specified dots.  Here they are...π}ππProcedure Rotate(cent1, cent2 : Integer;     { Two centroids For rotation }π                 angle : Real;               { Angle to rotate in degrees }π                 Var coord1, coord2 : Real); { both coordinates to rotate }πVarπ  coord1t, coord2t : Real;πbeginπ  {Set coordinates For temp system}π  coord1t := coord1 - cent1;π  coord2t := coord2 - cent2;ππ  {set new rotated coordinates}π  coord1 := coord1t * cos(angle * pi / 180) - coord2t * sin(angle * pi / 180);π  coord2 := coord1t * sin(angle * pi / 180) + coord2t * cos(angle * pi / 180);ππ  {Change coordinates from temp system}π  coord1 := coord1 + cent1;π  coord2 := coord2 + cent2;πend;ππProcedure Draw3d(x, y, z : Real; {coordinates} a, b : Real; {View angles}π                 Var newx, newy : Integer); {return coordinates}πVarπ  Xd, Yd, Zd : Real;πbeginπ  Xd := cos(a * pi / 180) * cos(b * pi / 180);π  Yd := cos(b * pi / 180) * sin(a * pi / 180);π  Zd := -sin(b * pi / 180);π  {Set coordinates For X/Y system}π  newx:= round(-z * Xd / Zd + x);π  newy:= round(-z * Yd / Zd + y);πend;ππ{πFor the first Procedure, you can rotate an image along any two axes, (ieπX,Y...X,Z...Y,Z).  Simply calculate the centroid For each axe, (the average Xπcoordinate, or Y or Z), then pass the angle to rotate (use a negative For otherπdirection) and it will pass back the new rotated coordinates.ππ    The second Procedure is For 3D drawing only. It transforms any 3D dot intoπits corresponding position on a 2D plan (ie your screen).  The new coordinatesπare returned in the NewX, and NewY. Those are what you would use to plot yourπdot on the screen.π}                                                                                  23     08-27-9321:52ALL                      SEAN PALMER              Another Graphic Rotate   IMPORT              58     ╓gµ {πSEAN PALMERππ> I've been trying For some time to get a Pascal Procedure that canπ> SCALE and/or ROTATE Graphic images. if anyone has any idea how to do this,π> or has a source code, PLEEEAASSEE drop me a line.. THANK YOU!ππThis is an out-and-out blatant hack of the routines from Abrash'sπXSHARP21. They are too slow to be usable as implemented here.π}ππ{$A-,B-,D+,E-,F-,G+,I-,L+,N-,O-,R-,S-,V-,X+}π{$M $2000,0,0}πProgram VectTest;πUsesπ  Crt, b320x200; {<-this Unit just implements Plot(x, y) and Color : Byte; }ππConstπ  ClipMinY = 0;π  ClipMaxY = 199;π  ClipMinX = 0;π  ClipMaxX = 319;π  VertMax  = 3;ππTypeπ  fixed = Recordπ    Case Byte ofπ      0 : (f : Byte; si : shortint);π      1 : (f2, b : Byte);π      2 : (w : Word);π      3 : (i : Integer);π    end;ππ  ByteArray = Array [0..63999] of Byte;ππ  VertRec   = Recordπ    X, Y : Byte;π  end;ππ  VertArr   = Array [0..VertMax] Of VertRec;π  EdgeScan  = Recordπ    scansLeft   : Integer;π    Currentend  : Integer;π    srcX, srcY  : fixed;π    srcStepX,π    srcStepY    : fixed;π    dstX        : Integer;π    dstXIntStep : Integer;π    dstXdir     : Integer;π    dstXErrTerm : Integer;π    dstXAdjUp   : Integer;π    dstXAdjDown : Integer;π    dir         : shortInt;π  end;ππConstπ  numVerts = 4;π  mapX     = 7;π  mapY     = 7;ππ  Vertex : Array [0..vertMax] of vertRec =π    ((x : 040; y : 020),π     (x : 160; y : 050),π     (x : 160; y : 149),π     (x : 040; y : 179));ππ  Points : Array [0..vertMax] of vertRec =π    ((x : 0; y : 0),π     (x : mapX; y : 0),π     (x : mapX; y : mapY),π     (x : 0; y : mapY));ππ  texMap : Array [0..mapY, 0..mapX] of Byte =π    (($F, $F, $F, $F, $F, $F, $F, $0),π     ($F, $7, $7, $7, $7, $7, $F, $0),π     ($F, $7, $2, $2, $2, $7, $F, $0),π     ($F, $7, $2, $2, $2, $7, $F, $0),π     ($F, $7, $2, $2, $9, $7, $F, $0),π     ($F, $7, $2, $2, $2, $7, $F, $0),π     ($F, $7, $2, $2, $2, $7, $F, $0),π     ($0, $0, $0, $0, $0, $0, $0, $0));ππVarπ  lfEdge,π  rtEdge : EdgeScan;π  z, z2  : Integer;ππFunction fixedDiv(d1, d2 : LongInt) : LongInt; Assembler;πAsmπ  db  $66; xor dx, dxπ  mov cx, Word ptr D1+2π  or  cx, cxπ  jns @Sπ  db  $66; dec dxπ @S:π  mov dx, cxπ  mov ax, Word ptr D1π  db  $66; shl ax, 16π  db  $66; idiv Word ptr d2π  db  $66; mov dx, axπ  db  $66; shr dx, 16πend;ππFunction div2Fixed(d1, d2 : LongInt) : LongInt; Assembler;πAsmπ  db $66; xor dx, dxπ  db $66; mov ax, Word ptr d1π  db $66; shl ax, 16π  jns @Sπ  db $66; dec dxπ @S:π  db $66; idiv Word ptr d2π  db $66; mov dx, axπ  db $66; shr dx, 16πend;ππFunction divfix(d1, d2 : Integer) : Integer; Assembler;πAsmπ  mov  al, Byte ptr d1+1π  cbwπ  mov  dx, axπ  xor  al, alπ  mov  ah, Byte ptr d1π  idiv d2πend;ππProcedure Draw;πVarπ  MinY,π  MaxY,π  MinVert,π  MaxVert,π  I, dstY  : Integer;ππ  Function SetUpEdge(Var Edge : EdgeScan; StartVert : Integer) : Boolean;π  Varπ    NextVert   : shortint;π    dstXWidth  : Integer;π    T,π    dstYHeight : fixed;π  beginπ    SetUpEdge := True;π    While (StartVert <> MaxVert) Doπ    beginπ      NextVert := StartVert + Edge.dir;π      if (NextVert >= NumVerts) Thenπ        NextVert := 0π      elseπ      if (NextVert < 0) Thenπ        NextVert := pred(NumVerts);ππ      With Edge Doπ      beginπ       scansLeft := vertex[NextVert].Y - vertex[StartVert].Y;π       if (scansLeft <> 0) Thenπ       beginπ         dstYHeight.f  := 0;π         dstYHeight.si := scansLeft;π         Currentend    := NextVert;π         srcX.f  := 0;π         srcX.si := Points[StartVert].X;π         srcY.f  := 0;π         srcY.si := Points[StartVert].Y;π         srcStepX.i := divFix(points[nextVert].x - srcX.si, scansLeft);π         srcStepY.i := divFix(points[nextVert].y - srcY.si, scansLeft);π         dstX       := vertex[StartVert].X;π         dstXWidth  := vertex[NextVert].X-vertex[StartVert].X;ππ         if (dstXWidth < 0) Thenπ         beginπ           dstXdir     := -1;π           dstXWidth   := -dstXWidth;π           dstXErrTerm := 1 - scansLeft;π           dstXIntStep := -(dstXWidth Div scansLeft);π         endπ         elseπ         beginπ           dstXdir     := 1;π           dstXErrTerm := 0;π           dstXIntStep := dstXWidth Div scansLeft;π         end;π         dstXAdjUp   := dstXWidth Mod scansLeft;π         dstXAdjDown := scansLeft;π         Exit;π       end;π       StartVert := NextVert;π      end;π    end;π    SetUpEdge := False;π  end;ππ  Function StepEdge(Var Edge : EdgeScan) : Boolean;π  beginπ    Dec(Edge.scansLeft);π    if (Edge.scansLeft = 0) Thenπ    beginπ      StepEdge := SetUpEdge(Edge, Edge.Currentend);π      Exit;π    end;π    With Edge Doπ    beginπ      Inc(srcX.i, srcStepX.i);π      Inc(srcY.i, srcStepY.i);π      Inc(dstX, dstXIntStep);π      Inc(dstXErrTerm, dstXAdjUp);π      if (dstXErrTerm > 0) Thenπ      beginπ        Inc(dstX, dstXdir);π        Dec(dstXErrTerm, dstXAdjDown);π      end;π    end;π    StepEdge := True;π  end;ππ  Procedure ScanOutLine;π  Varπ    srcX,π    srcY     : fixed;π    dstX,π    dstXMax  : Integer;π    dstWidth,π    srcXStep,π    srcYStep : fixed;π  beginπ    srcX.w  := lfEdge.srcX.w;π    srcY.w  := lfEdge.srcY.w;π    dstX    := lfEdge.dstX;π    dstXMax := rtEdge.dstX;ππ    if (dstXMax <= ClipMinX) Or (dstX >= ClipMaxX) Thenπ      Exit;π    dstWidth.f  := 0;π    dstWidth.si := dstXMax - dstX;π    if (dstWidth.i <= 0) Thenπ      Exit;π    srcXStep.i := divFix(rtEdge.srcX.i - srcX.i, dstWidth.i);π    srcYStep.i := divFix(rtEdge.srcY.i - srcY.i, dstWidth.i);π    if (dstXMax > ClipMaxX) Thenπ      dstXMax := ClipMaxX;π    if (dstX < ClipMinX) Thenπ    beginπ      Inc(srcX.i, srcXStep.i * (ClipMinX - dstX));π      Inc(srcY.i, srcYStep.i * (ClipMinX - dstX));π      dstX := ClipMinX;π    end;ππ    Asmπ     mov  ax, $A000π     mov  es, axπ     mov  ax, xResπ     mul  dstYπ     add  ax, dstXπ     mov  di, axπ     mov  cx, dstXMaxπ     sub  cx, dstXπ     mov  bx, srcXStep.iπ     mov  dx, srcYStep.iπ    @L:π     mov  al, srcY.&siπ     xor  ah, ahπ     shl  ax, 3π     add  al, srcX.&siπ     add  ax, offset texmapπ     mov  si, axπ     movsbπ     add  srcX.i,bxπ     add  srcY.i,dxπ     loop @Lπ     end;π   end;ππbeginπ  if (NumVerts < 3) Thenπ    Exit;π  MinY := vertex[numVerts - 1].y;π  maxY := vertex[numVerts - 1].y;π  maxVert := numVerts - 1;π  minVert := numVerts - 1;π  For I := numVerts - 2 downto 0 Doπ  beginπ    if (vertex[I].Y < MinY) Thenπ    beginπ      MinY    := vertex[I].Y;π      MinVert := I;π    end;π    if (vertex[I].Y > MaxY) Thenπ    beginπ      MaxY    := vertex[I].Y;π      MaxVert := I;π    end;π  end;π  if (MinY >= MaxY) Thenπ    Exit;π  dstY := MinY;π  lfEdge.dir := -1;π  SetUpEdge(lfEdge, MinVert);π  rtEdge.dir := 1;π  SetUpEdge(rtEdge, MinVert);π  While (dstY < ClipMaxY) Doπ  beginπ    if (dstY >= ClipMinY) Thenπ      ScanOutLine;π    if Not StepEdge(lfEdge) Thenπ      Exit;π    if Not StepEdge(rtEdge) Thenπ      Exit;π    Inc(dstY);π  end;πend;ππbeginπ  directVideo := False;π  TextAttr    := 63;π  { For z:=0 to mapY do For z2:=0 to mapx do texMap[z,z2]:=random(6+53);}π  For z := 4 to 38 doπ  beginπ    clearGraph;π    vertex[0].x := z * 4;π    vertex[3].x := z * 4;π    draw;π    if KeyPressed thenπ    beginπ      ReadKey;π      ReadKey;π    end;π  end;π  readln;πend.ππ                                                                                            24     08-27-9321:52ALL                      WILLIAM SITCH            Rotate PIC               IMPORT              22     ╓ {πWILLIAM SITCHππ> I've been trying For some time to get a Pascalπ> Procedure that can SCALE and/or ROTATE Graphic images. ifπ> anyone has any idea how to do this, or has a source code,π> PLEEEAASSEE drop me a line.. THANK YOU!ππHere is some code to rotate an image (in MCGA screen mode $13) ... but it has aπfew drawbacks... its kinda slow and the image falls apart during rotation... itπhasn't been tested fully either...π}ππProcedure rotate(x1, y1, x2, y2 : Word; ang, ainc : Real);πVarπ  ca, sa :  Real;π  cx, cy :  Real;π  dx, dy :  Real;π  h, i,π  j, k   :  Word;ππ  pinf   :  Array [1..12500] of Recordπ    x, y :  Word;π    col  :  Byte;π  end;ππbeginπ  ca := cos((ainc / 180) * pi);π  sa := sin((ainc / 180) * pi);ππ  For h := 1 to round(ang / ainc) doπ  beginπ    k  := 0;π    cx := x1 + ((x2 - x1) / 2);π    cy := y1 + ((y2 - y1) / 2);π    For i := x1 to x2 doπ      For j := y1 to y2 doπ      beginπ        inc(k);ππ        dx := cx + (((i - cx) * ca) - ((j - cy) * sa));π        dy := cy + (((i - cx) * sa) + ((j - cy) * ca));ππ        if (round(dx) > 0) and (round(dy) > 0) andπ           (round(dx) < 65000) and (round(dy) < 65000) thenπ        beginπ          pinf[k].x   := round(dx);π          pinf[k].y   := round(dy);π          pinf[k].col := mem[$A000 : j * 320 + i];π        endπ        elseπ        beginπ          pinf[k].x   := 0;π          pinf[k].y   := 0;π          pinf[k].col := 0;π        end;π      end;ππ      For i := x1 to x2 doπ        For j := y1 to y2 doπ          mem[$A000 : j * 320 + i] := 0;ππ      x1 := 320;π      x2 := 1;π      y1 := 200;π      y2 := 1;π      For i := 1 to k doπ      beginπ        if (pinf[i].x < x1) thenπ          x1 := pinf[i].x;π        if (pinf[i].x > x2) thenπ          x2 := pinf[i].x;ππ        if (pinf[i].y < y1) thenπ          y1 := pinf[i].y;π        if (pinf[i].y > y2) thenπ          y2 := pinf[i].y;ππ        if (pinf[i].x > 0) and (pinf[i].y > 0) thenπ          mem[$A000 : pinf[i].y * 320 + pinf[i].x] := pinf[i].col;π      end;π  end;πend;ππ{πIt works, but DON'T try to use it For a main module or base a Program AROUNDπit... instead try to change it to suit your needs, as right now it's kindaπoptimized For my needs...ππSorry For not editing it to work With any screen mode, but I just don't haveπthe time.  MCGA memory is a linear block of Bytes, and you can access it using:πmem[$A000:offset].  So to find the color at screen position 10,10, you wouldπgo:ππmem[$A000 : y * 320 + x]π          ^     ^     ^-- x val, 10π          |     |----- screenwidthπ          |-------- y val, 10π}                                                                                                                        25     08-27-9321:58ALL                      WILLIAM SITCH            Graphic Spinning Disk    IMPORT              24     ╓p─ {πWILLIAM SITCHππ> Okay, I've just finally got my hands on the formulas forπ> doing good Graphics manipulations...well, I decided to startπ> With something simple.  A rotating square.  But it DOESN'Tπ> WORK RIGHT.  I noticed the size seemed to shift in and outπ> and a little testing showed me that instead of following aπ> circular path (as they SHOULD), the corners (while spinning)π> actually trace out an OCTAGON. Why????  I've checked andπ> rechecked the formula logic...It's just as I was given.  Soπ> there's some quirk about the code that I don't know about.π> Here's the rotating routine:ππAhhh... "rounding errors" is what my comp sci teacher explained to me, butπthere isn't much you can do about it... I've included my (rather long)πspinning disc code to take a look at ... feel free to try to port it to yourπapplication...ππ}ππUsesπ  Graph, Crt;ππProcedure spin_disk;πTypeπ  pointdataType = Array [1..4] of Record x,y : Integer; end;πConstπ  delVar = 10;ππVarπ  ch       :  Char;π  p, op    :  pointdataType;π  cx, cy,π  x, y, r  :  Integer;π  i        :  Integer;π  rot      :  Integer;π  tempx,π  tempy    :  Integer;π  theta    :  Real;π  down     :  Boolean;π  del      :  Real;πbeginπ  cx := getmaxx div 2;π  cy := getmaxy div 2;π  r := 150;π  circle(cx,cy,r);ππ  rot := 0;π  p[1].x := 100;  p[1].y := 0;π  p[2].x := 0;    p[2].y := -100;π  p[3].x := -100; p[3].y := 0;π  p[4].x := 0;    p[4].y := 100;π  del := 50;π  down := True;ππ  Repeatπ    rot := rot + 2;π    theta := rot * 3.14 / 180;π    For i := 1 to 4 doπ      beginπ        tempx := p[i].x;π        tempy := p[i].y;π        op[i].x := p[i].x;π        op[i].y := p[i].y;π        p[i].x := round(cos(theta) * tempx - sin(theta) * tempy);π        p[i].y := round(sin(theta) * tempx + cos(theta) * tempy);π      end;π    setcolor(0);π    line(op[1].x + cx,cy - op[1].y,op[2].x + cx,cy - op[2].y);π    line(op[2].x + cx,cy - op[2].y,op[3].x + cx,cy - op[3].y);π    line(op[3].x + cx,cy - op[3].y,op[4].x + cx,cy - op[4].y);π    line(op[4].x + cx,cy - op[4].y,op[1].x + cx,cy - op[1].y);π    For i := 1 to 4 doπ      line(op[i].x + cx,cy - op[i].y,cx,cy);π    setcolor(11);π    line(p[1].x + cx,cy - p[1].y,p[2].x + cx,cy - p[2].y);π    line(p[2].x + cx,cy - p[2].y,p[3].x + cx,cy - p[3].y);π    line(p[3].x + cx,cy - p[3].y,p[4].x + cx,cy - p[4].y);π    line(p[4].x + cx,cy - p[4].y,p[1].x + cx,cy - p[1].y);π    setcolor(10);π    For i := 1 to 4 doπ      line(p[i].x + cx,cy - p[i].y,cx,cy);π    if (del < 1) thenπ      down := Falseπ    else if (del > 50) thenπ      down := True;π    if (down) thenπ      del := del - delVarπ    elseπ      del := del + delVar;π    Delay(round(del));π  Until (KeyPressed = True);π  ch := ReadKey;π  NoSound;πend;ππVarπ  Gd, Gm : Integer;ππbeginπ  Gd := Detect;π  InitGraph(Gd, Gm, 'd:\bp\bgi');ππ  Spin_disk;ππend.                                                                                                                      26     08-27-9321:59ALL                      SEAN PALMER              Drawing a B-Spline curve IMPORT              22     ╓╛: {πSEAN PALMERππI was just toying around With a B-Spline curve routine I got out of anπold issue of Byte, and thought it was pretty neat. I changed it to useπfixed point fractions instead of Reals, and optimized it some...ππby Sean Palmerπpublic domainπ}ππVarπ  color : Byte;πProcedure plot(x, y : Word);πbeginπ  mem[$A000 : y * 320 + x] := color;πend;ππTypeπ  coord = Recordπ    x, y : Word;π  end;ππ  CurveDataRec = Array [0..65521 div sizeof(coord)] of coord;ππFunction fracMul(f, f2 : Word) : Word;πInline(π  $58/                   {pop ax}π  $5B/                   {pop bx}π  $F7/$E3/               {mul bx}π  $89/$D0);              {mov ax,dx}ππFunction mul(f, f2 : Word) : LongInt;πInline(π  $58/                   {pop ax}π  $5B/                   {pop bx}π  $F7/$E3);              {mul bx}πππConstπ  nSteps = 1 shl 8;  {about 8 For smoothness (dots), 4 For speed (lines)}ππProcedure drawBSpline(Var d0 : coord; nPoints : Word);πConstπ  nsa  = $10000 div 6;π  nsb  = $20000 div 3;π  step = $10000 div nSteps;πVarπ  i, xx, yy,π  t1, t2, t3,π  c1, c2, c3, c4 : Word;ππ  d : curveDataRec Absolute d0;ππbeginπ  t1 := 0;π  color := 32 + 2;ππ  For i := 0 to nPoints - 4 doπ  beginππ   {algorithm converted from Steve Enns' original Basic subroutine}ππ    Repeatπ      t2 := fracMul(t1, t1);π      t3 := fracMul(t2, t1);π      c1 := (Integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);π      c2 := (t3 shr 1) + nsb - t2;π      c3 := ((t2 + t1 - t3) shr 1) + nsa;π      c4 := fracmul(nsa, t3);π      xx := (mul(c1, d[i].x) + mul(c2, d[i + 1].x) +π             mul(c3, d[i + 2].x) + mul(c4, d[i + 3].x)) shr 16;π      yy := (mul(c1, d[i].y) + mul(c2, d[i + 1].y) +π             mul(c3, d[i + 2].y) + mul(c4, d[i + 3].y)) shr 16;π      plot(xx, yy);π      inc(t1, step);π    Until t1 = 0;  {this is why nSteps must be even power of 2}π   inc(color);π   end;πend;ππConstπ  pts = 24; {number of points} {chose this because of colors}ππVarπ  c : Array [-1..2 + pts] of coord;π  i : Integer;πbeginπ  Asmπ    mov ax, $13π    int $10π  end;  {init vga/mcga Graphics}π  randomize;π  For i := 1 to pts doπ  With c[i] doπ  beginπ    {x:=i*(319 div pts);}    {for precision demo}π    x := random(320);               {for fun demo}π    y := random(200);π  end;π  {for i:=1 to pts div 2 do c[i*2+1].y:=c[i*2].y;}    {fit closer}π  For i := 1 to pts doπ  With c[i] doπ  beginπ    color := i + 32;π    plot(x, y);π  end;π  {replicate end points so curves fit to input}π  c[-1] := c[1];π  c[0]  := c[1];π  c[pts + 1] := c[pts];π  c[pts + 2] := c[pts];π  drawBSpline(c[-1], pts + 4);π  readln;π  Asmπ    mov ax, 3π    int $10π  end;  {Text mode again}πend.π                                                    27     08-27-9321:59ALL                      SEAN PALMER              Another B-Spline Curve   IMPORT              35     ╓₧┼ {πSEAN PALMERππI've been playing around with it as a way to make 'heat-seekingπmissiles' in games. Very interesting...ππWhat I do is have the points set up as follows:ππ1   : current positionπ2&3 : current speed + the current positionπ4   : destinationππand update current position by indexing somewhere into the curve (likeπat $100 out of $FFFFππThis works very well. Problem is that I don't know of a good way toπchange the speed.ππHere is a simple demo that makes a dot chase the mouse cursor (needsπVGA as written) that shows what I mean.ππIf ANYBODY can make this work smoother or improve on it in any way Iπwould appreciate being told how... 8)π}ππusesπ  mouse, crt;  { you will need to change accesses to the mouse unit }π               { to use a mouse package that you provide }πtypeπ  coord = recordπ    x, y : word;π  end;π  CurveDataRec = array [0..65521 div sizeof(coord)] of coord;ππconstπ  nSteps = 1 shl 8;  {about 8 for smoothness (dots), 4 for speed (lines)}ππvarπ  color : byte;π  src, spd,π  dst, mov1,π  mov2 : coord;π  i : integer;ππprocedure plot(x, y : word);πbeginπ  mem[$A000 : y * 320 + x] := color;πend;ππfunction fracMul(f, f2 : word) : word;πInline(π  $58/                   {pop ax}π  $5B/                   {pop bx}π  $F7/$E3/               {mul bx}π  $89/$D0);              {mov ax,dx}ππfunction mul(f, f2 : word) : longint;πinline(π  $58/                   {pop ax}π  $5B/                   {pop bx}π  $F7/$E3);              {mul bx}πππ{this is the original full BSpline routine}ππprocedure drawBSpline(var d0 : coord; nPoints : word);πconstπ  nsa  = $10000 div 6;π  nsb  = $20000 div 3;π  step = $10000 div nSteps;πvarπ  i, xx, yy : word;π  t1, t2, t3 : word;π  c1, c2, c3, c4 : word;π  d : curveDataRec absolute d0;πbeginπ  t1 := 0;π  color := 32 + 2;π  for i := 0 to nPoints - 4 doπ  beginπ    {algorithm converted from Steve Enns' original Basic subroutine}π    repeatπ      t2 := fracMul(t1, t1);π      t3 := fracMul(t2, t1);π      c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);π      c2 := (t3 shr 1) + nsb - t2;π      c3 := ((t2 + t1 - t3) shr 1) + nsa;π      c4 := fracmul(nsa, t3);π      xx := (mul(c1, d[i].x) + mul(c2, d[i + 1].x) +π             mul(c3, d[i + 2].x) + mul(c4, d[i + 3].x)) shr 16;π      yy := (mul(c1, d[i].y) + mul(c2, d[i + 1].y) +π             mul(c3, d[i + 2].y) + mul(c4, d[i + 3].y)) shr 16;π      plot(xx, yy);π      inc(t1, step);π    until t1 = 0;  {this is why nSteps must be even power of 2}π    inc(color);π  end;πend;πππ{find 1/nth point in BSpline}  {this is what does the B-Spline work}ππprocedure moveTowards(d1, d2, d3, d4 : coord; t1 : word; var mov : coord);πconstπ  nsa = $10000 div 6;π  nsb = $20000 div 3;πvarπ  t2, t3 : word;π  c1, c2,π  c3, c4 : word;πbeginπ  t2 := fracMul(t1, t1);π  t3 := fracMul(t2, t1);π  c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);π  c2 := (t3 shr 1) + nsb - t2;π  c3 := ((t2 + t1 - t3) shr 1) + nsa;π  c4 := fracmul(nsa, t3);π  mov.x := (mul(c1, d1.x) + mul(c2, d2.x) + mul(c3, d3.x) + mul(c4, d4.x)) shr 16;π  mov.y := (mul(c1, d1.y) + mul(c2, d2.y) + mul(c3, d3.y) + mul(c4, d4.y)) shr 16;πend;ππbeginπ  asmπ    mov ax, $13π    int $10π  end;  {init vga/mcga graphics}ππ  {mouse.init;}π  mshow;ππ  src.x := 5;π  src.y := 5;π  spd.x := 5;π  spd.y := 5;π  dst.x := 315;π  dst.y := 190;ππ  repeatπ   {for i:=0 to 23 do begin}π   { color:=i+32;}π   { inc(dst.x,i);}π    delay(10);π    {mouse.check;}  {this loads Mouse.X, Mouse.Y, Mouse.Button from driver}π    mhide;π    color := 15;π    plot(src.x, src.y);π    color := 14;π    plot(spd.x, spd.y);π    dst.x := mousex shr 1;π    dst.y := mousey;π    color := 1;π    plot(dst.x, dst.y);π    mshow;ππ    {the parameters in these next two lines can be changed}π    {I have played with almost all possible combinations and}π    {most work, but not well, so don't be afraid to play around}π    {But I think an entirely different approach is needed for the}π    {second moveTowards..}ππ    moveTowards(src, src, spd, dst, $0010, mov1);π    moveTowards(src, spd, dst, dst, $5000, mov2);π    src := mov1;π    longint(spd) := (longint(spd) * 7 + longint(mov2)) shr 3 and $1FFF1FFF;π  until 1=0;ππ  mhide;ππ  asmπ    mov ax, 3π    int $10π  end; {text mode again}πend.ππ                                                                                                               28     08-27-9322:00ALL                      BRENDEN BEAMAN           Another Star field       IMPORT              14     ╓¥ { BRendEN BEAMAN }ππProgram starfield;πUsesπ  Crt, Graph;ππVarπ  l, l2,π  gd, gm,π  x, y   : Integer;π  rad    : Array [1..20] of Integer;π  p      : Array [1..20, 1..5] of Integer;ππProcedure put(p, rad : Integer; col : Word);πbeginπ  setcolor(col);  {1 pixel arc instead of putpixel}π  arc(x, y, p, p + 1, rad);πend;ππProcedure putstar;πbeginπ  For l := 1 to 20 do      {putting stars. #15 below is color of stars}π    For l2 := 1 to 5 do put(p[l, l2], rad[l], 15);πend;ππProcedure delstar;πbeginπ  For l := 1 to 20 do  {erasing stars}π    For l2 := 1 to 5 do put(p[l, l2], rad[l], 0);πend;ππbeginπ  randomize;π  gd := detect;π  initGraph(gd, gm, 'd:\bp\bgi');π  x := 320;π  y := 240;ππ  For l := 1 to 20 doπ    rad[l] := l * 10;π  For l := 1 to 20 doπ    For l2 := 1 to 5 doπ      p[l, l2] := random(360);ππ  While not KeyPressed doπ  beginπ    delstar;π    For l := 1 to 20 doπ    begin                {moving stars towards 'camera'}π      rad[l] := rad[l] + round(rad[l] / 20 + 1); { (20)=starspeed.  }π      if rad[l] > 400 thenπ        rad[l] := l * 10;                 { starspeed must be equal }π    end;                                   { to or less than 20     }π    putstar;π  end;π  readln;πend.ππ   The concept is fairly simple, but most people underestimate arcs...π you can set where on the circle, (0-360 degres) the arc starts, andπ stops... if you set a one pixel arc at 100, and increase the radius ofπ the circle in a loop, it will apear to come towards you in threeπ dimentions... any other questions, or problems running it, contactπ me... ttylπ                                                                                               29     08-27-9322:08ALL                      SEAN PALMER              TWEAKED! Graph unit      IMPORT              132    ╓ⁿ⌐ {$A-,B-,D+,E-,F-,G+,I-,L+,N-,O-,R-,S-,V-,X+} {TP 6.0 & 286 required!}πUnit x320x240;ππ{π Sean Palmer, 1993π released to the Public Domainπ in tweaked modes, each latch/bit plane contains the entire 8-bit pixel.π the sequencer map mask determines which plane (pixel) to update, and, whenπ reading, the read map select reg determines which plane (pixel) to read.π almost exactly opposite from regular vga 16-color modes which is why I neverπ could get my routines to work For BOTH modes. 8)ππ  # = source screen pixelπ  Normal 16-color         Tweaked 256-colorππ      Bit Mask                Bit Maskπ      76543210                33333333π Map  76543210           Map  22222222π Mask 76543210           Mask 11111111π      76543210                00000000ππ  Functional equivalentsπ      Bit Mask        =       Seq Map Maskπ      Seq Map Mask    =       Bit Maskπ}πππInterfaceππVarπ  color : Byte;ππConstπ xRes    = 320;π yRes    = 240;   {displayed screen size}π xMax    = xRes - 1;π yMax    = yRes - 1;π xMid    = xMax div 2;π yMid    = yMax div 2;π vxRes   = 512;π vyRes   = $40000 div vxRes; {virtual screen size}π nColors = 256;π tsx : Byte = 8;π tsy : Byte = 8;  {tile size}πππProcedure plot(x, y : Integer);πFunction  scrn(x, y : Integer) : Byte;ππProcedure hLin(x, x2, y : Integer);πProcedure vLin(x, y, y2 : Integer);πProcedure rect(x, y, x2, y2 : Integer);πProcedure pane(x, y, x2, y2 : Integer);ππProcedure line(x, y, x2, y2 : Integer);πProcedure oval(xc, yc, a, b : Integer);πProcedure disk(xc, yc, a, b : Integer);πProcedure fill(x, y : Integer);ππProcedure putTile(x, y : Integer; p : Pointer);πProcedure overTile(x, y : Integer; p : Pointer);πProcedure putChar(x, y : Integer; p : Word);ππProcedure setColor(color, r, g, b : Byte);π{rgb vals are from 0-63}πFunction  getColor(color : Byte) : LongInt;π{returns $00rrggbb format}πProcedure setPalette(color : Byte; num : Word; Var rgb);π{rgb is list of 3-Byte rgb vals}πProcedure getPalette(color : Byte; num : Word; Var rgb);ππProcedure clearGraph;πProcedure setWriteMode(f : Byte);πProcedure waitRetrace;πProcedure setWindow(x, y : Integer);ππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππImplementationππConstπ  vSeg     = $A000;        {video segment}π  vxBytes  = vxRes div 4;  {Bytes per virtual scan line}π  seqPort  = $3C4;   {Sequencer}π  gcPort   = $3CE;    {Graphics Controller}π  attrPort = $3C0;   {attribute Controller}ππ  tableReadIndex    = $3C7;π  tableWriteIndex   = $3C8;π  tableDataRegister = $3C9;ππ  CrtcRegLen   = 10;π  CrtcRegTable : Array [1..CrtcRegLen] of Word =π    ($0D06, $3E07, $4109, $EA10, $AC11, $DF12, $0014, $E715, $0616, $E317);ππππVarπ  CrtcPort   : Word;  {Crt controller}π  oldMode    : Byte;π  ExitSave   : Pointer;π  input1Port : Word;  {Crtc Input Status Reg #1=CrtcPort+6}π  fillVal    : Byte;ππTypeπ tRGB = Recordπ   r, g, b : Byte;π end;ππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππProcedure clearGraph; Assembler;πAsmπ  mov ax, vSegπ  mov es, axπ  mov dx, seqPortπ  mov ax, $0F02π  out dx, ax {enable whole map mask}π  xor di, diπ  mov cx, $8000 {screen size in Words}π  cldπ  mov al, colorπ  mov ah, alπ  repz stosw {clear screen}πend;ππProcedure setWriteMode(f : Byte); Assembler;πAsm {copy/and/or/xor modes}π  mov ah, fπ  shl ah, 3π  mov al, 3π  mov dx, gcPortπ  out dx, ax {Function select reg}πend;ππProcedure waitRetrace; Assembler;πAsmπ  mov  dx, CrtcPortπ  add  dx, 6 {find Crt status reg (input port #1)}π @L1:π  in   al, dxπ  test al, 8π  jnz  @L1;  {wait For no v retrace}π @L2:π  in   al, dxπ  test al, 8π  jz   @L2 {wait For v retrace}π end;πππ{π Since a virtual screen can be larger than the actual screen, scrolling isπ possible.  This routine sets the upper left corner of the screen to theπ specified pixel. Make sure 0 <= x <= vxRes - xRes, 0 <= y <= vyRes - yResπ}πProcedure setWindow(x, y : Integer); Assembler;πAsmπ  mov  ax, vxBytesπ  mul  yπ  mov  bx, xπ  mov  cl, blπ  shr  bx, 2π  add  bx, ax     {bx=Ofs of upper left corner}π  mov  dx, input1Portπ @L:π  in   al, dxπ  test al, 8π  jnz  @L  {wait For no v retrace}π  sub  dx, 6  {CrtC port}π  mov  al, $Dπ  mov  ah, blπ  cli {these values are sampled at start of retrace}π  out  dx, ax  {lo Byte of display start addr}π  dec  alπ  mov  ah, bhπ  out  dx, ax    {hi Byte}π  stiπ  add  dx, 6π @L2:π  in   al, dxπ  test al, 8π  jz   @L2  {wait For v retrace}π  {this also resets Attrib flip/flop}π  mov  dx, attrPortπ  mov  al, $33π  out  dx, al   {Select Pixel Pan Register}π  and  cl, 3π  mov  al, clπ  shl  al, 1π  out  dx, al   {Shift is For 256 Color Mode}πend;ππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππProcedure plot(x, y : Integer); Assembler;πAsmπ  mov   ax, vSegπ  mov   es, axπ  mov   di, xπ  mov   cx, diπ  shr   di, 2π  mov   ax, vxBytesπ  mul   yπ  add   di, axπ  mov   ax, $0102π  and   cl, 3π  shl   ah, clπ  mov   dx, seqPortπ  out   dx, ax {set bit mask}π  mov   al, colorπ  stosbπend;ππFunction scrn(x, y : Integer) : Byte; Assembler;πAsmπ  mov ax, vSegπ  mov es, axπ  mov di, xπ  mov cx, diπ  shr di, 2π  mov ax, vxBytesπ  mul yπ  add di, axπ  and cl, 3π  mov ah, clπ  mov al, 4π  mov dx, gcPortπ  out dx, ax      {Read Map Select register}π  mov al, es:[di]  {get the whole plane}πend;ππProcedure hLin(x, x2, y : Integer); Assembler;πAsmπ  mov   ax, vSegπ  mov   es, axπ  cldπ  mov   ax, vxBytesπ  mul   yπ  mov   di, ax {base of scan line}π  mov   bx, xπ  mov   cl, blπ  shr   bx, 2π  mov   dx, x2π  mov   ch, dlπ  shr   dx, 2π  and   cx, $0303π  sub   dx, bx     {width in Bytes}π  add   di, bx     {offset into video buffer}π  mov   ax, $FF02π  shl   ah, clπ  and   ah, $0F {left edge mask}π  mov   cl, chπ  mov   bh, $F1π  rol   bh, clπ  and   bh, $0F {right edge mask}π  mov   cx, dxπ  or    cx, cxπ  jnz   @LEFTπ  and   ah, bh                  {combine left & right bitmasks}π @LEFT:π  mov   dx, seqPortπ  out   dx, axπ  inc   dxπ  mov   al, colorπ  stosbπ  jcxz  @EXITπ  dec   cxπ  jcxz  @RIGHTπ  mov   al, $0Fπ  out   dx, al     {skipped if cx=0,1}π  mov   al, colorπ  repz  stosb   {fill middle Bytes}π @RIGHT:π  mov   al, bhπ  out   dx, al       {skipped if cx=0}π  mov   al, colorπ  stosbπ @EXIT:πend;ππProcedure vLin(x, y, y2 : Integer); Assembler;πAsmπ  mov ax, vSegπ  mov es, axπ  cldπ  mov di, xπ  mov cx, diπ  shr di, 2π  mov ax, vxBytesπ  mul yπ  add di, axπ  mov ax, $102π  and cl, 3π  shl ah, clπ  mov dx, seqPortπ  out dx, axπ  mov cx, y2π  sub cx, yπ  inc cxπ  mov al, colorπ @DOLINE:π  mov bl, es:[di]π  stosbπ  add di, vxBytes-1π  loop @DOLINEπend;ππProcedure rect(x, y, x2, y2 : Integer);πVarπ  i : Word;πbeginπ  hlin(x, pred(x2), y);π  hlin(succ(x), x2, y2);π  vlin(x, succ(y), y2);π  vlin(x2, y, pred(y2));πend;ππProcedure pane(x, y, x2, y2 : Integer);πVarπ  i : Word;πbeginπ  For i := y2 downto y doπ    hlin(x, x2, i);πend;ππProcedure line(x, y, x2, y2:Integer);πVarπ  d, dx, dy,π  ai, bi, xi, yi : Integer;πbeginπ  if(x < x2) thenπ  beginπ    xi := 1;π    dx := x2 - x;π  endπ  elseπ  beginπ    xi := -1;π    dx := x - x2;π  end;π  if (y < y2) thenπ  beginπ    yi := 1;π    dy := y2 - y;π  endπ  elseπ  beginπ    yi := -1;π    dy := y - y2;π  end;π  plot(x, y);π  if dx > dy thenπ  beginπ    ai := (dy - dx) * 2;π    bi := dy * 2;π    d  := bi - dx;π    Repeatπ      if (d >= 0) thenπ      beginπ        inc(y, yi);π        inc(d, ai);π      endπ      elseπ        inc(d, bi);π      inc(x, xi);π      plot(x, y);π    Until (x = x2);π  endπ  elseπ  beginπ    ai := (dx - dy) * 2;π    bi := dx * 2;π    d  := bi - dy;π    Repeatπ      if (d >= 0) thenπ      beginπ        inc(x, xi);π        inc(d, ai);π      endπ      elseπ        inc(d, bi);π      inc(y, yi);π      plot(x, y);π    Until (y = y2);π  end;πend;ππProcedure oval(xc, yc, a, b : Integer);πVarπ  x, y      : Integer;π  aa, aa2,π  bb, bb2,π  d, dx, dy : LongInt;πbeginπ  x := 0;π  y := b;π  aa := LongInt(a) * a;π  aa2 := 2 * aa;π  bb := LongInt(b) * b;π  bb2 := 2 * bb;π  d := bb - aa * b + aa div 4;π  dx := 0;π  dy := aa2 * b;π  plot(xc, yc - y);π  plot(xc, yc + y);π  plot(xc - a, yc);π  plot(xc + a, yc);π  While (dx < dy) doπ  beginπ    if(d > 0) thenπ    beginπ      dec(y);π      dec(dy, aa2);π      dec(d, dy);π    end;π    inc(x);π    inc(dx, bb2);π    inc(d, bb + dx);π    plot(xc + x, yc + y);π    plot(xc - x, yc + y);π    plot(xc + x, yc - y);π    plot(xc - x, yc - y);π  end;ππ  inc(d, (3 * (aa - bb) div 2 - (dx + dy)) div 2);ππ  While (y > 0) doπ  beginπ    if (d < 0) thenπ    beginπ      inc(x);π      inc(dx, bb2);π      inc(d, bb + dx);π    end;π    dec(y);π    dec(dy, aa2);π    inc(d, aa - dy);π    plot(xc + x, yc + y);π    plot(xc - x, yc + y);π    plot(xc + x, yc - y);π    plot(xc - x, yc - y);π  end;πend;ππProcedure disk(xc, yc, a, b:Integer);πVarπ  x, y      : Integer;π  aa, aa2,π  bb, bb2,π  d, dx, dy : LongInt;πbeginπ  x   := 0;π  y   := b;π  aa  := LongInt(a) * a;π  aa2 := 2 * aa;π  bb  := LongInt(b) * b;π  bb2 := 2 * bb;π  d   := bb - aa * b + aa div 4;π  dx  := 0;π  dy  := aa2 * b;ππ  vLin(xc, yc - y, yc + y);ππ  While (dx < dy) doπ  beginπ    if (d > 0) thenπ    beginπ      dec(y);π      dec(dy, aa2);π      dec(d, dy);π    end;π    inc(x);π    inc(dx, bb2);π    inc(d, bb + dx);π    vLin(xc - x, yc - y, yc + y);π    vLin(xc + x, yc - y, yc + y);π  end;ππ  inc(d, (3 * (aa - bb) div 2 - (dx + dy)) div 2);ππ  While (y >= 0) doπ  beginπ    if (d < 0) thenπ    beginπ      inc(x);π      inc(dx, bb2);π      inc(d, bb + dx);π      vLin(xc - x, yc - y, yc + y);π      vLin(xc + x, yc - y, yc + y);π    end;π    dec(y);π    dec(dy, aa2);π    inc(d, aa - dy);π  end;πend;ππ{This routine only called by fill}πFunction lineFill(x, y, d, prevXL, prevXR : Integer) : Integer;πVarπ  xl, xr, i : Integer;πLabelπ  _1, _2, _3;πbeginπ  xl := x;π  xr := x;ππ  Repeatπ    dec(xl);π  Until (scrn(xl, y) <> fillVal) or (xl < 0);ππ  inc(xl);ππ  Repeatπ    inc(xr);π  Until (scrn(xr, y) <> fillVal) or (xr > xMax);ππ  dec(xr);π  hLin(xl, xr, y);π  inc(y, d);ππ  if Word(y) <= yMax thenπ  For x := xl to xr doπ    if (scrn(x, y) = fillVal) thenπ    beginπ      x := lineFill(x, y, d, xl, xr);π      if Word(x) > xr thenπ        Goto _1;π    end;ππ  _1 :ππ  dec(y, d + d);π  Asmπ    neg d;π  end;π  if Word(y) <= yMax thenπ  beginπ  For x := xl to prevXL doπ    if (scrn(x, y) = fillVal) thenπ    beginπ      i := lineFill(x, y, d, xl, xr);π      if Word(x) > prevXL thenπ        Goto _2;π    end;ππ    _2 :ππ    for x := prevXR to xr doπ      if (scrn(x, y) = fillVal) thenπ      beginπ        i := lineFill(x, y, d, xl, xr);π        if Word(x) > xr thenπ          Goto _3;π      end;ππ      _3 :ππ      end;ππ  lineFill := xr;πend;ππProcedure fill(x, y : Integer);πbeginπ  fillVal := scrn(x, y);π  if fillVal <> color thenπ    lineFill(x, y, 1, x, x);πend;πππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππProcedure putTile(x, y : Integer; p : Pointer); Assembler;πAsmπ  push  dsπ  lds   si, pπ  mov   ax, vSegπ  mov   es, axπ  mov   di, xπ  mov   cx, diπ  shr   di, 2π  mov   ax, vxBytesπ  mul   yπ  add   di, axπ  mov   ax, $102π  and   cl, 3π  shl   ah, cl      {make bit mask}π  mov   dx, seqPortπ  mov   bh, tsyπ @DOLINE:π  mov   cl, tsxπ  xor   ch, chπ  push  axπ  push  di    {save starting bit mask}π @LOOP:π  {mov al, 2}π  out   dx, axπ  shl   ah, 1       {give it some time to respond}π  mov   bl, es:[di]π  movsbπ  dec   diπ  test  ah, $10π  jz    @SAMEByteπ  mov   ah, 1π  inc   diπ @SAMEByte:π  loop  @LOOPπ  pop   diπ  add   di, vxBytesπ  pop   ax {start of next line}π  dec   bhπ  jnz   @DOLINEπ  pop   dsπend;ππProcedure overTile(x, y : Integer; p : Pointer); Assembler;πAsmπ  push  dsπ  lds   si, pπ  mov   ax, vSegπ  mov   es, axπ  mov   di, xπ  mov   cx, diπ  shr   di, 2π  mov   ax, vxBytesπ  mul   yπ  add   di, axπ  mov   ax, $102π  and   cl, 3π  shl   ah, cl      {make bit mask}π  mov   bh, tsyπ  mov   dx, seqPortπ @DOLINE:π  mov   ch, tsxπ  push  axπ  push  di    {save starting bit mask}π @LOOP:π  mov   al, 2π  mov   dx, seqPortπ  out   dx, axπ  shl   ah, 1π  xchg  ah, clπ  mov   al, 4π  mov   dl, gcPort and $FFπ  out   dx, axπ  xchg  ah, clπ  inc   clπ  and   cl, 3π  lodsbπ  or    al, alπ  jz    @SKIPπ  mov   bl, es:[di]π  cmp   bl, $C0π  jae   @SKIPπ  stosbπ  dec   diπ @SKIP:π  test  ah, $10π  jz    @SAMEByteπ  mov   ah, 1π  inc   diπ @SAMEByte:π  dec   chπ  jnz   @LOOPπ  pop   diπ  add   di, vxBytesπ  pop   ax {start of next line}π  dec   bhπ  jnz   @DOLINEπ  pop   dsπend;ππ{won't handle Chars wider than 1 Byte}πProcedure putChar(x, y : Integer; p : Word); Assembler;πAsmπ  mov   si, p  {offset of Char in DS}π  mov   ax, vSegπ  mov   es, axπ  mov   di, xπ  mov   cx, diπ  shr   di, 2π  mov   ax, vxBytesπ  mul   yπ  add   di, axπ  mov   ax, $0102π  and   cl, 3π  shl   ah, cl      {make bit mask}π  mov   dx, seqPortπ  mov   cl, tsyπ  xor   ch, chπ @DOLINE:π  mov   bl, [si]π  inc   siπ  push  axπ  push  di    {save starting bit mask}π @LOOP:π  mov   al, 2π  out   dx, axπ  shl   ah, 1π  shl   bl, 1π  jnc   @SKIPπ  mov   al, colorπ  mov   es:[di], alπ @SKIP:π  test  ah, $10π  jz    @SAMEByteπ  mov   ah, 1π  inc   diπ @SAMEByte:π  or    bl, blπ  jnz   @LOOPπ  pop   diπ  add   di, vxBytesπ  pop   ax {start of next line}π  loop  @DOLINEπend;ππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππProcedure setColor(color, r, g, b : Byte); Assembler;πAsm {set DAC color}π  mov  dx, tableWriteIndexπ  mov  al, colorπ  out  dx, alπ  inc  dxπ  mov  al, rπ  out  dx, alπ  mov  al, gπ  out  dx, alπ  mov  al, bπ  out  dx, alπend; {Write index now points to next color}ππFunction getColor(color : Byte) : LongInt; Assembler;πAsm {get DAC color}π  mov  dx, tableReadIndexπ  mov  al, colorπ  out  dx, alπ  add  dx, 2π  cldπ  xor  bh, bhπ  in   al, dxπ  mov  bl, alπ  in   al, dxπ  mov  ah, alπ  in   al, dxπ  mov  dx, bxπend; {read index now points to next color}ππProcedure setPalette(color : Byte; num : Word; Var rgb); Assembler;πAsmπ  mov   cx, numπ  jcxz  @Xπ  mov   ax, cxπ  shl   cx, 1π  add   cx, ax {mul by 3}π  push  dsπ  lds   si, rgbπ  cldπ  mov   dx, tableWriteIndexπ  mov   al, colorπ  out   dx, alπ  inc   dxπ @L:π  lodsbπ  out   dx, alπ  loop  @Lπ  pop   dsπ @X:πend;ππProcedure getPalette(color : Byte; num : Word; Var rgb); Assembler;πAsmπ  mov   cx, numπ  jcxz  @Xπ  mov   ax, cxπ  shl   cx, 1π  add   cx, ax {mul by 3}π  les   di, rgbπ  cldπ  mov   dx, tableReadIndexπ  mov   al, colorπ  out   dx, alπ  add   dx, 2π @L:π  in    al, dxπ  stosbπ  loop  @Lπ @X:πend;ππ{XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX}ππFunction vgaPresent : Boolean; Assembler;πAsmπ  mov ah, $Fπ  int $10π  mov oldMode, al  { save old Gr mode}π  mov ax, $1A00π  int $10          { check For VGA}π  cmp al, $1Aπ  jne @ERR         { no VGA Bios}π  cmp bl, 7π  jb @ERR          { is VGA or better?}π  cmp bl, $FFπ  jnz @OKπ @ERR:π  xor al, alπ  jmp @EXITπ @OK:π  mov al, 1π @EXIT:πend;ππProcedure Graphbegin;πVarπ  p     : Array [0..255] of tRGB;π  i, j,π  k, l  : Byte;πbeginπ  Asmπ    mov ax, $0013π    int $10π  end;   {set BIOS mode}ππ  l := 0;π  For i := 0 to 5 doπ    For j := 0 to 5 doπ      For k := 0 to 5 doπ      With p[l] doπ      beginπ        r := (i * 63) div 5;π        g := (j * 63) div 5;π        b := (k * 63) div 5;π        inc(l);π      end;ππ  For i := 216 to 255 doπ  With p[i] doπ  beginπ    l := ((i - 216) * 63) div 39;π    r := l;π    g := l;π    b := l;π  end;ππ  setpalette(0, 256, p);π  color := 0;ππ  Asmπ   mov  dx, seqPortπ   mov  ax, $0604π   out  dx, ax            { disable chain 4}π   mov  ax, $0100π   out  dx, ax            { synchronous reset asserted}π   dec  dxπ   dec  dxπ   mov  al, $E3π   out  dx, al            { misc output port at $3C2}π                          { use 25mHz dot clock,  480 lines}π   inc  dxπ   inc  dxπ   mov  ax, $0300π   out  dx, ax            { restart sequencer}π   mov  dx, CrtcPortπ   mov  al, $11π   out  dx, al            { select cr11}π   inc  dxπ   in   al, dxπ   and  al, $7Fπ   out  dx, alπ   dec  dx                { remove Write protect from cr0-cr7}π   mov  si, offset CrtcRegTableπ   mov  cx, CrtcRegLenπ   repz outsw             { set Crtc data}π   mov  ax, vxBytesπ   shr  ax, 1             { Words per scan line}π   mov  ah, alπ   mov  al, $13π   out  dx, ax            { set CrtC offset reg}π  end;ππ  clearGraph;πend;ππProcedure Graphend; Far;πbeginπ  ExitProc := exitSave;π  Asmπ    mov al, oldModeπ    mov ah, 0π    int $10π  end;πend;ππbeginπ  CrtcPort   := memw[$40 : $63];π  input1Port := CrtcPort + 6;π  if vgaPresent thenπ  beginπ    ExitSave := exitProc;π    ExitProc := @Graphend;π    Graphbegin;π  endπ  elseπ  beginπ    Writeln(^G + 'VGA required.');π    halt(1);π  end;πend.π                                                                     30     10-28-9311:35ALL                      NORMAN YEN               View PCX File            IMPORT              28     ╓ªé {===========================================================================πDate: 08-23-93 (08:26)πFrom: NORMAN YENπSubj: RE: .PCX AND COMM ROUTINEπ---------------------------------------------------------------------------ππ MB> I heard something in this echo about someone having Pascal source toπ MB> view .PCXπ MB> files and I would appreciate if they would re-post the source if it'sπ MB> not tooπ MB> long or tell me where I can get it.  I am also looking for some goodπ MB> COMM routines for Pascal, anyone have any or no where I can get some?ππ        The routine I have will only work with 320x200x256c images.πHope it helps!ππNormanππ{π        For all those Pascal programmers who just want something simpleπ        to display a 320x200x256 colour PCX file on the screen here it is.π        This was a direct translation from the C source code of PCXVIEWπ        written by Lee Hamel (Patch), Avalanche coder.  I removed theπ        inline assembly code so that you beginners can see what was goingπ        on behind those routines.ππ                                                      Norman Yenπ                                                      Infinite Dreams BBSπ                                                      August 11, 1993π}ππtype pcxheader_rec=recordπ     manufacturer: byte;π     version: byte;π     encoding: byte;π     bits_per_pixel: byte;π     xmin, ymin: word;π     xmax, ymax: word;π     hres: word;π     vres: word;π     palette: array [0..47] of byte;π     reserved: byte;π     colour_planes: byte;π     bytes_per_line: word;π     palette_type: word;π     filler: array [0..57] of byte;π     end;ππvar header: pcxheader_rec;π    width, depth: word;π    bytes: word;π    palette: array [0..767] of byte;π    f: file;π    c: byte;ππprocedure Read_PCX_Line(vidoffset: word);πvar c, run: byte;π    n: integer;π    w: word;πbeginπ  n:=0;π  while (n < bytes) doπ  beginπ    blockread (f, c, 1);ππ    { if it's a run of bytes field }π    if ((c and 192)=192) thenπ    beginππ      { and off the high bits }π      run:=c and 63;ππ      { get the run byte }π      blockread (f, c, 1);π      n:=n+run;π      for w:=0 to run-1 doπ      beginπ        mem [$a000:vidoffset]:=c;π        inc (vidoffset);π      end;π    end elseπ    beginπ      n:=n+1;π      mem [$a000:vidoffset]:=c;π      inc (vidoffset);π    end;π  end;πend;ππprocedure Unpack_PCX_File;πvar i: integer;πbeginπ  for i:=0 to 767 doπ    palette [i]:=palette [i] shr 2;π  asmπ    mov ax,13hπ    int 10hπ    mov ax,1012hπ    xor bx,bxπ    mov cx,256π    mov dx,offset paletteπ    int 10hπ  end;π  for i:=0 to depth-1 doπ    Read_PCX_Line (i*320);π  asmπ    xor ax,axπ    int 16hπ    mov ax,03hπ    int 10hπ  end;πend;ππbeginπ  if (paramcount > 0) thenπ  beginπ    assign (f, paramstr (1));π    reset (f,1);π    blockread (f, header, sizeof (header));π    if (header.manufacturer=10) and (header.version=5) andπ       (header.bits_per_pixel=8) and (header.colour_planes=1) thenπ    beginπ      seek (f, filesize (f)-769);π      blockread (f, c, 1);π      if (c=12) thenπ      beginπ        blockread (f, palette, 768);π        seek (f, 128);π        width:=header.xmax-header.xmin+1;π        depth:=header.ymax-header.ymin+1;π        bytes:=header.bytes_per_line;π        Unpack_PCX_File;π      end else writeln ('Error reading palette.');π    end else writeln ('Not a 256 colour PCX file.');π    close (f);π  end else writeln ('No file name specified.');πend.ππ    31     10-28-9311:39ALL                      BAS VAN GALLEN           Another STARS            IMPORT              29     ╓dn {===========================================================================π BBS: Canada Remote SystemsπDate: 10-17-93 (23:26)πFrom: BAS VAN GAALENπSubj: Stars?ππ{$N+}ππprogram _Rotation;ππusesπ  crt,dos;ππconstπ  NofPoints = 75;π  Speed = 5;π  Xc : real = 0;π  Yc : real = 0;π  Zc : real = 150;π  SinTab : array[0..255] of integer = (π    0,2,5,7,10,12,15,17,20,22,24,27,29,31,34,36,38,41,43,45,47,49,52,54,π    56,58,60,62,64,66,67,69,71,73,74,76,78,79,81,82,83,85,86,87,88,90,91,π    92,93,93,94,95,96,97,97,98,98,99,99,99,100,100,100,100,100,100,100,π    100,99,99,99,98,98,97,97,96,95,95,94,93,92,91,90,89,88,87,85,84,83,π    81,80,78,77,75,73,72,70,68,66,65,63,61,59,57,55,53,51,48,46,44,42,40,π    37,35,33,30,28,26,23,21,18,16,14,11,9,6,4,1,-1,-4,-6,-9,-11,-14,-16,π    -18,-21,-23,-26,-28,-30,-33,-35,-37,-40,-42,-44,-46,-48,-51,-53,-55,π    -57,-59,-61,-63,-65,-66,-68,-70,-72,-73,-75,-77,-78,-80,-81,-83,-84,π    -85,-87,-88,-89,-90,-91,-92,-93,-94,-95,-95,-96,-97,-97,-98,-98,-99,π    -99,-99,-100,-100,-100,-100,-100,-100,-100,-100,-99,-99,-99,-98,-98,π    -97,-97,-96,-95,-94,-93,-93,-92,-91,-90,-88,-87,-86,-85,-83,-82,-81,π    -79,-78,-76,-74,-73,-71,-69,-67,-66,-64,-62,-60,-58,-56,-54,-52,-49,π    -47,-45,-43,-41,-38,-36,-34,-31,-29,-27,-24,-22,-20,-17,-15,-12,-10,π    -7,-5,-2,0);ππtypeπ  PointRec = recordπ               X,Y,Z : integer;π             end;π  PointPos = array[0..NofPoints] of PointRec;ππvarπ  Point : PointPos;ππ{----------------------------------------------------------------------------}ππprocedure SetGraphics(Mode : byte); assembler;πasm mov AH,0; mov AL,Mode; int 10h; end;ππ{----------------------------------------------------------------------------}ππprocedure Init;ππvarπ  I : byte;ππbeginπ  randomize;π  for I := 0 to NofPoints do beginπ    Point[I].X := random(250)-125;π    Point[I].Y := random(250)-125;π    Point[I].Z := random(250)-125;π  end;πend;ππ{----------------------------------------------------------------------------}ππprocedure DoRotation;ππconstπ  Xstep = 1;π  Ystep = 1;π  Zstep = -2;ππvarπ  Xp,Yp : array[0..NofPoints] of word;π  X,Y,Z,X1,Y1,Z1 : real;π  PhiX,PhiY,PhiZ : byte;π  I,Color : byte;ππfunction Sinus(Idx : byte) : real;ππbeginπ  Sinus := SinTab[Idx]/100;πend;ππfunction Cosinus(Idx : byte) : real;ππbeginπ  Cosinus := SinTab[(Idx+192) mod 255]/100;πend;ππbeginπ  PhiX := 0; PhiY := 0; PhiZ := 0;π  repeatπ    while (port[$3da] and 8) <> 8 do;π    while (port[$3da] and 8) = 8 do;π    for I := 0 to NofPoints do beginππ      if (Xp[I]+160 < 320) and (Yp[I]+100 < 200) thenπ        mem[$a000:(Yp[I]+100)*320+Xp[I]+160] := 0;ππ      X1 := Cosinus(PhiY)*Point[I].X-Sinus(PhiY)*Point[I].Z;π      Z1 := Sinus(PhiY)*Point[I].X+Cosinus(PhiY)*Point[I].Z;π      X := Cosinus(PhiZ)*X1+Sinus(PhiZ)*Point[I].Y;π      Y1 := Cosinus(PhiZ)*Point[I].Y-Sinus(PhiZ)*X1;π      Z := Cosinus(PhiX)*Z1-Sinus(PhiX)*Y1;π      Y := Sinus(PhiX)*Z1+Cosinus(PhiX)*Y1;ππ      Xp[I] := round((Xc*Z-X*Zc)/(Z-Zc));π      Yp[I] := round((Yc*Z-Y*Zc)/(Z-Zc));π      if (Xp[I]+160 < 320) and (Yp[I]+100 < 200) then beginπ        Color := 31+round(Z/7);π        if Color > 31 then Color := 31π        else if Color < 16 then Color := 16;π        mem[$a000:(Yp[I]+100)*320+Xp[I]+160] := Color;π      end;ππ      inc(Point[I].Z,Speed); if Point[I].Z > 125 then Point[I].Z := -125;π    end;π    inc(PhiX,Xstep);π    inc(PhiY,Ystep);π    inc(PhiZ,Zstep);π  until keypressed;πend;ππ{----------------------------------------------------------------------------}ππbeginπ  SetGraphics($13);π  Init;π  DoRotation;π  textmode(lastmode);πend.ππ      32     11-02-9304:50ALL                      STEVE BOUTILIER          Simple & QUICK Graphics  IMPORT              8      ╓>╝ { STEVE BOUTILIER }ππUsesπ  Dos,π  Crt;ππProcedure OpenGraphics; Assembler;πAsmπ  Mov Ah, 00hπ  Mov Al, 13hπ  Int $10πend;ππProcedure CloseGraphics; Assembler;πAsmπ  Mov Ah, 00hπ  Mov Al, 03hπ  Int $10πend;ππProcedure PutXY(X, Y : Byte); Assembler;πAsmπ  Mov Ah, 02hπ  Mov Dh, Y - 1π  Mov Dl, X - 1π  Mov Bh, 0π  Int $10πend;ππProcedure OutChar(S : Char; Col : Byte); Assembler;πAsmπ  Mov Ah, 0Ehπ  Mov Al, Sπ  Mov Bh, 0π  Mov Bl, Colπ  Int $10πend;ππProcedure OutString(S : String; Col : Byte);πVarπ I  : Integer;π Ch : Char;πbeginπ  For I := 1 to Length(s) doπ  beginπ   Ch := S[I];π   OutChar(Ch, Col);π  end;πend;ππbeginπ  OpenGraphics;π  OutString('HELLO WORLD!' + #13#10, 14);π  Repeat Until KeyPressed;π  CloseGraphics;πend.ππ{πBTW: This code is Public Domain! Do what you want With it! most of youπ     probably already have routines that are even better than this.π}ππ                   33     11-02-9305:30ALL                      NORMAN YEN               Display PCX Files        IMPORT              26     ╓æà {π> I heard something in this echo about someone having Pascal source to viewπ> .PCX Files and I would appreciate if they would re-post the source if it'sπ> not too long or tell me where I can get it.  I am also looking For someπ> good COMM routines For Pascal, anyone have any or no where I can get some?ππThe routine I have will only work With 320x200x256c images.ππ        For all those Pascal Programmers who just want something simpleπ        to display a 320x200x256 colour PCX File on the screen here it is.π        This was a direct translation from the C source code of PCXVIEWπ        written by Lee Hamel (Patch), Avalanche coder.  I removed theπ        Inline assembly code so that you beginners can see what was goingπ        on behind those routines.ππNorman Yen - Infinite Dreams BBS - August 11, 1993π}ππTypeπ  pcxheader_rec = Recordπ    manufacturer   : Byte;π    version        : Byte;π    encoding       : Byte;π    bits_per_pixel : Byte;π    xmin, ymin     : Word;π    xmax, ymax     : Word;π    hres, vres     : Word;π    palette        : Array [0..47] of Byte;π    reserved       : Byte;π    colour_planes  : Byte;π    Bytes_per_line : Word;π    palette_Type   : Word;π    filler         : Array [0..57] of Byte;π  end;ππVarπ  header  : pcxheader_rec;π  width,π  depth   : Word;π  Bytes   : Word;π  palette : Array [0..767] of Byte;π  f       : File;π  c       : Byte;ππProcedure Read_PCX_Line(vidoffset : Word);πVarπ  c, run : Byte;π  n      : Integer;π  w      : Word;πbeginπ  n := 0;π  While (n < Bytes) doπ  beginπ    blockread (f, c, 1);π    { if it's a run of Bytes field }π    if ((c and 192) = 192) thenπ    beginπ      { and off the high bits }π      run := c and 63;π      { get the run Byte }π      blockread (f, c, 1);π      n := n + run;π      For w := 0 to run - 1 doπ      beginπ        mem[$a000 : vidoffset] := c;π        inc(vidoffset);π      end;π    endπ    elseπ    beginπ      n := n + 1;π      mem[$a000 : vidoffset] := c;π      inc(vidoffset);π    end;π  end;πend;ππProcedure Unpack_PCX_File;πVarπ  i : Integer;πbeginπ  For i := 0 to 767 doπ    palette[i] := palette[i] shr 2;π  Asmπ    mov ax, 13hπ    int 10hπ    mov ax, 1012hπ    xor bx, bxπ    mov cx, 256π    mov dx, offset paletteπ    int 10hπ  end;π  For i := 0 to depth - 1 doπ    Read_PCX_Line(i * 320);π  Asmπ    xor ax, axπ    int 16hπ    mov ax, 03hπ    int 10hπ  end;πend;ππbeginπ  if (paramcount > 0) thenπ  beginπ    assign(f, paramstr(1));π    reset(f, 1);π    blockread (f, header, sizeof(header));π    if (header.manufacturer = 10) and (header.version = 5) andπ       (header.bits_per_pixel = 8) and (header.colour_planes = 1) thenπ    beginπ      seek(f, Filesize(f) - 769);π      blockread(f, c, 1);π      if (c = 12) thenπ      beginπ        blockread(f, palette, 768);π        seek(f, 128);π        width := header.xmax - header.xmin + 1;π        depth := header.ymax - header.ymin + 1;π        Bytes := header.Bytes_per_line;π        Unpack_PCX_File;π      endπ      elseπ        Writeln('Error reading palette.');π    endπ    elseπ      Writeln('Not a 256 colour PCX File.');π    close(f);π  endπ  elseπ    Writeln('No File name specified.');πend.π                                34     11-02-9305:31ALL                      DAVE FOSTER              Display PIC Files        IMPORT              27     ╓    ⌐ {πDave Fosterππ> Could anyone please post any routines or help on howπ> to read an image into TURBO 6. I can save the imageπ> in any format, but i need code to be able to displayπ> it on the screen. Source code would be an advantage!π>πI wrote this Program For a friend to read a image into his Program, andπand I would be happy For any help on how to improve it.π}ππProgram  Read_Image;      { SRC-CODE.PAS   ver 1.00 }π{-----------------------------------------------------------------------------π Program reads in a binary data File, and displays the image on the screen byπ using "PutPixel" Procedure in the Graph Unit.  The image can be displayed inπ color, or in grey-scale by using the subroutine "Set64Gray" below.π This is a quick and dirty method to display the image using "PutPixel",π and I hope someone will be able to show us how to use the "PutImage" toπ display the image quicker.π-----------------------------------------------------------------------------}ππUsesπ  Dos, Crt, Graph;ππTypeπ  ByteArray = Array [0..175] of Byte;ππVarπ  Gd, Gm,π  m, n    : Integer;π  buffer  : ByteArray;π  f       : File;ππ{π> Does anyone know how can I get a Graphic mode in VGA in which Iπ> could use 64 gray level (at least 32)?  Could I keep on using theπ> Graphical Procedures in Unit Graph then?ππ The fragment below will initialize the first 64 VGA color values toπ gray scale.  These colors are valid For any VGA mode (including Text),π but in most Graphics modes/devices the Borland Graph Unit limits youπ to using only 16 colors.π}ππProcedure Set64Gray;π{ Sets up 64 shades of gray where 0 = black, 63 = full white }πTypeπ  CRec = Recordπ    R, G, B: Byte;π  end;πVarπ  Regs : Registers;π  I    : Integer;π  G64  : Array [0..63] of CRec;πbeginπ  { Initialize the block of color values }π  For I := 0 to 63 doπ  With G64[I] doπ  beginπ    R := I;π    G := I;          { Color is gray when RGB values are equal }π    B := I;π  end;ππ  Regs.ax := $1012;      { Dos Function to update block of colors }π  Regs.bx := 0;          { First color to change }π  Regs.cx := 64;         { Number of colors to change }π  Regs.es := seg(G64); { Address of block of color values }π  Regs.dx := ofs(G64);π  intr($10, Regs);πend;ππbeginπ  Gd := detect;π  initGraph(Gd, Gm, 'e:\bp\bgi');ππ  { Open the image File which is 250 lines, and 175 pixels per line.π    Each pixel is 1 Byte, and no header data, or Record delimiters.π    File is 43,750 Bytes (250 x 175) in size.  Have look at the inputπ    File using binary File viewer. }ππ   assign(f, 'DOMINO.DAT');π   reset(f, 175);ππ  { if you enable this, you will be able to see the image in grey-scale,π    but I am not sure if it is quite right.  Currently it seems to displayπ    only few grey-scale levels instead of the full 64 levels.ππ   }Set64Gray;ππ  { Method used to read the File line at a time, and Write the pixelπ    values to the screen. This is bit slow, and it would be lot fasterπ    by using "PutImage" but I do not know the method For that. }ππ   n := 1;π   While not eof(f) doπ   beginπ     BlockRead(f, buffer, 1);π     For m := 1 to 175 doπ       PutPixel(m, n, buffer[m]);π     n := n + 1;π   end;ππ   close(f);π   readln;π   closeGraph;πend.ππ{πThe image File "DOMINO.DAT" used in the Program "SRC-CODE.PAS".πImage File is 250 x 175 pixels (43,750 Bytes).π}ππ 35     11-02-9305:49ALL                      RANDY PARKER             Writing to Graphic Pages IMPORT              9      ╓r {πRANDY PARKERππ    I've been playing With using the Absolute address $A000:0000 to do directπvideo Writes in Graphics mode and was wondering if someone could tell me howπto get colors.  I use an Array of [1..NumOfBits].  NumOfBits being the numberπof bits the current Graphic page Uses when it stores it's information.ππThe following is an example of what I mean:π}ππProgram UseFastGraf;πUsesπ  Graph;ππTypeπ  View = Array [1..19200] of Word;ππVarπ  I,π  GraphDriver,π  GraphMode    : Integer;π  View1        : View Absolute $A000:0000;π  View2        : View;ππbeginπ  GraphDriver := Detect;π  InitGraph(GraphDriver, GraphMode, 'e:\bp\bgi');π  For I := 1 to 1000 Doπ  beginπ    SetColor(Random(GetMaxColor));π    Line(Random(GetMaxX), Random(GetMaxY), Random(GetMaxX), GetMaxY);π  end;π  View2 := View1;π  SetColor(15);π  OutTextXY(100, 100, 'Press Enter To Continue : ');π  Readln;π  ClearDevice;π  OutTextXY(100, 100, 'Press Enter To See The Previous Screen');π  Readln;π  View1 := View2;π  Readln;πend.ππ                36     11-02-9305:52ALL                      VINCE LAURENT            Scalable HEX Screen      IMPORT              25     ╓╥ {πVINCE LAURENTππI wrote some code to draw a scalable hex field on the screen. Canπanyone give me a hand in optimizing it? There is a lot of redundantπline drawing and positioning... I would also like to be able to haveπa fexible amount of hexigons showing.  For example, if the scale is,πsay 40, show 19 hexs, if it is smaller, show more (like as many thatπcould have fit in the area occupied by 19).ππBTW, this code can be freely used and distributed or completely ignored :-) }ππProgram HexzOnScreen;πUsesπ  Graph, Crt;πTypeπ  PtArray = Array [1..6, 1..2] of Real;πVarπ  s1, s2,π  side,π  i, j,π  Gd, Gm  : Integer;π  Pts     : PtArray;π  ErrCode : Integer;π  Sqrt3,π  sts     : Real;ππbeginπ  Sqrt3 := Sqrt(3);π  Side  := 40;             { initial hex side length ( min = 8 ) }π  sts   := Side * Sqrt3;π  s1    := 200;π  s2    := 60;     { starting point For hex field }π  InitGraph(Gd, Gm, 'e:\bp\bgi\');π  ErrCode := GraphResult;π  if not ErrCode = grOk thenπ  beginπ    Writeln('Error: ', GraphErrorMsg(ErrCode));π    Halt(0);π  end;π  SetColor(LightGray);π  Delay(10);   { give the screen a chance to toggle to Graph mode }π  For j := 1 to 17 DOπ  beginπ    Pts[1, 1] := s1;π    Pts[1, 2] := s2;π    Pts[2, 1] := Pts[1, 1] - side;π    Pts[2, 2] := Pts[1, 2];π    Pts[3, 1] := Pts[1, 1] - side - (side / 2);π    Pts[3, 2] := Pts[1, 2] + (sts / 2);π    Pts[4, 1] := Pts[1, 1] - side;π    Pts[4, 2] := Pts[1, 2] + sts ;π    Pts[5, 1] := Pts[1, 1];π    Pts[5, 2] := Pts[4, 2];π    Pts[6, 1] := Pts[1, 1] + (side / 2);π    Pts[6, 2] := Pts[1, 2] + (sts  / 2);π    For I := 1 to 6 DOπ    beginπ      if i <> 6 thenπ        Line(Round(Pts[i, 1]),  Round(Pts[i, 2]),π             Round(Pts[i + 1, 1]), Round(Pts[i + 1, 2]))π      elseπ        Line(Round(Pts[i, 1]), Round(Pts[i, 2]),π             Round(Pts[1, 1]), Round(Pts[1, 2]));π    end;π    Case j OFπ      1..2 :π      beginπ        s1 := Round(Pts[6, 1] + side);π        s2 := Round(Pts[6, 2]);π      end;π      3..4 :π      beginπ        s1 := Round(Pts[5, 1]);π        s2 := Round(Pts[5, 2]);π      end;π      5..6 :π      beginπ        s1 := Round(Pts[3, 1]);π        s2 := Round(Pts[3, 2]);π      end;π      7..8 :π      beginπ        s1 := Round(Pts[3, 1]);π        s2 := Round(Pts[3, 2] - sts);π      end;π      9..10 :π      beginπ        s1 := Round(Pts[1, 1]);π        s2 := Round(Pts[1, 2] - sts);π      end;π      11 :π      beginπ        s1 := Round(Pts[6, 1] + side);π        s2 := Round(Pts[6, 2] - sts);π      end;π      12..13 :π      beginπ        s1 := Round(Pts[6, 1] + side);π        s2 := Round(Pts[6, 2]);π      end;π      14 :π      beginπ        s1 := Round(Pts[5, 1]);π        s2 := Round(Pts[5, 2]);π      end;π      15 :π      beginπ        s1 := Round(Pts[3, 1]);π        s2 := Round(Pts[3, 2]);π      end;π      16 :π      beginπ        s1 := Round(Pts[3, 1]);π        s2 := Round(Pts[3, 2] - sts);π      end;π    end;π  end;π  Line(s1, s2, Round(s1 + (side / 2)), Round(s2 - sts / 2));π  Readln;π  CloseGraph;πend.π                                                                     37     11-02-9305:54ALL                      NICK ONOUFRIOU           Quick PutImage           IMPORT              22     ╓╨a {πNICK ONOUFRIOUππI'm writing a small game that requires a transparent putimage Function. Iπnormally use the BGI, but in this Case I need a little bit more speed. Thisπpartial Program shows what I have already. What I want to know is there isπsimple method of masking color 0 so it won't be displayed.π}πProgram PutMan;ππUsesπ  Dos, Crt;ππConstπ(* Turbo Pascal, Width= 11 Height= 23 Colors= 256 *)ππ  Man : Array [1..259] of Byte = (π          $0A,$00,$16,$00,$00,$00,$00,$00,$00,$00,$00,$00,π          $00,$00,$00,$00,$00,$00,$00,$02,$02,$02,$00,$00,π          $00,$00,$00,$00,$00,$02,$02,$02,$02,$02,$00,$00,π          $00,$00,$00,$02,$2C,$2C,$2C,$2C,$2C,$02,$00,$00,π          $00,$00,$2C,$10,$10,$2C,$10,$10,$2C,$00,$00,$00,π          $00,$2C,$2C,$2C,$2C,$2C,$2C,$2C,$00,$00,$00,$00,π          $00,$2C,$0C,$0C,$0C,$2C,$00,$00,$00,$00,$00,$00,π          $00,$2C,$2C,$2C,$00,$00,$00,$00,$00,$00,$00,$00,π          $00,$0F,$00,$00,$00,$00,$00,$00,$0F,$00,$00,$0F,π          $0F,$0F,$00,$00,$00,$00,$00,$0F,$00,$0D,$0D,$0D,π          $0D,$0D,$00,$00,$00,$00,$0F,$0D,$0D,$0D,$0D,$0D,π          $0D,$0D,$00,$00,$00,$0F,$1F,$1F,$1F,$1F,$1F,$1F,π          $1F,$0F,$00,$00,$00,$1F,$1F,$1F,$1F,$1F,$1F,$1F,π          $0F,$00,$00,$00,$00,$1F,$1F,$1F,$1F,$1F,$00,$0F,π          $00,$00,$00,$00,$00,$0D,$0D,$0D,$00,$00,$0F,$00,π          $00,$00,$00,$0D,$0D,$0D,$0D,$0D,$00,$00,$00,$00,π          $00,$00,$0D,$0D,$0D,$0D,$0D,$00,$00,$00,$00,$00,π          $00,$0D,$0D,$00,$0D,$0D,$00,$00,$00,$00,$00,$00,π          $0D,$0D,$00,$0D,$0D,$00,$00,$00,$00,$00,$00,$07,π          $07,$00,$07,$07,$00,$00,$00,$00,$00,$00,$07,$07,π          $00,$07,$07,$00,$00,$00,$00,$00,$00,$00,$00,$00,π          $00,$00,$00,$00,$00,$00,$00);ππTypeπ  _screenRec = Array [0..199, 0..319] of Byte;ππVarπ  _mcgaScreen  : _screenRec Absolute $A000:0000;πππProcedure SetMode(mode : Integer);πVarπ  regs : Registers;πbeginπ  regs.ah := 0;π  regs.al := mode;π  intr($10, regs);πend;ππProcedure ClearPage(color : Integer);πbeginπ  FillChar(_mcgaScreen, 64000, color);πend;ππProcedure PutImg(x, y : Integer; Var Img);πTypeπ  AList = Array[1..$FFFF] of Byte;πVarπ  APtr      : ^AList;π  J, Width,π  Height,π  Counter   : Word;πbeginπ  Aptr    := @Img;π  Width   := (Aptr^[2] SHL 8) + Aptr^[1] + 1;π  Height  := (Aptr^[4] SHL 8) + Aptr^[3] + 1;π  Counter := 5;π  For j := y to (y + height - 1) doπ  beginπ    Move(Aptr^[Counter], _mcgaScreen[j, x], Width);π    Inc(Counter, Width);π  end;πend;ππbeginπ  SetMode(19);π  ClearPage(Blue);π  PutImg(150, 80, Ptr(seg(man), ofs(man))^);π  readln;π  SetMode(3);πend.π                                                                                                                        38     11-02-9305:55ALL                      STEFAN XENOS             Loading Images from Disk IMPORT              27     ╓¡ {πSTEFAN XENOSππ> I am able to load an image into a buffer and display it with PutImage ect.,π> but I would like to load the image from disk instead of with getimage.ππName: ImageStuff.PasπPurpose: ImageStuff is a unit for storing bitmaps in dynamic variables andπ         writing them to disk.πProgger: Stefan XenosππThis unit is public domain.}ππUnit ImageStuff;ππinterfaceππUsesπ Graph;ππTypeπ  Image = Recordπ    BitMap : Pointer;π    Size   : Word;π end;ππProcedure Get(X1, Y1, X2, Y2 : Word; Var aImage : Image);πProcedure Put(X, Y : Word; aImage : Image; BitBlt : Word);πProcedure Kill(Var aImage : Image);πProcedure Save(Var F : File; aImage : Image);πProcedure Load(Var F : File; Var aImage : Image);ππimplementationππProcedure Get(X1, Y1, X2, Y2 : Word; Var aImage : Image);π{Clips an image from the screen and store it in a dynamic variable}πBeginπ  aImage.bitmap := nil;π  aImage.size   := ImageSize(X1, Y1, X2, Y2);π  GetMem(aImage.BitMap,aImage.Size);    {Ask for some memory}π  GetImage(X1, Y1, X2, Y2, aImage.BitMap^); {Copy the image}πEnd;ππProcedure Put(X, Y : Word; aImage : Image; BitBlt : Word);πBeginπ  PutImage(X, Y, aImage.BitMap^, BitBlt);   {Display image}πEnd;ππProcedure Kill(Var aImage : Image);π{Frees up the memory used by an unwanted image}πBeginπ  FreeMem (aImage.BitMap, aImage.Size); {Free up memory used by image}π  aImage.Size   := 0;π  aImage.BitMap := Nil;πEnd;ππProcedure Save(Var F : File; aImage : Image);π{Saves an image to disk. File MUST already be opened for write}πBeginπ  BlockWrite(F, aImage.Size, 2);             {Store the image's size so thatπ                                            it may be correctly loaded later}π  BlockWrite(F, aImage.BitMap^, aImage.Size); {Write image itself to disk}πEnd;ππProcedure Load (Var F : File; Var aImage : Image);π{Loads an image off disk and stores it in a dynamic variable}πBeginπ BlockRead(F, aImage.Size, 2);              {Find out how big the image is}π GetMem(aImage.BitMap, aImage.Size);        {Allocate memory for it}π BlockRead(F, aImage.BitMap^, aImage.Size)  {Load the image}πEnd;ππBeginπEnd.ππ{πHere's some source which should help you figure out how to use the unit Iπjust sent.π}ππ{By Stefan Xenos}πProgram ImageTest;ππUsesπ  Graph,π  ImageStuff;ππVarπ  Pic      : Image;π  LineNum  : Byte;π  DataFile : File;π  GrDriver,π  GrMode   : Integer;ππConstπ FileName = 'IMAGE.DAT';π MaxLines = 200;ππBeginπ {Initialise}π DetectGraph(GrDriver, GrMode);π InitGraph(GrDriver, GrMode, '');π Randomize;ππ {Draw some lines}π For LineNum := 1 to MaxLines doπ beginπ   setColor(random (maxcolors));π   line(random(getmaxx), random(getmaxy), random(getmaxx), random(getmaxy));π end;ππ {Copy image from screen}π Get(100, 100, 150, 150, Pic);ππ readLn;ππ {Clear screen}π ClearDevice;ππ {Display image}π Put(100, 100, Pic, NormalPut);ππ readLn;ππ {Clear screen}π ClearDevice;ππ {Save image to disk}π Assign(DataFile, FileName);π Rewrite(DataFile, 1);π Save(DataFile, Pic);π Close(DataFile);ππ {Kill image}π Kill(pic);ππ {Load image from disk}π Assign(DataFile, FileName);π Reset(DataFile, 1);π Load(DataFile, pic);π Close(DataFile);ππ {Display image}π Put(200, 200, Pic, NormalPut);ππ readLn;ππ CloseGraph;π WriteLn(Pic.size);πEnd.π                                                                                                            39     11-02-9305:56ALL                      SEAN PALMER              Another QUICK PutImage   IMPORT              18     ╓py (*πSEAN PALMERππ> there is simple method of masking color 0 so it won't be displayed.π> An assembly language routine based around this:ππProcedure PutImg(x, y : Integer; Var Img);πTypeπ  AList = Array[1..$FFFF] of Byte; {1-based Arrays are slower than 0-based}πVarπ  APtr    : ^AList; {I found a very fast way to do this: With}π  j, i,π  Width,π  Height,π  Counter : Word;πbeginπ  Aptr    := @Img;π  Width   := (Aptr^[2] SHL 8) + Aptr^[1] + 1; {these +1's that 1-based Arrays }π  Height  := (Aptr^[4] SHL 8) + Aptr^[3] + 1; { require make For slower code}π  Counter := 5;π  For j := y to (y + height - 1) doπ  begin  {try pre-calculating the offset instead}π    For i := x to (x + width - 1) doπ    beginπ      Case Aptr^[Counter] of {CASE is probably not the way to do this}π        0:; { do nothing }π      else _mcgaScreen[j, i] := Aptr^[Counter]; { plot it }π      end;π      Inc(Counter);π    end;π  end;πend;ππok, here's my try:π*)ππTypeπ  pWord = ^Word;ππProcedure putImg(x, y : Integer; Var image);πVarπ  anImg : Recordπ    img : Array [0..$FFF7] of Byte;π  end Absolute image;ππ  aScrn : Recordπ    scrn : Array [0..$FFF7] of Byte;π  end Absolute $A000 : 0000;ππ  width,π  height,π  counter,π  offs, src : Word;ππbeginπ  width  := pWord(@anImg[0])^;π  height := pWord(@anImg[2])^;π  offs   := y * 320 + x;π  src    := 4;   {skip width, height}π  With aScrn, anImg doπ  Repeatπ    counter := width;π    Repeatπ      if img[src] <> 0 thenπ        scrn[offs] := img[src];π      inc(src);π      inc(offs);π      dec(counter);π    Until counter = 0;π    inc(offs, 320 - width);π    dec(height);π  Until height = 0;πend;ππ{πThose Arrays-pretending-to-be-Records above so they'll work With the Withπstatement should end up making BP keep the address in Registers, making itπfaster. In any Case it won't be slower than yours. I'd appreciate youπtiming them and letting me know the results. Actually, let me know if itπeven compiles and works... 8)ππBut Really, man, if you're writing Graphics routines you Really have toπgo For assembly. Pascal don't cut it. (c doesn't either...)π}π                                                                                            40     11-02-9306:11ALL                      KEVIN OTTO               Fading                   IMPORT              11     ╓Q { KEVIN OTTO }ππUnit Fade;ππ{ Change DelayAmt and Steps to change the speed of fading. }ππInterfaceππUsesπ  Dos, Crt;ππConstπ  Colors   = 64;π  DelayAmt = 15;π  Steps    = 24;ππTypeπ  PalType = Array [0..Colors - 1] of Recordπ    R, G, B : Byte;π  end;ππVarπ  OrigPal : palType;ππProcedure GetPal(Var OrigPal : PalType);πProcedure FadePal(OrigPal : PalType; FadeOut : Boolean);ππImplementationππProcedure GetPal(Var OrigPal : PalType);πVarπ  Reg : Registers;πbeginπ  With Reg doπ  beginπ    AX := $1017;π    BX := 0;π    CX := colors;π    ES := seg(OrigPal);π    DX := ofs(OrigPal);π    intr ($10, Reg);π  end;πend;ππProcedure FadePal(OrigPal : PalType; FadeOut : Boolean);πVarπ  Reg     : Registers;π  WorkPal : PalType;π  Fade    : Word;π  Pct     : Real;π  I       : Word;πbeginπ  With Reg doπ  For Fade := 0 to Steps doπ  beginπ    Pct := Fade / Steps;π    if FadeOut thenπ      Pct := 1 - Pct;π    For I := 0 to Colors - 1 doπ    With WorkPal[I] doπ    beginπ      R := round(OrigPal[I].R * Pct);π      G := round(OrigPal[I].G * Pct);π      B := round(OrigPal[I].B * Pct);π    end;π    AX := $1012;π    BX := 0;π    CX := Colors;π    ES := seg (WorkPal);π    DX := ofs (WorkPal);π    intr ($10, Reg);π    Delay (DelayAmt);π  end;πend;ππend.π                                  41     11-02-9317:24ALL                      SEAN PALMER              Transparent PutImage     IMPORT              15     ╓└! {πFrom: SEAN PALMERπSubj: transparent putimageπ}ππProcedure PutImg(x,y : integer;Var Img);πtypeπ AList = array[1..$FFFF] of Byte; {1-based arrays are slower than 0-based}πvarπ APtr : AList;                   {I found a very fast way to do this: WITH}π j,i,Width,Height,Counter : Word;πbeginπ Aptr:=@Img;π Width:=(Aptr] SHL 8) + Aptr]+1;  {these +1's that 1-based arrays }π Height:=(Aptr] SHL 8) + Aptr]+1;  { require make for slower code}π Counter:=5;π For j:=y to (y+height-1) do begin  {try pre-calculating the offset instead}π  for i:=x to (x+width-1) do beginπ   case AptrCounter] of          {CASE is probably not the way to do this}π    0:; (* do nothing *)π    else _mcgaScreen[j,i]:=AptrCounter]; (* plot it *)π    end;π   Inc(Counter);π   end;π  end;π end;ππok, here's my try:ππtype pWord=word;ππprocedure putImg(x,y:integer;var image);πvarπ anImg:record img:array[0..$FFF7]of byte; end absolute image;π aScrn:record scrn:array[0..$FFF7]of byte; end absolute $A000:0000;π width,height,counter,offs,src:word;πbeginπ width:=pWord(@anImg[0])π height:=pWord(@anImg[2])π offs:=y*320+x;π src:=4;   {skip width, height}π with aScrn,anImg do repeatπ  counter:=width;π  repeatπ   if img[src]<>0 then scrn[offs]:=img[src];π   inc(src);π   inc(offs);π   dec(counter);π   until counter=0;π  inc(offs,320-width);π  dec(height);π  until height=0;π end;πππThose arrays-pretending-to-be-records above so they'll work with the WITHπstatement should end up making BP keep the address in registers, making itπfaster. In any case it won't be slower than yours. I'd appreciate youπtiming them and letting me know the results. Actually, let me know if itπeven compiles and works... 8)π                                                                                                  42     11-02-9317:44ALL                      SEAN PALMER              Bresenham Line           IMPORT              12     ╓n {πFrom: SEAN PALMERπSubj: Bresenham's LineππYou need a plot(x,y) procedure and a global color variable to use these asπposted. }πππ{bresenham's line}πprocedure line(x,y,x2,y2:integer);var d,dx,dy,ai,bi,xi,yi:integer;beginπ if(x<x2)then begin xi:=1;dx:=x2-x;end else begin xi:=-1;dx:=x-x2;end;π if(y<y2)then begin yi:=1;dy:=y2-y;end else begin yi:=-1;dy:=y-y2;end;π plot(x,y);π if dx>dy then begin ai:=(dy-dx)*2;bi:=dy*2; d:=bi-dx;π  repeatπ   if(d>=0)then begin inc(y,yi);inc(d,ai);end else inc(d,bi);π   inc(x,xi);plot(x,y);π   until(x=x2);π  endπ else begin ai:=(dx-dy)*2;bi:=dx*2; d:=bi-dy;π  repeatπ   if(d>=0)then begin inc(x,xi);inc(d,ai);end else inc(d,bi);π   inc(y,yi);plot(x,y);π   until(y=y2);π  end;π end;πππ{filled ellipse}πprocedure disk(xc,yc,a,b:integer);π var x,y:integer; aa,aa2,bb,bb2,d,dx,dy:longint; beginπ x:=0;y:=b;π aa:=longint(a)*a; aa2:=2*aa;π bb:=longint(b)*b; bb2:=2*bb;π d:=bb-aa*b+aa div 4;π dx:=0;dy:=aa2*b;π vLin(xc,yc-y,yc+y);π while(dx<dy)do beginπ  if(d>0)then begin dec(y); dec(dy,aa2); dec(d,dy); end;π  inc(x); inc(dx,bb2); inc(d,bb+dx);π  vLin(xc-x,yc-y,yc+y);vLin(xc+x,yc-y,yc+y);π  end;π inc(d,(3*(aa-bb)div 2-(dx+dy))div 2);π while(y>=0)do beginπ  if(d<0)then beginπ   inc(x); inc(dx,bb2); inc(d,bb+dx);π   vLin(xc-x,yc-y,yc+y);vLin(xc+x,yc-y,yc+y);π   end;π  dec(y); dec(dy,aa2); inc(d,aa-dy);π  end;π end;π                                                          43     11-21-9309:28ALL                      MICHAEL HOENIE           Create Chars in Graphics IMPORT              78     ╓èà π  { This program allows you to create characters using the GRAPHICS unitπ    supplied otherwise with the SWAG routines. If you have any questionsπ    on these routines, please let me know.ππ    MICHAEL HOENIE - Intelec Pascal Moderator.  }ππ  program charedit;ππ  uses dos, crt;ππ  const numnewchars=1;ππ  typeπ    string80=string[80];ππ  var { all variables inside of the game }π    char_map:array[1..16] of string[8];π    xpos,ypos,x,y,z:integer;π    out,incom:string[255];π    charout:char;π    outfile:text;π    char:array[1..16] of byte;ππ    procedure loadchar;π    typeπ      bytearray=array[0..15] of byte;π      chararray=recordπ        charnum:byte;π        chardata:bytearray;π      end;π    varπ      regs:registers;π      newchars:chararray;π    beginπ      with regs doπ        beginπ          ah:=$11;   { video sub-Function $11 }π          al:=$0;    { Load Chars to table $0 }π          bh:=$10;   { number of Bytes per Char $10 }π          bl:=$0;    { Character table to edit }π          cx:=$1;    { number of Chars we're definig $1}π          dx:=176;π          for x:=0 to 15 do newchars.chardata[x]:=char[x+1];π          es:=seg(newchars.chardata);π          bp:=ofs(newchars.chardata);π          intr($10,regs);π        end;π    end;ππ  Procedure FastWrite(Col,Row,Attrib:Byte; Str:string80);π  beginπ    inlineπ      ($1E/$1E/$8A/$86/row/$B3/$50/$F6/$E3/$2B/$DB/$8A/$9E/col/π      $03/$C3/$03/$C0/$8B/$F8/$be/$00/$00/$8A/$BE/attrib/π      $8a/$8e/str/$22/$c9/$74/$3e/$2b/$c0/$8E/$D8/$A0/$49/$04/π      $1F/$2C/$07/$74/$22/$BA/$00/$B8/$8E/$DA/$BA/$DA/$03/$46/π      $8a/$9A/str/$EC/$A8/$01/$75/$FB/$FA/$EC/$A8/$01/$74/$FB/π      $89/$1D/$47/$47/$E2/$Ea/$2A/$C0/$74/$10/$BA/$00/$B0/π      $8E/$DA/$46/$8a/$9A/str/$89/$1D/$47/$47/$E2/$F5/$1F);π  end;ππ  procedure initalize;ππ  beginπ    for x:=1 to 16 do char[x]:=0;π    xpos:=1;π    ypos:=1;π    for x:=1 to 16 do char_map[x]:='        '; { clear it out }π  end;ππ  procedure display_screen;π  beginπ    loadchar;π     fastwrite(1,1,$1F,'         CHAREDIT - By Michael S. Hoenie         ');π     fastwrite(1,2,$7,'      12345678   ┌─────Data');π     fastwrite(1,3,$7,'     ▄▄▄▄▄▄▄▄▄▄  │');π     fastwrite(1,4,$7,'   1 █        █ 000');π     fastwrite(1,5,$7,'   2 █        █ 000 Single:  ░');π     fastwrite(1,6,$7,'   3 █        █ 000');π     fastwrite(1,7,$7,'   4 █        █ 000 Multiple:');π     fastwrite(1,8,$7,'   5 █        █ 000');π     fastwrite(1,9,$7,'   6 █        █ 000     ░░░░░░');π    fastwrite(1,10,$7,'   7 █        █ 000     ░░░░░░');π    fastwrite(1,11,$7,'   8 █        █ 000     ░░░░░░');π    fastwrite(1,12,$7,'   9 █        █ 000                    U            ');π    fastwrite(1,13,$7,'  10 █        █ 000 f1=paint spot      │    MOVEMENT');π    fastwrite(1,14,$7,'  11 █        █ 000 f2=erase spot   L──┼──R         ');π    fastwrite(1,15,$7,'  12 █        █ 000  S=save char       │            ');π    fastwrite(1,16,$7,'  13 █        █ 000  Q=quit editor     D');π    fastwrite(1,17,$7,'  14 █        █ 000  C=reset char    r=scroll-right');π    fastwrite(1,18,$7,'  15 █        █ 000  l=scroll-left');π    fastwrite(1,19,$7,'  16 █        █ 000  r=scroll-right');π    fastwrite(1,20,$7,'     ▀▀▀▀▀▀▀▀▀▀      u=scroll-up');π  end;ππ  procedure calculate_char;π  beginπ    for x:=1 to 16 do char[x]:=0;π    for x:=1 to 16 doπ      beginπ        fastwrite(7,x+3,$4F,char_map[x]);π        incom:=char_map[x];π        y:=0;π        if copy(incom,1,1)='█' then y:=y+1;π        if copy(incom,2,1)='█' then y:=y+2;π        if copy(incom,3,1)='█' then y:=y+4;π        if copy(incom,4,1)='█' then y:=y+8;π        if copy(incom,5,1)='█' then y:=y+16;π        if copy(incom,6,1)='█' then y:=y+32;π        if copy(incom,7,1)='█' then y:=y+64;π        if copy(incom,8,1)='█' then y:=y+128;π        char[x]:=y;π      end;π    for x:=1 to 16 doπ      beginπ        str(char[x],incom);π        while length(incom)<3 do insert(' ',incom,1);π        fastwrite(17,x+3,$4E,incom);π      end;π    loadchar;π  end;ππ  procedure do_online;π  varπ    done:boolean;π    int1,int2,int3:integer;π  beginπππ    done:=false;π    int1:=0;π    int2:=0;π    int3:=0;π    while not done doπ      beginπ        incom:=copy(char_map[ypos],xpos,1);π        int1:=int1+1;π        if int1>150 then int2:=int2+1;π        if int2>4 thenπ          beginπ            int1:=0;π            int3:=int3+1;π            if int3>2 then int3:=1;π            case int3 ofπ              1:fastwrite(xpos+6,ypos+3,$F,incom);π              2:fastwrite(xpos+6,ypos+3,$F,'');π            end;π          end;ππ{ this section moved over to be transferred across the network. }ππif keypressed thenπ  beginπ    charout:=readkey;π    out:=charout;π    if ord(out[1])=0 thenπ      beginπ        charout:=readkey;π        out:=charout;π        fastwrite(60,2,$2F,out);π        case out[1] ofπ          ';':begin { F1 }π                delete(char_map[ypos],xpos,1);π                insert('█',char_map[ypos],xpos);π                calculate_char;π              end;π          '<':begin { F2 }π                delete(char_map[ypos],xpos,1);π                insert(' ',char_map[ypos],xpos);π                calculate_char;π              end;π          'H':begin { up }π                ypos:=ypos-1;π                if ypos<1 then ypos:=16;π                calculate_char;π              end;π          'P':begin { down }π                ypos:=ypos+1;π                if ypos>16 then ypos:=1;π                calculate_char;π              end;π          'K':begin { left }π                xpos:=xpos-1;π                if xpos<1 then xpos:=8;π                calculate_char;π              end;π          'M':begin { right }π                xpos:=xpos+1;π                if xpos>8 then xpos:=1;π                calculate_char;π              end;π        end;π      end elseπππ        begin { regular keys }π          case out[1] ofπ            'Q','q':begin { done }π                      clrscr;π                      write('Are you SURE you want to quit? (Y/n) ? ');π                      readln(incom);π                      case incom[1] ofπ                        'Y','y':done:=true;π                      end;π                      clrscr;π                      display_screen;π                      calculate_char;π                    end;π            'S','s':begin { save }π                      assign(outfile,'chardata.txt');π                      {$i-} reset(outfile) {$i+};π                      if (ioresult)>=1 then rewrite(outfile);π                      append(outfile);π                      writeln(outfile,'Character Char:');π                      writeln(outfile,'');π                      writeln(outfile,'       12345678');π                      for x:=1 to 16 doπ                        beginπ                          str(x,out);π                          while length(out)<6 do insert(' ',out,1);π                          writeln(outfile,out+char_map[x]);π                        end;π                      writeln(outfile,'');π                      write(outfile,'Chardata:');π                      for x:=1 to 15 doπ                        beginπ                          str(char[x],incom);π                          write(outfile,incom+',');π                        end;π                      str(char[16],incom);π                      writeln(outfile,incom);π                      writeln(outfile,'-----------------------------');π                      close(outfile);π                      clrscr;π                      writeln('File was saved under CHARDATA.TXT.');π                      writeln;π                      write('Press ENTER to continue ? ');π                      readln(incom);π                      clrscr;π                      display_screen;π                      calculate_char;π                    end;π            'U','u':begin { move entire char up }π                     incom:=char_map[1];π                     for x:=2 to 16 do char_map[x-1]:=char_map[x];π                     char_map[16]:=incom;π                     calculate_char;π                    end;π            'R','r':begin { move entire char to the right }π                      for x:=1 to 16 doπ                        beginπ                          out:=copy(char_map[x],8,1);π                          incom:=copy(char_map[x],1,7);π                          char_map[x]:=out+incom;π                        end;π                      calculate_char;π                    end;π            'L','l':begin { move entire char to the left }π                      for x:=1 to 16 doπππ                        beginπ                          out:=copy(char_map[x],1,1);π                          incom:=copy(char_map[x],2,7);π                          char_map[x]:=incom+out;π                        end;π                      calculate_char;π                    end;π            'D','d':begin { move entire char down }π                      incom:=char_map[16];π                      for x:=16 downto 2 do char_map[x]:=char_map[x-1];π                      char_map[1]:=incom;π                      calculate_char;π                    end;π            'C','c':begin { reset }π                      clrscr;π                      write('Are you SURE you want to clear it? (Y/n) ? ');π                      readln(incom);π                      case incom[1] ofπ                        'Y','y':initalize;π                      end;π                      clrscr;π                      display_screen;π                      calculate_char;π                    end;π          end;π        end;π  end;π      end;π  end;ππ  beginπ    textmode(c80);π    initalize;π    display_screen;π    calculate_char;π    do_online;π    clrscr;π    writeln('Thanks for using CHAREDIT!');π  end.ππ                                                                                                                                44     11-21-9309:44ALL                      WILLIAM PLANKE           Writing PCX files        IMPORT              94     ╓└ {πFrom: WILLIAM PLANKEπSubj: Write PCX example 1/4ππAs I follow this forum, many requests are made for PCX graphicsπfile routines. Those that are looking for Read_PCX info canπfind it on the ZSoft BBS in a wonderful Pascal example: ShowPCX.ππOn the other hand, there is next to zilch out there on how toπWrite_PCX files. I know.... I searched and searched and couldn'tπfind a thing! So with a little brute force  and a few ZSoftπC language snippets <groan>, I got this together:π}πππ{ =================== TPv6.0  P C X _ W ======================== }ππ{$R-}    {Range checking, turn off when debugged}ππunit PCX_W;ππ{ --------------------- Interface ----------------- }ππinterfaceππtypeπ    Str80 = string [80];ππprocedure Write_PCX  (Name:Str80);πππ{ ===================== Implementation ============ }ππimplementationππusesπ    Graph;πππ{-------------- Write_PCX --------------}ππprocedure Write_PCX (Name:Str80);ππconstπ     RED1   = 0;π     GREEN1 = 1;π     BLUE1  = 2;ππtypeπ    ArrayPal   = array [0..15, RED1..BLUE1] of byte;ππconstπ     MAX_WIDTH  = 4000;    { arbitrary - maximum width (in bytes) ofπ                             a PCX image }π     INTENSTART =   $5;π     BLUESTART  =  $55;π     GREENSTART =  $A5;π     REDSTART   =  $F5;ππtypeπ    Pcx_Header = recordπ    {comments from ZSoft ShowPCX pascal example}ππ        Manufacturer: byte;     { Always 10 for PCX file }ππ        Version: byte;          { 2 - old PCX - no palette (not usedπ                                      anymore),π                                  3 - no palette,π                                  4 - Microsoft Windows - no paletteπ                                      (only in old files, new Windowsπ                                      version uses 3),π                                  5 - with palette }ππ        Encoding: byte;         { 1 is PCX, it is possible that we mayπ                                  add additional encoding methods in theπ                                  future }ππ        Bits_per_pixel: byte;   { Number of bits to represent a pixelπ                                  (per plane) - 1, 2, 4, or 8 }ππ        Xmin: integer;          { Image window dimensions (inclusive) }π        Ymin: integer;          { Xmin, Ymin are usually zero (not always)}π        Xmax: integer;π        Ymax: integer;ππ        Hdpi: integer;          { Resolution of image (dots per inch) }π        Vdpi: integer;          { Set to scanner resolution - 300 isπ                                  default }ππ        ColorMap: ArrayPal;π                                { RGB palette data (16 colors or less)π                                  256 color palette is appended to endπ                                  of file }ππ        Reserved: byte;         { (used to contain video mode)π                                  now it is ignored - just set to zero }ππ        Nplanes: byte;          { Number of planes }ππ        Bytes_per_line_per_plane: integer;   { Number of bytes toπ                                               allocate for a scanlineπ                                               plane. MUST be an an EVENπ                                               number! Do NOT calculateπ                                               from Xmax-Xmin! }ππ        PaletteInfo: integer;   { 1 = black & white or color image,π                                  2 = grayscale image - ignored in PB4,π                                      PB4+ palette must also be set toπ                                      shades of gray! }ππ        HscreenSize: integer;   { added for PC Paintbrush IV Plusπ                                  ver 1.0,  }π        VscreenSize: integer;   { PC Paintbrush IV ver 1.02 (and later)}π                                { I know it is tempting to use theseπ                                  fields to determine what video modeπ                                  should be used to display the imageπ                                  - but it is NOT recommended since theπ                                  fields will probably just containπ                                  garbage. It is better to have theπ                                  user install for the graphics mode heπ                                  wants to use... }ππ        Filler: array [74..127] of byte;     { Just set to zeros }π    end;ππ    Array80    = array [1..80]        of byte;π    ArrayLnImg = array [1..326]       of byte; { 6 extra bytes atπ     beginng of line that BGI uses for size info}π    Line_Array = array [0..MAX_WIDTH] of byte;π    ArrayLnPCX = array [1..4]         of Array80;ππvarπ   PCXName   : File;π   Header    : Pcx_Header;                 { PCX file header }π   ImgLn     : ArrayLnImg;π   PCXLn     : ArrayLnPCX;π   RedLn,π   BlueLn,π   GreenLn,π   IntenLn   : Array80;π   Img       : pointer;πππ{-------------- BuildHeader- -----------}ππprocedure BuildHeader;ππconstπ     PALETTEMAP: ArrayPal=π                 {  R    G    B                    }π                (($00, $00, $00),  {  black        }π                 ($00, $00, $AA),  {  blue         }π                 ($00, $AA, $00),  {  green        }π                 ($00, $AA, $AA),  {  cyan         }π                 ($AA, $00, $00),  {  red          }π                 ($AA, $00, $AA),  {  magenta      }π                 ($AA, $55, $00),  {  brown        }π                 ($AA, $AA, $AA),  {  lightgray    }π                 ($55, $55, $55),  {  darkgray     }π                 ($55, $55, $FF),  {  lightblue    }π                 ($55, $FF, $55),  {  lightgreen   }π                 ($55, $FF, $FF),  {  lightcyan    }π                 ($FF, $55, $55),  {  lightred     }π                 ($FF, $55, $FF),  {  lightmagenta }π                 ($FF, $FF, $55),  {  yellow       }π                 ($FF, $FF, $FF) );{  white        }ππvarπ   i : word;ππbeginπ     with Header doπ          beginπ               Manufacturer  := 10;π               Version  := 5;π               Encoding := 1;π               Bits_per_pixel := 1;π               Xmin := 0;π               Ymin := 0;π               Xmax := 639;π               Ymax := 479;π               Hdpi := 640;π               Vdpi := 480;π               ColorMap := PALETTEMAP;π               Reserved := 0;π               Nplanes  := 4; { Red, Green, Blue, Intensity }π               Bytes_per_line_per_plane := 80;π               PaletteInfo := 1;π               HscreenSize := 0;π               VscreenSize := 0;π               for i := 74 to 127 doπ                   Filler [i] := 0;π          end;πend;πππ{-------------- GetBGIPlane ------------}ππprocedure GetBGIPlane (Start:word; var Plane:Array80);ππvarπ   i : word;ππbeginπ     for i:= 1 to Header.Bytes_per_line_per_plane doπ         Plane [i] := ImgLn [Start +i -1]πend;ππ{-------------- BuildPCXPlane ----------}ππprocedure BuildPCXPlane (Start:word; Plane:Array80);ππvarπ   i : word;ππbeginπ     for i := 1 to Header.Bytes_per_line_per_plane doπ         PCXLn [Start] [i] := Plane [i];πend;πππ{-------------- EncPCXLine -------------}ππprocedure EncPCXLine (PlaneLine : word); { Encode a PCX line }ππvarπ   This,π   Last,π   RunCount : byte;π   i,π   j        : word;πππ  {-------------- EncPut -----------------}ππ  procedure EncPut (Byt, Cnt :byte);ππ  constπ       COMPRESS_NUM = $C0;  { this is the upper two bits thatπ                              indicate a count }ππ  varπ     Holder : byte;ππ  beginπ  {$I-}π       if (Cnt = 1) and (COMPRESS_NUM <> (COMPRESS_NUM and Byt)) thenπ          blockwrite (PCXName, Byt,1)          { single occurance }π          {good place for file error handler!}π       elseπ           beginπ                Holder := (COMPRESS_NUM or Cnt);π                blockwrite (PCXName, Holder, 1); { number of times theπ                                                   following colorπ                                                   occurs }π                blockwrite (PCXName, Byt, 1);π           end;π  {$I+}π  end;πππbeginπ     i := 1;         { used in PCXLn }π     RunCount := 1;π     Last := PCXLn [PlaneLine][i];π     for j := 1 to Header.Bytes_per_line_per_plane -1 doπ         beginπ              inc (i);π              This := PCXLn [PlaneLine][i];π              if This = Last thenπ                 beginπ                      inc (RunCount);π                      if RunCount = 63 then   { reached PCX run lengthπ                                                limited max yet? }π                         beginπ                              EncPut (Last, RunCount);π                              RunCount := 0;π                         end;π                 endπ              elseπ                  beginπ                       if RunCount >= 1 thenπ                          Encput (Last, RunCount);π                       Last := This;π                       RunCount := 1;π                  end;π         end;π     if RunCount >= 1 then  { any left over ? }π        Encput (Last, RunCount);πend;ππ            { - - -W-R-I-T-E-_-P-C-X- - - - - - - - }ππconstπ     XMAX = 639;π     YMAX = 479;ππvarπ   i, j, Size : word;ππbeginπ     BuildHeader;π     assign     (PCXName,Name);π{$I-}π     rewrite    (PCXName,1);π     blockwrite (PCXName,Header,sizeof (Header));π     {good place for file error handler!}π{$I+}π     setviewport (0,0,XMAX,YMAX, ClipOn);π     Size := imagesize (0,0,XMAX,0); { size of a single row }π     getmem (Img,Size);ππ     for i := 0 to YMAX doπ         beginπ              getimage (0,i,XMAX,i,Img^);  { Grab 1 line from theπ                                             screen store in Imgπ                                             buffer  }π              move (Img^,ImgLn,Size {326});πππ              GetBGIPlane (INTENSTART, IntenLn);π              GetBGIPlane (BLUESTART,  BlueLn );π              GetBGIPlane (GREENSTART, GreenLn);π              GetBGIPlane (REDSTART,   RedLn  );π              BuildPCXPlane (1, RedLn  );π              BuildPCXPlane (2, GreenLn);π              BuildPCXPlane (3, BlueLn );π              BuildPCXPlane (4, IntenLn); { 320 bytes/lineπ                                            uncompressed }π              for j := 1 to Header.NPlanes doππ                  EncPCXLine (j);π         end;π     freemem (Img,Size);           (* Release the memory        *)π{$I-}π     close (PCXName);              (* Save the Image            *)π{$I+}πend;ππend {PCX.TPU} .πππ{ -----------------------Test Program -------------------------- }ππprogram WritePCX;ππusesπ    Graph, PCX_W;ππ{-------------- DrawHorizBars ----------}ππprocedure DrawHorizBars;ππvarπ   i, Color : word;ππbeginπ     cleardevice;π     Color := 15;π     for i := 0 to 15 doπ         beginπ              setfillstyle (solidfill,Color);π              bar (0,i*30,639,i*30+30);       { 16*30 = 480 }π              dec (Color);π         end;πend;ππ{-------------- Main -------------------}ππvarπ   NameW : Str80;π   Gd,π   Gm    : integer;ππbeginπ     writeln;π     if (ParamCount = 0) then           { no DOS command lineπ                                          parameters }π        beginπ             write ('Enter name of PCX picture file to write: ');π             readln (NameW);π             writeln;π        endπ     elseπ         beginπ              NameW := paramstr (1);  { get filename from DOSπ                                        command line }π         end;ππ     if (Pos ('.', NameW) = 0) then   { make sure the filenameπ                                        has PCX extension }π        NameW := Concat (NameW, '.pcx');ππ     Gd:=VGA;π     Gm:=VGAhi; {640x480, 16 colors}π     initgraph (Gd,Gm,'..\bgi');  { path to your EGAVGA.BGI }ππ     DrawHorizBars;ππ     readln;π     Write_PCX (NameW); { PCX_W.TPU }π     closegraph;                    { Close graphics    }π     textmode (co80);               { back to text mode }πend.  { Write_PCX }π                                                                           45     11-26-9317:01ALL                      RAPHAEL VANNEY           DISPLAY Text in Graphics IMPORT              11     ╓h# {πRAPHAEL VANNEYππ*You mean displaying Text While in Graphics mode :-) ?ππ> Yup. Already got a suggestion on using 640x480 With 8x8 font, so ifπ> you have any other one please do tell.. ttyl...ππSure. Just call the BIOS routines to display Characters With a "standard"πlook. By standard look, I mean they look like they were Characters inπText mode.ππOkay, here is the basic Procedure to display a String (Works in any Text/πGraphics mode) :π}ππProcedure BIOSWrite(Str : String; Color : Byte); Assembler;πAsmπ  les  di, Strπ  mov  cl, es:[di]     { cl = longueur chane }π  inc  di              { es:di pointe sur 1er caractre }π  xor  ch, ch          { cx = longueur chane }π  mov  bl, Color       { bl:=coul }π  jcxz @ExitBW         { sortie si Length(s)=0 }π @BoucleBW:π  mov  ah, 0eh         { sortie TTY }π  mov  al, es:[di]     { al=caractre  afficher }π  int  10h             { et hop }π  inc  di              { caractre suivant }π  loop @BoucleBWπ @ExitBW:πend ;ππ{πI'm not sure how to manage the background color in Graphics mode ; maybeπyou should experiment With values in "coul", there could be a magic bitπto keep actual background color.π}ππ                                                                                                                              46     01-27-9411:51ALL                      PETER M. GRUHN           3D Rotation              IMPORT              49     ╓┼ program BoxRot;ππ{PUBLIC DOMAIN  1993 Peter M. GruhnππProgram draws a box on screen. Allows user to rotate the box aroundπthe three primary axes. Viewing transform is simple ignore z.ππI used _Computer_Graphics:_Principles_and_Practice_, Foley et alπISBN 0-201-12110-7 as a referenceππRUNNING:πBorland Pascal 7. Should run on any graphics device supported by BGI.πIf you have smaller than 280 resolution, change '+200' to somethingπsmaller and/or change 75 to something smaller.ππSince this machine isπnot really set up for doing DOS graphics, I hard coded my BGI path, soπyou have to find 'initgraph' and change the bgi path to something thatπworks on your machine. Try ''.ππOkey dokey. This is kinda slow, and does a nice job of demonstrating theπproblems of repeatedly modifying the same data set. That is, the more andπmore you rotate the box, the more and more distorted it gets. This isπbecause computers are not perfect at calculations, and all of those littleπerrors add up quite quickly.ππIt's because of that that I used reals, not reals. I used floating pointπbecause the guy doesn't know what is going on at all with 3d, so better toπlook at only the math that is really happening. Besides, I still have toπthink to use fixed point. Whaddaya want for .5 hour programming.ππ DIRECTIONS:π   ',' - rotates around the x axisπ   '.' - rotates around the y axisπ   '/' - rotates around the z axisπ   'q' - quitsππ   All rotations are done around global axes, not object axes.π}ππusesπ  graph,π  crt;ππconstπ  radtheta = 1 {degrees} * 3.1415926535 {radians} / 180 {per degrees};π  { sin and cos on computers are done in radians. }ππtypeπ  tpointr = record   { Just a record to hold 3d points }π    x, y, z : real;π  end;ππvarπ  box : array [0..7] of tpointr;   { The box we will manipulate }π  c   : char;                      { Our input mechanism }ππprocedure init;πvarπ  gd, gm : integer;π{ turns on graphics and creates a cube. Since the rotation routinesπ  rotate around the origin, I have centered the cube on the origin, soπ  that it stays in place and only spins. }πbeginπ  gd := detect;π  initgraph(gd, gm, 'e:\bp\bgi');π  box[0].x := -75;  box[0].y := -75;  box[0].z := -75;π  box[1].x := 75;   box[1].y := -75;  box[1].z := -75;π  box[2].x := 75;   box[2].y := 75;   box[2].z := -75;π  box[3].x := -75;  box[3].y := 75;   box[3].z := -75;π  box[4].x := -75;  box[4].y := -75;  box[4].z := 75;π  box[5].x := 75;   box[5].y := -75;  box[5].z := 75;π  box[6].x := 75;   box[6].y := 75;   box[6].z := 75;π  box[7].x := -75;  box[7].y := 75;   box[7].z := 75;πend;ππprocedure myline(x1, y1, z1, x2, y2, z2 : real);π{ Keeps the draw routine pretty. Pixels are integers, so I round. Since theπ cube is centered around 0,0 I move it over 200 to put it on screen. }πbeginπ{ if you think those real mults are slow, here's some rounds too... hey, youπ  may wonder, what happened to the stinking z coordinate? Ah, says I, thisπ  is the simplest of 3d viewing transforms. You just take the z coord out ofπ  things and boom. Looking straight down the z axis on the object. If I getπ  inspired, I will add simple perspective transform to these.  There, gotπ  inspired. Made mistakes. Foley et al are not very good at tutoringπ  perspective and I'm kinda ready to be done and post this. }π  line(round(x1) + 200, round(y1) + 200, round(x2) + 200, round(y2) + 200);πend;ππprocedure draw;π{ my model is hard coded. No cool things like vertex and edge and face lists.}πbeginπ  myline(box[0].x, box[0].y, box[0].z, box[1].x, box[1].y, box[1].z);π  myline(box[1].x, box[1].y, box[1].z, box[2].x, box[2].y, box[2].z);π  myline(box[2].x, box[2].y, box[2].z, box[3].x, box[3].y, box[3].z);π  myline(box[3].x, box[3].y, box[3].z, box[0].x, box[0].y, box[0].z);ππ  myline(box[4].x, box[4].y, box[4].z, box[5].x, box[5].y, box[5].z);π  myline(box[5].x, box[5].y, box[5].z, box[6].x, box[6].y, box[6].z);π  myline(box[6].x, box[6].y, box[6].z, box[7].x, box[7].y, box[7].z);π  myline(box[7].x, box[7].y, box[7].z, box[4].x, box[4].y, box[4].z);ππ  myline(box[0].x, box[0].y, box[0].z, box[4].x, box[4].y, box[4].z);π  myline(box[1].x, box[1].y, box[1].z, box[5].x, box[5].y, box[5].z);π  myline(box[2].x, box[2].y, box[2].z, box[6].x, box[6].y, box[6].z);π  myline(box[3].x, box[3].y, box[3].z, box[7].x, box[7].y, box[7].z);ππ  myline(box[0].x, box[0].y, box[0].z, box[5].x, box[5].y, box[5].z);π  myline(box[1].x, box[1].y, box[1].z, box[4].x, box[4].y, box[4].z);πend;ππprocedure rotx;π{if you know your matrix multiplication, the following equationsπ are derived fromππ [x   [ 1  0  0  0   [x',y',z',1]π  y     0  c -s  0 =π  z     0  s  c  0π  1]    0  0  0  1]π}πvarπ  i : integer;πbeginπ  setcolor(0);π  draw;π  for i := 0 to 7 doπ  beginπ    box[i].x :=  box[i].x;π    box[i].y :=  box[i].y * cos(radTheta) + box[i].z * sin(radTheta);π    box[i].z := -box[i].y * sin(radTheta) + box[i].z * cos(radTheta);π  end;π  setcolor(15);π  draw;πend;ππprocedure roty;π{if you know your matrix multiplication, the following equationsπ are derived fromππ [x   [ c  0  s  0   [x',y',z',1]π  y     0  1  0  0 =π  z    -s  0  c  0π  1]    0  0  0  1]π}πvarπ  i : integer;πbeginπ  setcolor(0);π  draw;π  for i := 0 to 7 doπ  beginπ    box[i].x := box[i].x * cos(radTheta) - box[i].z * sin(radTheta);π    box[i].y := box[i].y;π    box[i].z := box[i].x * sin(radTheta) + box[i].z * cos(radTheta);π  end;π  setcolor(15);π  draw;πend;ππprocedure rotz;π{if you know your matrix multiplication, the following equationsπ are derived fromππ [x   [ c -s  0  0   [x',y',z',1]π  y     s  c  0  0 =π  z     0  0  1  0π  1]    0  0  0  1]π}πvarπ  i : integer;πbeginπ  setcolor(0);π  draw;π  for i := 0 to 7 doπ  beginπ    box[i].x :=  box[i].x * cos(radTheta) + box[i].y * sin(radTheta);π    box[i].y := -box[i].x * sin(radTheta) + box[i].y * cos(radTheta);π    box[i].z :=  box[i].z;π  end;π  setcolor(15);π  draw;πend;πππbeginπ  init;π  setcolor(14);π  draw;π  repeatπ    c := readkey;π    case c ofπ      ',' : rotx;π      '.' : roty;π      '/' : rotz;π      else {who gives a};π    end; {case}π  until c = 'q';π  closegraph;πend.πππ                                         47     01-27-9411:58ALL                      SEAN PALMER              Bresenham's Line         IMPORT              20     ╓─j {π>> I was wondering if anyone could show me the equations (and perhaps aπ>> demo in standard pascal) of the following shapes. What I need to know isπ>> where to plot the point.π>> Circle. (I've tried using the equation taught to me at school, but itπ>> Line  (What I would like would be to be able to plot a line by giving itππThere seems yet again to be enough interest/need so I'll post this stuff justπONCE more.... somebody put this in SWAG or something.... PLEASE!!!ππ [Okay Sean, here you go!  -Kerry]ππYou need a plot(x,y) procedure and a global color variable to use these asπposted.π}ππ{bresenham's line}πprocedure line(x, y, x2, y2 : integer);πvarπ  d, dx, dy,π  ai, bi,π  xi, yi : integer;πbeginπ  if (x < x2) thenπ  beginπ    xi := 1;π    dx := x2 - x;π  endπ  elseπ  beginπ    xi := - 1;π    dx := x - x2;π  end;ππ  if (y < y2) thenπ  beginπ    yi := 1;π    dy := y2 - y;π  endπ  elseπ  beginπ    yi := - 1;π    dy := y - y2;π  end;ππ  plot(x, y);ππ  if dx > dy thenπ  beginπ    ai := (dy - dx) * 2;π    bi := dy * 2;π    d  := bi - dx;π    repeatπ      if (d >= 0) thenπ      beginπ        inc(y, yi);π        inc(d, ai);π      endπ      elseπ        inc(d, bi);ππ      inc(x, xi);π      plot(x, y);π    until (x = x2);π  endπ  elseπ  beginπ    ai := (dx - dy) * 2;π    bi := dx * 2;π    d  := bi - dy;π    repeatπ      if (d >= 0) thenπ      beginπ        inc(x, xi);π        inc(d, ai);π      endπ      elseπ        inc(d, bi);ππ      inc(y, yi);π      plot(x, y);π    until (y = y2);π  end;πend;πππ{filled ellipse}πprocedure disk(xc,  yc,  a,  b : integer);πvarπ  x, y      : integer;π  aa, aa2,π  bb, bb2,π  d, dx, dy : longint;πbeginπ  x   := 0;π  y   := b;π  aa  := longint(a) * a;π  aa2 := 2 * aa;π  bb  := longint(b) * b;π  bb2 := 2 * bb;π  d   := bb - aa * b + aa div 4;π  dx  := 0;π  dy  := aa2 * b;π  vLin(xc, yc - y, yc + y);ππ  while (dx < dy) doπ  beginπ    if (d > 0) thenπ    beginπ      dec(y);π      dec(dy, aa2);π      dec(d, dy);π    end;π    inc(x);π    inc(dx, bb2);π    inc(d, bb + dx);π    vLin(xc - x, yc - y, yc + y);π    vLin(xc + x, yc - y, yc + y);π  end;ππ  inc(d, (3 * (aa - bb) div 2 - (dx + dy)) div 2);π  while (y >= 0) doπ  beginπ    if (d < 0) thenπ    beginπ      inc(x);π      inc(dx, bb2);π      inc(d, bb + dx);π      vLin(xc - x, yc - y, yc + y);π      vLin(xc + x, yc - y, yc + y);π    end;π    dec(y);π    dec(dy, aa2);π    inc(d, aa - dy);π  end;πend;ππ                    48     01-27-9412:05ALL                      LIOR BAR-ON              Gif Source 1             IMPORT              98     ╓≈ {π> Can you post the gif source and any other graphic source for doing thisππHere is gif format (it doesn't get to full 768·1024·256)πor even less, but it is ok.π}ππ{$R-}{$S-}{$B-}πprogram GIF4TP;ππusesπ  crt, GRAPH;ππconstπ  ProgramName = 'TP4GIF';π  ProgramRevision = '2';ππtypeπ  BufferArray = array[0..63999] of byte;π  BufferPointer = ^BufferArray;ππvarπ  GifFile : file of BufferArray;π  InputFileName : string;π  RawBytes : BufferPointer;   { The heap array to hold it, raw    }π  Buffer : BufferPointer;     { The Buffer data stream, unblocked }π  Buffer2 : BufferPointer;    { More Buffer data stream if needed }π  Byteoffset,                 { Computed byte position in Buffer array }π  BitIndex                    { Bit offset of next code in Buffer array }π   : longint;ππ  Width,      {Read from GIF header, image width}π  Height,     { ditto, image height}π  LeftOfs,    { ditto, image offset from left}π  TopOfs,     { ditto, image offset from top}π  RWidth,     { ditto, Buffer width}π  RHeight,    { ditto, Buffer height}π  ClearCode,  {GIF clear code}π  EOFCode,    {GIF end-of-information code}π  OutCount,   {Decompressor output 'stack count'}π  MaxCode,    {Decompressor limiting value for current code size}π  CurCode,    {Decompressor variable}π  OldCode,    {Decompressor variable}π  InCode,     {Decompressor variable}π  FirstFree,  {First free code, generated per GIF spec}π  FreeCode,   {Decompressor, next free slot in hash table}π  RawIndex,     {Array pointers used during file read}π  BufferPtr,π  XC,YC,      {Screen X and Y coords of current pixel}π  ReadMask,   {Code AND mask for current code size}π  I           {Loop counter, what else?}π  :word;ππ  Interlace,  {true if interlaced image}π  AnotherBuffer, {true if file > 64000 bytes}π  ColorMap    {true if colormap present}π  : boolean;ππ  ch : char;π  a,              {Utility}π  Resolution,     {Resolution, read from GIF header}π  BitsPerPixel,   {Bits per pixel, read from GIF header}π  Background,     {Background color, read from GIF header}π  ColorMapSize,   {Length of color map, from GIF header}π  CodeSize,       {Code size, read from GIF header}π  InitCodeSize,   {Starting code size, used during Clear}π  FinChar,        {Decompressor variable}π  Pass,           {Used by video output if interlaced pic}π  BitMask,        {AND mask for data size}π  R,G,Bπ  :byte;ππ    {The hash table used by the decompressor}π  Prefix: array[0..4095] of word;π  Suffix: array[0..4095] of byte;ππ    {An output array used by the decompressor}π  PixelValue : array[0..1024] of byte;ππ    {The color map, read from the GIF header}π  Red,Green,Blue: array [0..255] of byte;π  MyPalette : PaletteType;ππ  TempString : String;ππConstπ MaxCodes: Array [0..9] of Word = (4,8,16,$20,$40,$80,$100,$200,$400,$800);π CodeMask:Array [1..4] of byte= (1,3,7,15);π PowersOf2: Array [0..8] of word=(1,2,4,8,16,32,64,128,256);π Masks: Array [0..9] of integer = (7,15,$1f,$3f,$7f,$ff,$1ff,$3ff,$7ff,$fff);π BufferSize : Word = 64000;ππfunction NewExtension(FileName,Extension : string) : string;π{πPlaces a new extension on to the file name.π}πvarπ  I : integer;πbeginπ  if (Extension[1] = '.') then delete(Extension,1,1);π  delete(Extension,4,251);π  I := pos('.',FileName);π  if (I = 0) thenπ  beginπ    while (length(FileName) > 0) and (FileName[length(FileName)] = ' ')π      do delete(FileName,length(FileName),1);π    NewExtension := FileName + '.' + Extension;π  end else beginπ    delete(FileName,I + 1,254 - I);π    NewExtension := FileName + Extension;π  end;πend; { NewExtension }ππfunction Min(I,J : longint) : longint;πbeginπ  if (I < J) then Min := I else Min := J;πend; { Min }ππprocedure AllocMem(var P : BufferPointer);πvarπ  ASize : longint;πbeginπ  ASize := MaxAvail;π  if (ASize < BufferSize) then beginπ    Textmode(15);π    writeln('Insufficient memory available!');π    halt;π  end else getmem(P,BufferSize);πend; { AllocMem }ππfunction Getbyte : byte;πbeginπ  if (RawIndex >= BufferSize) then exit;π  Getbyte := RawBytes^[RawIndex];π  inc(RawIndex);πend;ππfunction Getword : word;πvarπ  W : word;πbeginπ  if (succ(RawIndex) >= BufferSize) then exit;π  move(RawBytes^[RawIndex],W,2);π  inc(RawIndex,2);π  Getword := W;πend; { GetWord }ππprocedure ReadBuffer;πvarπ  BlockLength : byte;π  I,IOR : integer;πbeginπ  BufferPtr := 0;π  Repeatπ    BlockLength := Getbyte;π    For I := 0 to Blocklength-1 doπ    beginπ      if RawIndex = BufferSize thenπ      beginπ        {$I-}π        Read (GIFFile,RawBytes^);π        {$I+}π        IOR := IOResult;π        RawIndex := 0;π      end;π      if not AnotherBufferπ        then Buffer^[BufferPtr] := Getbyteπ        else Buffer2^[BufferPtr] := Getbyte;π      BufferPtr := Succ (BufferPtr);π      if BufferPtr=BufferSize then beginπ        AnotherBuffer := true;π        BufferPtr := 0;π        AllocMem (Buffer2);π      end;π    end;π  Until Blocklength=0;πend; { ReadBuffer }ππprocedure InitEGA;πvarπ  Driver,Mode : integer;πbeginπ  DetectGraph(Driver,Mode);π  InitGraph(Driver,Mode,'e:\bp\bgi');π  SetAllPalette(MyPalette);π  if (Background <> 0) then beginπ    SetFillStyle(SolidFill,Background);π    bar(0,0,Width,Height);π  end;πend; { InitEGA }ππprocedure DetColor(var PValue : byte; MapValue : Byte);π{πDetermine the palette value corresponding to the GIF colormap intensityπvalue.π}πvarπ  Local : byte;πbeginπ  PValue := MapValue div 64;π  if (PValue = 1)π    then PValue := 2π    else if (PValue = 2)π      then PValue := 1;πend; { DetColor }ππprocedure Init;πvarπ  I : integer;πbeginπ  XC := 0;          {X and Y screen coords back to home}π  YC := 0;π  Pass := 0;        {Interlace pass counter back to 0}π  BitIndex := 0;   {Point to the start of the Buffer data stream}π  RawIndex := 0;      {Mock file read pointer back to 0}π  AnotherBuffer := false;    {Over 64000 flag off}π  AllocMem(Buffer);π  AllocMem(RawBytes);π  InputFileName := NewExtension(InputFileName,'GIF');π  {$I-}π  Assign(giffile,InputFileName);π  Reset(giffile);π  I := IOResult;π  if (I <> 0) then beginπ    textmode(15);π    writeln('Error opening file ',InputFileName,'. Press any key ');π    readln;π    halt;π  end;π  read(GIFFile,RawBytes^);π  I := IOResult;π{$I+}πend; { Init }ππprocedure ReadGifHeader;πvarπ  I : integer;πbeginπ  TempString := '';π  for I := 1 to 6 do TempString := TempString + chr(Getbyte);π  if (TempString <> 'GIF87a') then beginπ    textmode(15);π    writeln('Not a GIF file, or header read error. Press enter.');π    readln;π    halt;π  end;π{πGet variables from the GIF screen descriptorπ}π  RWidth := Getword;         {The Buffer width and height}π  RHeight := Getword;π{πGet the packed byte immediately following and decode itπ}π  B := Getbyte;π  Colormap := (B and $80 = $80);π  Resolution := B and $70 shr 5 + 1;π  BitsPerPixel := B and 7 + 1;π  ColorMapSize := 1 shl BitsPerPixel;π  BitMask := CodeMask[BitsPerPixel];π  Background := Getbyte;π  B := Getbyte;         {Skip byte of 0's}π{πCompute size of colormap, and read in the global one if there. Computeπvalues to be used when we set up the EGA paletteπ}π  MyPalette.Size := Min(ColorMapSize,16);π  if Colormap then beginπ    for I := 0 to pred(ColorMapSize) do beginπ      Red[I] := Getbyte;π      Green[I] := Getbyte;π      Blue[I] := Getbyte;π      DetColor(R,Red[I]);π      DetColor(G,Green [I]);π      DetColor(B,Blue [I]);π      MyPalette.Colors[I] := B and 1 +π                    ( 2 * (G and 1)) + ( 4 * (R and 1)) + (8 * (B div 2)) +π                    (16 * (G div 2)) + (32 * (R div 2));π    end;π  end;π{πNow read in values from the image descriptorπ}π  B := Getbyte;  {skip image seperator}π  Leftofs := Getword;π  Topofs := Getword;π  Width := Getword;π  Height := Getword;π  A := Getbyte;π  Interlace := (A and $40 = $40);π  if Interlace then beginπ    textmode(15);π    writeln(ProgramName,' is unable to display interlaced GIF pictures.');π    halt;π  end;πend; { ReadGifHeader }ππprocedure PrepDecompressor;πbeginπ  Codesize := Getbyte;π  ClearCode := PowersOf2[Codesize];π  EOFCode := ClearCode + 1;π  FirstFree := ClearCode + 2;π  FreeCode := FirstFree;π  inc(Codesize); { since zero means one... }π  InitCodeSize := Codesize;π  Maxcode := Maxcodes[Codesize - 2];π  ReadMask := Masks[Codesize - 3];πend; { PrepDecompressor }ππprocedure DisplayGIF;π{πDecompress and display the GIF data.π}πvarπ  Code : word;ππ  procedure DoClear;π  beginπ    CodeSize := InitCodeSize;π    MaxCode := MaxCodes[CodeSize-2];π    FreeCode := FirstFree;π    ReadMask := Masks[CodeSize-3];π  end; { DoClear }ππ  procedure ReadCode;π  varπ    Raw : longint;π  beginπ    if (CodeSize >= 8) then beginπ      move(Buffer^[BitIndex shr 3],Raw,3);π      Code := (Raw shr (BitIndex mod 8)) and ReadMask;π    end else beginπ      move(Buffer^[BitIndex shr 3],Code,2);π      Code := (Code shr (BitIndex mod 8)) and ReadMask;π    end;π    if AnotherBuffer then beginπ      ByteOffset := BitIndex shr 3;π      if (ByteOffset >= 63000) then beginπ        move(Buffer^[Byteoffset],Buffer^[0],BufferSize-Byteoffset);π        move(Buffer2^[0],Buffer^[BufferSize-Byteoffset],63000);π        BitIndex := BitIndex mod 8;π        FreeMem(Buffer2,BufferSize);π      end;π    end;π    BitIndex := BitIndex + CodeSize;π  end; { ReadCode }ππ  procedure OutputPixel(Color : byte);π  beginπ    putpixel(XC,YC,Color); { about 3x faster than using the DOS interrupt! }π    inc(XC);π    if (XC = Width) then beginπ      XC := 0;π      inc(YC);π      if (YC mod 10 = 0) and keypressed and (readkey = #27) then beginπ        textmode(15);  { let the user bail out }π        halt;π      end;π    end;π  end; { OutputPixel }ππππbegin { DisplayGIF }π  CurCode := 0; { not initted anywhere else... don't know why }π  OldCode := 0; { not initted anywhere else... don't know why }π  FinChar := 0; { not initted anywhere else... don't know why }π  OutCount := 0;π  DoClear;      { not initted anywhere else... don't know why }π  repeatπ    ReadCode;π    if (Code <> EOFCode) then beginπ      if (Code = ClearCode) then begin { restart decompressor }π        DoClear;π        ReadCode;π        CurCode := Code;π        OldCode := Code;π        FinChar := Code and BitMask;π        OutputPixel(FinChar);π      end else begin        { must be data: save same as CurCode and InCode }π        CurCode := Code;π        InCode := Code;π{ if >= FreeCode, not in hash table yet; repeat the last character decoded }π        if (Code >= FreeCode) then beginπ          CurCode := OldCode;π          PixelValue[OutCount] := FinChar;π          inc(OutCount);π        end;π{πUnless this code is raw data, pursue the chain pointed to by CurCodeπthrough the hash table to its end; each code in the chain puts itsπassociated output code on the output queue.π}π        if (CurCode > BitMask) then repeatπ          PixelValue[OutCount] := Suffix[CurCode];π          inc(OutCount);π          CurCode := Prefix[CurCode];π        until (CurCode <= BitMask);π{πThe last code in the chain is raw data.π}π        FinChar := CurCode and BitMask;π        PixelValue[OutCount] := FinChar;π        inc(OutCount);π{πOutput the pixels. They're stacked Last In First Out.π}π        for I := pred(OutCount) downto 0 do OutputPixel(PixelValue[I]);π        OutCount := 0;π{πBuild the hash table on-the-fly.π}π        Prefix[FreeCode] := OldCode;π        Suffix[FreeCode] := FinChar;π        OldCode := InCode;π{πPoint to the next slot in the table. If we exceed the current MaxCodeπvalue, increment the code size unless it's already 12. if it is, doπnothing: the next code decompressed better be CLEARπ}π        inc(FreeCode);π        if (FreeCode >= MaxCode) then beginπ          if (CodeSize < 12) then beginπ            inc(CodeSize);π            MaxCode := MaxCode * 2;π            ReadMask := Masks[CodeSize - 3];π          end;π        end;π      end; {not Clear}π    end; {not EOFCode}π  until (Code = EOFCode);πend; { DisplayGIF }ππbegin { TP4GIF }π  writeln(ProgramName,' Rev ',ProgramRevision);π  if (paramcount > 0)π    then TempString := paramstr(1)π  else beginπ    write(' > ');π    readln(TempString);π  end;π  InputFileName := TempString;π  Init;π  ReadGifHeader;π  PrepDecompressor;π  ReadBuffer;π  FreeMem(RawBytes,BufferSize);π  InitEGA;π  DisplayGIF;π  SetAllPalette(MyPalette);π  close(GifFile);π  Ch := readkey;π  textmode(15);π  freemem(Buffer,BufferSize);        { totally pointless, but it's good form }πend.π                                                  49     01-27-9412:07ALL                      THORSTEN BARTH           GIF Code                 IMPORT              42     ╓ÄQ {π> Does anyone have ANY source, on how to display a gif in VGA modeππIt's as bad as ... but it works.ππ--- VGA gif loader part 1 of 3 ---π}ππ{$X+}ππUses Graph,Dos;ππVarπ  Gd,Gm: Integer;π  Datei: File;π  palette: array[0..767] of byte;π  buffer: array[0..1279] of byte;π  prefix,tail: array[0..4095] OF WORD;π  keller: array[0..640] of Word;ππFunction LoadGif(N: String; VersX,VersY: Word): Integer;ππFunction GetChar: Char;πVar C: Char;πBeginπ  BlockRead(Datei,C,1);π  GetChar:=C;πEnd;ππFunction GetByte: Byte;πVar B: Byte;πBeginπ  BlockRead(Datei,B,1);π  GetByte:=B;πEnd;ππFunction GetWord: Word;πVar W: Word;πBeginπ  BlockRead(Datei,W,2);π  Getword:=W;πEnd;ππProcedure AGetBytes(Anz: Word);πBeginπ  BlockRead(Datei,Buffer,Anz);πEnd;ππVarπ  lokal_farbtafel: Integer;π  mask,restbytes,pp,lbyte,blocklen,code,oldcode,sonderfall,π  incode,freepos,kanz,pass,clearcode,eofcode,maxcode,infobyte,π  globalfarbtafel,backcolor,interlace,bilddef,abslinks,absoben: word;π  bits,restbits,codesize: Byte;π  rot,gruen,blau,by,bpp: Byte;π  z,i,x1,y1,x2,y2: integer;π  bem: string[6];π  farben: integer;π  x,y,xa,ya,dy: word;πbeginπ  loadgif:=0;π  Assign(Datei,N);π  reset(Datei,1);π  if ioresult>0 then begin loadgif:=1; exit; end;π  bem:='';π  for i:=1 to 6 do bem:=bem+getchar;π  if copy(bem,1,3)<>'GIF' then begin loadgif:=2; exit; end;π  x2:=getword;π  y2:=getword;π  infobyte:=getbyte;π  globalfarbtafel:=infobyte and 128;π  bpp:=(infobyte and 7)+1;π  farben:=1 shl bpp;π  backcolor:=getbyte;π  by:=getbyte;π  if globalfarbtafel<>0 thenπ    for i:=0 to (3*farben)-1 doπ      palette[i]:=getbyte shr 2;π  bilddef:=getbyte;π  while bilddef=$21 do beginπ    by:=getbyte; z:=getbyte;π    for i:=1 to z do by:=getbyte;π    by:=getbyte;π    bilddef:=getbyte;π  end;πππ  if bilddef<>$2c then begin loadgif:=3; exit; end;π  abslinks:=getword+VersX;π  absoben:=getword+VersY;π  x2:=getword;π  y2:=getword;π  by:=getbyte;π  lokal_farbtafel:=by and 128;π  interlace:=by and 64;π  by:=getbyte;π  x1:=0; y1:=0; xa:=x2; Ya:=Y2;π  if farben<16 then begin loadgif:=4; exit; end;π  if lokal_farbtafel<>0 thenπ    for i:=0 to 3*Farben-1 doπ      palette[I]:=getbyte shr 2;π  asmπ    mov ax,$1012π    push dsπ    pop esπ    xor bx,bxπ    mov cx,256π    lea dx,paletteπ    int $10π    mov pass,0π    MOV CL,bppπ    MOV AX,1π    SHL AX,CLπ    MOV clearcode,AXπ    INC AXπ    MOV eofcode,AXπ    INC AXπ    MOV freepos,AXπ    MOV AL,bppπ    MOV AH,0π    INC AXπ    MOV codesize,ALπ    MOV CX,AXπ    MOV AX,1π    SHL AX,CLπ    DEC AXπ    MOV maxcode,AXπ    MOV kanz,0π    MOV dy,8π    MOV restbits,0π    MOV restbytes,0π    MOV x,0π    MOV y,0π@gif0: CALL FAR PTR @getgifbyteπ    CMP AX,eofcodeπ    je @ende1π@gif1: CMP AX,clearcodeπ    je @reset1π@gif3: MOV AX,codeπ    MOV incode,AXπ    CMP ax,freeposπ    jb @gif4π    MOV AX,oldcodeπ    MOV code,AXπ    MOV BX,kanzπ    MOV CX,sonderfallπ    SHL BX,1π    MOV [OFFSET keller+BX],CXπ    INC kanzπ@gif4: CMP AX,clearcodeπ    JB @gif6π@gif5: MOV BX,codeπ    SHL BX,1π    PUSH BXπ    MOV AX,[Offset tail+BX]π    MOV BX,kanzπ    SHL BX,1π    MOV [OFFSET keller+BX],AXπ    INC kanzπ    POP BXπ    MOV AX,[Offset prefix+BX]π    MOV code,AXπ    CMP AX,clearcodeπ    ja @gif5π@gif6: MOV BX,kanzπ    SHL BX,1π    MOV [Offset keller+BX],AXπ    MOV sonderfall,AXπ    INC kanzπ@gif7: MOV AX,[Offset keller+BX]π    CALL FAR PTR @pixelπ    CMP BX,0π    JE @gif8π    DEC BXπ    DEC BXπ    JMP @gif7ππ@gif8: MOV kanz,0π    MOV BX,freeposπ    SHL BX,1π    MOV AX,oldcodeπ    MOV [Offset prefix+BX],AXπ    MOV AX,codeπ    MOV [Offset tail+BX],AXπ    MOV AX,incodeπ    MOV oldcode,AXπ    INC freeposπ    MOV AX,freeposπ    CMP AX,maxcodeπ    JBE @gif2π    CMP codesize,12π    JAE @gif2π    INC codesizeπ    MOV CL,codesizeπ    MOV AX,1π    SHL AX,CLπ    DEC AXπ    MOV maxcode,AXπ@gif2: JMP @gif0π@ende1: JMP @endeπ@reset1: MOV AL,bppπ    MOV AH,0π    INC AXπ    MOV codesize,ALπ    MOV CX,AXπ    MOV AX,1π    SHL AX,CLπ    DEC AXπ    MOV maxcode,AXπ    MOV AX,clearcodeπ    ADD AX,2π    MOV freepos,AXπ    CALL FAR PTR @getgifbyteπ    MOV sonderfall,AXπ    MOV oldcode,AXπ    CALL FAR PTR @pixelπ    JMP @gif2π@getgifbyte: MOV DI,0π    MOV mask,1π    MOV bits,0π@g1: MOV AL,bitsπ    CMP AL,codesizeπ    JAE @g0π    CMP restbits,0π    JA @g2π    CMP restbytes,0π    JNE @l2π    PUSH DIπ    CALL Getbyteπ    POP DIπ    MOV blocklen,AXπ    MOV restbytes,AXπ    PUSH DIπ    PUSH AXπ    CALL AGetbytesπ    POP DIπ    MOV pp,0π@l2: MOV BX,ppπ    MOV AL,[BX+Offset Buffer]π    XOR AH,AHπ    INC ppπ    DEC restbytesπ    MOV lbyte,AXπ    MOV restbits,8π@g2: SHR lbyte,1π    JNC @nocarryπ    OR DI,maskπ@nocarry: INC bitsπ    DEC restbitsπ    SHL mask,1π    JMP @g1π@g0:MOV bits,0π    MOV code,DIπ    MOV AX,DIπ    RETFπ@pixel:π    PUSH BXπ    MOV BX,xπ    ADD BX,abslinksπ    PUSH BXπ    MOV BX,yπ    ADD BX,absobenπ    PUSH BXπ    PUSH AXπ    CALL Putpixelπ    POP BXπ    INC xπ    MOV AX,xπ    CMP AX,x2π    JB @s0π    MOV x,0π    CMP interlace,0π    JNE @s1π    INC yπ    JMP @s0π@s1: MOV AX,dyπ    ADD y,AXπ    MOV AX,yπ    CMP AX,y2π    JB @s0π    INC passπ    CMP pass,1π    JNE @s3π    JMP @s2π@s3: SHR dy,1π@s2: MOV AX,DYπ    SHR AX,1π    MOV Y,AXπ@s0: RETFπ@ende:π  End;π  Close(Datei);πEnd;πππbeginππend.                                         50     01-27-9412:07ALL                      BERNIE PALLEK            VGA256 Unit              IMPORT              40     ╓> {π> I'm using 320x200x256.  I use mainly assembly to do my procedures andπ> function in this library... but I can't manage to figure out a way to doπ> GET and PUTs ... have ny Idea how to do it?  And yes, if you have any niceπ> graphic procedures/functions, well, I'm interrested...ππOk, if you want, I can post a bitmap scaler I got from Sean Palmer... it's inπassembler, so it's fast, and you could use it just like put, except it doesn'tπdo "transparency."  If I ever figure out how to do it, I'll modify it and postπit.  But for now, here are some other routines for mode 13h:π}ππTYPEπ  RGBPalette = ARRAY[0..767] OF Byte;ππPROCEDURE SetVideoMode(desiredVideoMode : Byte);πBEGIN ASM MOV AH,0; MOV AL,desiredVideoMode; INT $10; END; END;ππFUNCTION GetPixel(pix2get_x, pix2get_y : Word) : Byte;πBEGIN GetPixel := Mem[$A000 : pix2get_y * 320 + pix2get_x]; END;ππPROCEDURE SetPixel(pix2set_x, pix2set_y : Word; pix2set_c : Byte);πBEGIN Mem[$A000 : pix2set_y * 320 + pix2set_x] := pix2set_c; END;ππPROCEDURE Ellipse(exc, eyc, ea, eb : Integer);πVAR elx, ely : Integer;π  aa, aa2, bb, bb2, d, dx, dy : LongInt;πBEGINπ  elx:=0; ely:=eb; aa:=LongInt(ea)*ea; aa2:=2*aa;π  bb:=LongInt(eb)*eb; bb2:=2*bb;π  d:=bb-aa*eb+aa DIV 4; dx:=0; dy:=aa2*eb;π  SetPixel(exc, eyc-ely, Colour); SetPixel(exc, eyc+ely, Colour);π  SetPixel(exc-ea, eyc, Colour); SetPixel(exc+ea, eyc, Colour);π  WHILE (dx < dy) DO BEGINπ    IF (d > 0) THEN BEGINπ      Dec(ely); Dec(dy, aa2); Dec(d, dy);π    END;π    Inc(elx); Inc(dx, bb2); Inc(d, bb+dx);π    SetPixel(exc+elx, eyc+ely, Colour);π    SetPixel(exc-elx, eyc+ely, Colour);π    SetPixel(exc+elx, eyc-ely, Colour);π    SetPixel(exc-elx, eyc-ely, Colour);π  END;π  Inc(d, (3*(aa-bb) DIV 2-(dx+dy)) DIV 2);π  WHILE (ely > 0) DO BEGINπ    IF (d < 0) THEN BEGINπ      Inc(elx); Inc(dx, bb2); Inc(d, bb + dx);π    END;π    Dec(ely); Dec(dy, aa2); Inc(d, aa-dy);π    SetPixel(exc+elx, eyc+ely, Colour);π    SetPixel(exc-elx, eyc+ely, Colour);π    SetPixel(exc+elx, eyc-ely, Colour);π    SetPixel(exc-elx, eyc-ely, Colour);π  END;πEND;ππ{ these routines have been "compressed" to take up less line space; Iπ  like spaces between addition, subtraction, etc, but I took them outπ  to save space... you can add them again if you want }πππPROCEDURE Line(lnx1, lny1, lnx2, lny2 : Integer);πVAR lndd, lndx, lndy, lnai, lnbi, lnxi, lnyi : Integer;πBEGINπ  IF (lnx1 < lnx2) THEN BEGIN lnxi:=1; lndx:=lnx2-lnx1;π  END ELSE BEGIN lnxi := (-1); lndx:= lnx1-lnx2; END;π  IF (lny1 < lny2) THEN BEGIN lnyi:=1; lndy:=lny2-lny1;π  END ELSE BEGIN lnyi := (-1); lndy:=lny1-lny2; END;π  SetPixel(lnx1, lny1, Colour);π  IF (lndx > lndy) THEN BEGINπ    lnai:=(lndy-lndx)*2; lnbi:=lndy*2; lndd:=lnbi-lndx;π    REPEATπ      IF (lndd >= 0) THEN BEGINπ        Inc(lny1, lnyi);π        Inc(lndd, lnai);π      END ELSE Inc(lndd, lnbi);π      Inc(lnx1, lnxi);π      SetPixel(lnx1, lny1, Colour);π    UNTIL (lnx1 = lnx2);π  END ELSE BEGINπ    lnai := (lndx - lndy) * 2;π    lnbi := lndx * 2;π    lndd := lnbi - lndy;π    REPEATπ      IF (lndd >= 0) THEN BEGINπ        Inc(lnx1, lnxi);π        Inc(lndd, lnai);π      END ELSE inc(lndd, lnbi);π      Inc(lny1, lnyi);π      SetPixel(lnx1, lny1, Colour);π    UNTIL (lny1 = lny2);π  END;πEND;ππPROCEDURE GetPalette(index2get : Byte; VAR r_inte, g_inte, b_inte : Byte);π{ returns the r, g, and b values of a palette index }πBEGINπ  Port[$3C7] := index2get;π  r_inte := Port[$3C9];π  g_inte := Port[$3C9];π  b_inte := Port[$3C9];πEND;ππPROCEDURE SetPalette(index2set, r_inte, g_inte, b_inte : Byte);π{ sets the r, g, and b values of a palette index }πBEGINπ  Port[$3C8] := index2set;π  Port[$3C9] := r_inte;π  Port[$3C9] := g_inte;π  Port[$3C9] := b_inte;πEND;ππ{ oh, I'll give credit where credit is due: Sean Palmer supplied theπ  Bresenham line and ellipse procedures }πππPROCEDURE BurstSetPalette(burstPalette : RGBPalette);πVARπ  burstCount : Word;πBEGINπ  Port[$3C8] := 0;π  FOR burstCount := 0 TO 767 DO Port[$3C9] := burstPalette[burstCount];πEND;ππPROCEDURE WaitForRetrace;π{ waits for a vertical retrace to reduce flicker }πBEGINπ     (* REPEAT UNTIL (Port[$3DA] AND $08) = 0; *)π     { the above loop has been commented because it is only }π     { necessary to wait until a retrace is in progress }π     REPEAT UNTIL (Port[$3DA] AND $08) <> 0;πEND;ππPROCEDURE ClearScr;πBEGINπ     FillChar(Mem[$A000:0000], 64000, 0);πEND;ππFUNCTION GetOverscan : Byte;πVARπ  tmpOverscanByte : Byte;πBEGINπ  ASMπ    MOV AX,$1008π    INT $10π    MOV tmpOverscanByte,BHπ  END;π  GetOverscan := tmpOverscanByte;πEND;ππPROCEDURE SetOverscan(borderColour : Byte);πBEGINπ  ASMπ    MOV AX,$1001π    MOV BH,borderColourπ    INT $10π  END;πEND;ππ{πWell, that's basically it, except for the bitmap scaler.  If you want it, letπme know if you can receive NetMail, and I'll send it that way; otherwise, I'llπpost.  The last two procedures/functions have not been tested.  In fact, Iπcan't guarantee that any of the stuff will work.  But try it out...  :^)πC-YA.π}                 51     01-27-9412:07ALL                      JASEN BETTS              Line Drawing             IMPORT              14     ╓ç∙ {π> I used something like this:π> for x := 1 to 100 doπ> beginπ>      y := slope*x;π>      putpixel(x,y);π> end;ππthe slope method is a close cousin to bubble-sort an algorithm to use ifπyou can't be bothered to use a more efficient one for the job.ππhere's one. that only uses addition and subtraction in it's loop.π(FWIW it's based on the commutativity of multiplication.)ππI think It's got some fancy name which I forget, this code is 100% myπown (freeware) and reasonably well tested.π}ππ  procedure myline(x1,y1,x2,y2,color:integer);ππ    {Freeware: my bugs - your problem , 29 dec 1993 J.Betts,π     PASCAL echo Fidonet.     please keep this notice intact}ππ  function sign(x:integer):integer; {like sgn(x) in basic}π  begin if x<0 then sign:=-1 else if x>0 then sign:=1 else sign:=0 end;π  varπ    x,y,count,xs,ys,xm,ym:integer;π  beginπ    x:=x1;y:=y1;ππ    xs:=x2-x1;    ys:=y2-y1;ππ    xm:=sign(xs); ym:=sign(ys);π    xs:=abs(xs);  ys:=abs(ys);ππ    putpixel(x,y,color);ππ  if xs > ysπ    then begin {flat line <45 deg}π      count:=-(xs div 2);π      while (x <> x2 ) do beginπ        count:=count+ys;π        x:=x+xm;π        if count>0 then beginπ          y:=y+ym;π          count:=count-xs;π          end;π        putpixel(x,y,color);π        end;π      endπ    else begin {steep line >=45 deg}π      count:=-(ys div 2);π      while (y <> y2 ) do beginπ        count:=count+xs;π        y:=y+ym;π        if count>0 then beginπ          x:=x+xm;π          count:=count-ys;π          end;π        putpixel(x,y,color);π        end;π      end;π  end;ππ                                                                                                      52     01-27-9412:09ALL                      JORDAN PHILLIPS          Graphics Images          IMPORT              21     ╓Ç0 {π  Well, here are some image routines, I made it to where the WIDTH is storedπ in the first two bytes and the HEIGHT is stored in the 3rd and 4th bytes...π If you must really know... I guess it goes along with TP's get/put imageπ convention... This is for mode $13 ONLY of coarse...π}ππ  Procedure GetImage ( X1, Y1, X2, Y2 : Integer; VAR DEST ) ;π   Var Width,S,O : Word ;ππ    BEGINπ     S := SEG (DEST);π     O := OFS (DEST);ππ     ASMπ      PUSH DSππ      MOV DX, Video_Segπ      MOV DS, DXπ      MOV BX, 320π      MOV AX, Y1; MUL BXπ      ADD AX, X1; MOV SI, AXππ      MOV DX, Sπ      MOV ES, DXπ      MOV DI, Oππ      MOV DX, Y2; SUB DX, Y1; INC DXπ      MOV BX, X2; SUB BX, X1; INC BXπ      MOV WIDTH, BXππ      MOV AX, WIDTHπ      STOSWπ      MOV AX, DXπ      STOSWππ     @LOOP:π      MOV CX, WIDTHπ      REP MOVSBπ      ADD SI, 320; SUB SI, WIDTHπ      DEC DXπ      JNZ @LOOPππ      POP DSπ     End ;π   End ;ππ  Procedure PutImage ( X1, Y1 : Integer; VAR SOURCE ) ;π   Var Width, S, O : Word ;π    BEGINπ     S := SEG (SOURCE);π     O := OFS (SOURCE);ππ     ASMπ      PUSH DSππ      MOV DX, Video_Segπ      MOV ES, DXπ      MOV BX, 320            { Setup Dest Addr }π      MOV AX, Y1; MUL BXπ      ADD AX, X1; MOV DI, AXππ      MOV DX, S { Setup Source Addr }π      MOV DS, DXπ      MOV SI, Oππ      LODSW   { Get Width and Height }π      MOV WIDTH, AXπ      LODSWπ      MOV DX, AXππ     @LOOP:π      MOV CX, WIDTHπ      REP MOVSBπ      ADD DI, 320; SUB DI, WIDTHπ      DEC DXπ      JNZ @LOOPππ      POP DSπ     End ;π   End ;ππ  Function SaveImage ( X1, Y1, X2, Y2 : Integer ; VAR Size : Word ) : Pointer ;π   Var Img : Pointer ;π    Beginπ     FixInt ( X1, X2 ) ; { Put lesser in X1 }π     FixInt ( Y1, Y2 ) ; { Put lesser in Y1 }π     Size := WORD((X2-X1+1)*(Y2-Y1+1) +4);π     GetMem ( Img, Size ) ;π     GetImage ( X1, Y1, X2, Y2, Img^ ) ;π     SaveImage := Img ;π    End ;ππ Procedure CopyImage ( X1, Y1, X2, Y2, Dx, DY : Integer ) ;π  Var Img : Pointer ;π      Size : Word ;π   Beginπ    Img := SaveImage ( X1, Y1, X2, Y2, Size ) ;π    PutImage ( Dx, Dy, Img^) ;π    FreeMem ( Img, Size ) ;π   End ;ππ Procedure LoadImage ( FileName : String ; VAR Img : Pointer ; Var Size : Wordπ   Var F : File ;π  Beginπ   Img := NIL ;π   Size := 0 ;π   If Not Exist ( FileName ) Then Exit ;π   Assign ( F, Filename ) ;π   Reset ( F, 1 ) ;π   Size := FileSize ( F ) ;π   GetMem ( Img, Size ) ;π   BlockRead ( F, Img^, Size ) ;π   Close ( F ) ;π  End ;π                                                                                                        53     01-27-9412:11ALL                      SEAN PALMER              Flood Filling            IMPORT              13     ╓5& {π> Does anyone have any code to flood fill an area? I need the code to doπ> both, a fill to a certain border colour, or a fill to ANYπ> colour other then the one the fill started on.π}ππvar fillVal:byte;π{This routine only called by fill}πfunction lineFill(x,y,d,prevXL,prevXR:integer):integer;π var xl,xr,i:integer;πbeginπ xl:=x;xr:=x;π repeat dec(xl); until(scrn(xl,y)<>fillVal)or(xl<0); inc(xl);π repeat inc(xr); until(scrn(xr,y)<>fillVal)or(xr>xMax); dec(xr);π hLin(xl,xr,y);π inc(y,d);π if word(y)<=yMax thenπ  for x:=xl to xr doπ   if(scrn(x,y)=fillVal)then beginπ    x:=lineFill(x,y,d,xl,xr);π    if word(x)>xr then break;π    end;π dec(y,d+d); asm neg d;end;π if word(y)<=yMax then beginπ  for x:=xl to prevXL doπ   if(scrn(x,y)=fillVal)then beginπ    i:=lineFill(x,y,d,xl,xr);π    if word(x)>prevXL then break;π    end;π  for x:=prevXR to xr doπ   if(scrn(x,y)=fillVal)then beginπ    i:=lineFill(x,y,d,xl,xr);π    if word(x)>xr then break;π    end;π  end;π lineFill:=xr;π end;ππprocedure fill(x,y:integer);beginπ fillVal:=scrn(x,y);if fillVal<>color then lineFill(x,y,1,x,x);π end;ππ{πThis one's too recursive for anything really complicated (blows the stack). Butπit works. You'll find that making it do a border fill instead isn't hard atπall. You'll need to provide your own hLin and scrn routines.ππhLin draws a horizontal line from X,to X2,at Y scrn reads the pixel at X,Y andπreturns its color color is a global byte variable in this incarnation. The fillπhappens in this color.π}π                                       54     01-27-9412:13ALL                      TIM JENSEN               Masked Images            IMPORT              12     ╓0▀ {π>Try converting it to use pointers instead of accessing the array withπ>indexes, and use a pointer to video memory for direct plotsπ>instead of using the putPixel routine. Also it's quicker toπ>check against 0 for the background than to check against 255.ππI found a copy of "The Visible Computer: 8088" in my bookshelves andπtried rewriting my assembly routines.  Here's what I finally got:π}ππprocedure MaskPut(x,y: word; p: pointer); assembler;πvarπ XX,YY: byte;πasmπ        LES SI,pπ        MOV [XX],0π        MOV [YY],0π        MOV CX,256π        XOR DX,DXπ        CLDπ@Loopit:SEGES LODSBπ        MOV DL,ALπ        PUSH ESπ        PUSH SIπ        CMP DL,255π        JZ @Doneπ        MOV AX,0A000hπ        MOV ES,AXπ        MOV AX,320π        MOV BX,[Y]π        ADD BL,[YY]π        PUSH DXπ        MUL BXπ        POP DXπ        MOV BX,[X]π        ADD BL,[XX]π        ADD AX,BXπ        MOV SI,AXπ        MOV ES:[SI],DLπ@Done:  INC [XX]π        CMP [XX],16π        JNZ @Okayπ        MOV [XX],0π        INC [YY]π@Okay:  POP SIπ        POP ESπ        LOOP @Loopitπend;ππ{πIt works fine.  I didn't notice much of a difference in speed though.  Iπtested it and I can plot about 1103 sprites/second in ASM and 828πsprites/sec. with my original TP code.  Please keep in mind I'm not muchπof an assembly programmer. Can anyone help me optimize this code (intoπ286 would be good too). Thanx for your help!π}π    55     01-27-9412:14ALL                      JENS LARSSON             ModeX Scrolling          IMPORT              6      ╓π┬ {π> does anyone know how to scroll up or down in 320*200*256 mode ??ππ     Enter mode-x (look for source on any board, quite common), andπ     then pan the screen like this:π}ππ     Asmπ      mov     bx,StartMemπ      mov     ah,bhπ      mov     al,0chπ      mov     dx,3d4hπ      out     dx,axπ      mov     ah,blπ      inc     alπ      out     dx,axπ     End;π{π     To begin, zero StartMem and then increase it with 80 each time -π     tada - the screen pans down. Oh, btw, If I were you I would callπ     a sync just before running it...π}                                                                                                 56     01-27-9412:15ALL                      RICHARD MOREY            Images                   IMPORT              13     ╓╟ {π-> I'm trying to use the GetImage and PutImage commands from Turboπ-> PascalππOkay.. did you declare a varible that would hold the size you needed? Iπhave a little program I wrote to draw a musical staff and put the notesπup randomly so that I can practice reading music..π}ππProgram MusicNotes;ππUsesπ  Crt,π  Dos,π  Graph,π  XtraDos;ππconstπ  NotePos : Array[1..11] Of Integer =π(164,179,194,209,224,239,254,269,284,299,314);π  Note : Array[1..11] Of Char =π('G','F','E','D','C','B','A','G','F','E','D');ππProcedure Beep;ππbeginπ  sound(600);π  delay(100);π  nosound;πend;ππvarπ  CallUnit : CallH;π  Key : Char;π  P : Pointer;π  Size : Word;π  Y, X,π  MaxX, MaxY,π  grMode,π  grDriver : Integer;ππBeginπgrDriver := Detect;πInitGraph(grDriver, grMode,'D:\bp\bgi');πMaxX:=GetMaxX;πMaxY:=GetMaxY;πSetColor(white);πCircle(15,15,15);πFloodFill(15,15,white);πSize:=ImageSize(0,0,30,30);πGetMem(P,Size);πgetImage(0,0,30,30,P^);πcleardevice;πY:=((MaxY Div 2)-60);πFor X:=1 To 5 Doπ Beginπ  Line(0,Y,MaxX,Y);π  Y:=Y+30;π End;πRandomize;πRepeatπX:=Random(11)+1;π  PutImage(320,(NotePos[X]-15),P^,ORPut);π  Repeatπ   Key:=Char(CallUnit.KeyReturn);π  Until Key=Note[X];π  Beep;π  PutImage(320,(NotePos[X]-15),P^,XOrPut);π  If (X/2)=(X Div 2) Thenπ    Line(290,NotePos[x],350,NotePos[x])π    Elseπ     If X>1 Thenπ       Line(290,NotePos[x-1],350,NotePos[x-1]);πUntil 3=2;πEnd.ππThe important part is the SIZE=.. Use that line to create a varbibleπbuig enough to hold the image.π                                                                  57     01-27-9412:17ALL                      DAVID DAHL               Palette Maniputlation    IMPORT              44     ╓Mö {$G+}  { Enable 286 Instructions }πUnit Palette;ππ{ Programmed By David Dahl }ππ(* PUBLIC DOMAIN *)ππInterfaceππ  Type PaletteRec  = Recordπ                           Red,π                           Green,π                           Blue  : Byte;π                     End;π       PaletteType = Array[0..255] of PaletteRec;π       PalettePtr  = ^PaletteType;ππ  Procedure SetPalette        (Var PalBuf : PaletteType);π  Procedure GetPalette        (Var PalBuf : PaletteType);ππ  Procedure BlackPalette;π  Procedure FadeInFromBlack   (Var Palin : PaletteType);π  Procedure FadeInFromBlackQ  (Var Palin     : PaletteType;π                                   Intensity : Word);π  Procedure FadeOutToBlack    (Var Palin : PaletteType);π  Procedure FadeFromPalToPal  (Var OldPal, NewPal : PaletteType);π  Procedure FadeFromPalToPalQ (Var OldPal, NewPal : PaletteType;π                                   Color          : Word);πππ  Var BlackP  : PaletteType;π      WhiteP  : PaletteType;ππ      TempPal : PaletteType;ππImplementationππ{-[ Set Value Of All DAC Registers ]--------------------------------------}πProcedure SetPalette (Var PalBuf : PaletteType); Assembler;πAsmπ    PUSH DSππ    XOR AX, AX       { Palette Start = 0 }π    MOV CX, 0300h / 2π    LDS SI, PalBuf   { Load DS:SI With Address Of PalBuf (For OUTSB) }ππ    MOV DX, 03C8h    { Tell VGA Card What DAC Color To Start With }π    OUT DX, ALππ    INC DX           { Set DX To Equal DAC Data Port }π    MOV BX, DXπ    CLDππ    { Wait For V-sync }π    MOV DX, 03DAhπ    @VSYNC0:π      IN   AL, DXπ      TEST AL, 8π    JZ @VSYNC0ππ    MOV DX, BXπ    REPπ       OUTSBππ    MOV BX, DXππ    { Wait For V-sync }π    MOV DX, 03DAhπ    @VSYNC1:π      IN   AL, DXπ      TEST AL, 8π    JZ @VSYNC1ππ    MOV DX, BXπ    MOV CX, 0300h / 2π    REPπ       OUTSBππ    POP DSπEnd;ππ{-[ Get Value Of All DAC Registers ]--------------------------------------}πProcedure GetPalette (Var PalBuf : PaletteType); Assembler;πAsmπ    PUSH DSππ    XOR AX, AX       { Palette Start = 0 }π    MOV CX, 0300hπ    LES DI, PalBuf   { Load ES:DI With Address Of PalBuf (For INSB) }ππ    MOV DX, 03C7h    { Tell VGA Card What DAC Color To Start With }π    OUT DX, ALππ    INC DX           { Set DX To Equal DAC Data Port }π    INC DXπ    CLDππ    REPπ       INSBππ    POP DSπEnd;πππProcedure BlackPalette;πBeginπ     SetPalette (BlackP);πEnd;ππProcedure FadeInFromBlack (Var Palin : PaletteType);πVar DAC,π    Intensity : Word;πBeginπ     For Intensity := 0 to 32 doπ     Beginπ       For DAC := 0 to 255 doπ       Beginπ          TempPal[DAC].Red   := (Palin[DAC].Red   * Intensity) DIV 32;π          TempPal[DAC].Green := (Palin[DAC].Green * Intensity) DIV 32;π          TempPal[DAC].Blue  := (Palin[DAC].Blue  * Intensity) DIV 32;π       End;ππ       SetPalette (TempPal);π     End;πEnd;ππProcedure FadeInFromBlackQ (Var Palin     : PaletteType;π                                Intensity : Word);πConst DAC : Word = 0;πBeginπ     For DAC := 0 to 255 doπ     Beginπ          TempPal[DAC].Red   := (Palin[DAC].Red   * Intensity) DIV 32;π          TempPal[DAC].Green := (Palin[DAC].Green * Intensity) DIV 32;π          TempPal[DAC].Blue  := (Palin[DAC].Blue  * Intensity) DIV 32;π     End;ππ     SetPalette (TempPal);πEnd;ππProcedure FadeOutToBlack (Var Palin : PaletteType);πVar DAC,π    Intensity : Word;πBeginπ     For Intensity := 32 downto 0 doπ     Beginπ       For DAC := 0 to 255 doπ       Beginπ          TempPal[DAC].Red   := (Palin[DAC].Red   * Intensity) DIV 32;π          TempPal[DAC].Green := (Palin[DAC].Green * Intensity) DIV 32;π          TempPal[DAC].Blue  := (Palin[DAC].Blue  * Intensity) DIV 32;π       End;ππ       SetPalette (TempPal);π     End;πEnd;πππProcedure FadeFromPalToPal (Var OldPal, NewPal : PaletteType);πVar DAC,π    Color : Word;πBeginπ     For Color := 32 downto 0 doπ     Beginπ       For DAC := 0 to 255 doπ       Beginπ          TempPal[DAC].Red   := ((OldPal[DAC].Red   * Color) DIV 32) +π                                ((NewPal[DAC].Red   * (32 - Color)) DIV 32);π          TempPal[DAC].Green := ((OldPal[DAC].Green * Color) DIV 32) +π                                ((NewPal[DAC].Green * (32 - Color)) DIV 32);π          TempPal[DAC].Blue  := ((OldPal[DAC].Blue  * Color) DIV 32) +π                                ((NewPal[DAC].Blue  * (32 - Color)) DIV 32);π       End;ππ       SetPalette (TempPal);π     End;πEnd;ππProcedure FadeFromPalToPalQ (Var OldPal, NewPal : PaletteType;π                                 Color          : Word);πConst DAC : Word = 0;πBeginπ     For DAC := 0 to 255 doπ     Beginπ          TempPal[DAC].Red   := ((OldPal[DAC].Red   * (32 - Color)) DIV 32)+π                                ((NewPal[DAC].Red   * Color) DIV 32);π          TempPal[DAC].Green := ((OldPal[DAC].Green * (32 - Color)) DIV 32)+π                                ((NewPal[DAC].Green * Color) DIV 32);π          TempPal[DAC].Blue  := ((OldPal[DAC].Blue  * (32 - Color)) DIV 32)+π                                ((NewPal[DAC].Blue  * Color) DIV 32);π     End;ππ     SetPalette (TempPal);πEnd;ππVar Counter : Word;πBeginπ     For Counter := 0 to 255 doπ     Beginπ          BlackP[Counter].Red   := 0;π          BlackP[Counter].Green := 0;π          BlackP[Counter].Blue  := 0;π     End;ππ     For Counter := 0 to 255 doπ     Beginπ          WhiteP[Counter].Red   := 63;π          WhiteP[Counter].Green := 63;π          WhiteP[Counter].Blue  := 63;π     End;πEnd.ππ                                                                               58     01-27-9412:17ALL                      LIOR BAR-ON              PCX Files                IMPORT              122    ╓2V πunit PCX;ππ{   The following display modes are supported:ππ          Mode      TP GraphMode     Resolution    Colorsπ          ~~~~      ~~~~~~~~~~~~     ~~~~~~~~~~    ~~~~~~π          $04       CGAC0 to C3      320 x 200         4π          $06       CGAHi            640 x 200         2π          $0D        ---             320 x 200        16π          $0E       EGALo/VGALo      640 x 200        16π          $10       EGAHi/VGAMed     640 x 350        16π          $12       VGAHi            640 x 480        16π          $13        ---             320 x 200       256ππ   Mode $13 is supported only for files containing palette information,π   i.e. not those produced by versions of Paintbrush earlier than 3.0.}ππINTERFACEππuses DOS, GRAPH;ππtype    RGBrec = recordπ                   redval, greenval, blueval: byte;π                 end;ππvar     pcxfilename: pathstr;π        file_error: boolean;π        pal: palettetype;π        RGBpal: array[0..15] of RGBrec;π        RGB256: array[0..255] of RGBrec;π        page_addr: word;π        bytes_per_line: word;π        buff0, buff1: pointer;ππ        { CGA display memory banks: }π        screenbuff0: array[0..7999] of byte absolute $b800:$0000;π        screenbuff1: array[0..7999] of byte absolute $b800:$2000;ππconst   page0 = $A000;           { EGA/VGA display segment }ππprocedure SETMODE(mode: byte);πprocedure SETREGISTERS(var palrec);πprocedure READ_PCX_FILE(gdriver: integer; pfilename: pathstr);πprocedure READ_PCX256(pfilename: pathstr);ππ{========================================================================}ππIMPLEMENTATIONππvar     scratch, abuff0, abuff1: pointer;π        is_CGA, is_VGA: boolean;π        repeatcount: byte;π        datalength: word;π        columncount, plane, video_index: word;π        regs: registers;ππconst   buffsize = 65521;   { Largest possible }ππ{ -------------------------- BIOS calls --------------------------------- }ππ{ For modes not supported by the BGI, use SetMode to initialize theπ  graphics. Since SetRGBPalette won't work if Turbo hasn't done theπ  graphics initialization itself, use SetRegisters to change the colorsπ  in mode $13. }ππprocedure SETMODE(mode: byte);ππbeginπregs.ah:= 0;                 { BIOS set mode function }πregs.al:= mode;              { Display mode }πintr($10, regs);             { Call BIOS }πend;ππprocedure SETREGISTERS(var palrec);ππ{ Palrec is any string of 768 bytes containing the RGB data. }ππbeginπregs.ah:= $10;               { BIOS color register function }πregs.al:= $12;               { Subfunction }πregs.es:= seg(palrec);       { Address of palette info. }πregs.dx:= ofs(palrec);πregs.bx:= 0;                 { First register to change }πregs.cx:= $100;              { Number of registers to change }πintr($10, regs);             { Call BIOS }πend;ππ{ ====================== EGA/VGA 16-color files ========================= }ππprocedure DECODE_16; assembler;ππasmπpush    bpππ{ ----------------- Assembler procedure for 16-color files -------------- }ππ{ The first section is initialization done on each run through theπ  input buffer. }ππ@startproc:πmov     bp, plane           { plane in BP }πmov     es, page_addr       { video display segment }πmov     di, video_index     { index into video segment }πmov     ah, byte ptr bytes_per_line  { line length in AH }πmov     dx, columncount     { column counter }πmov     bx, datalength      { no. of bytes to read }πxor     cx, cx              { clean up CX for loop counter }πmov     cl, repeatcount     { count in CX }πpush    ds                  { save DS }πlds     si, scratch         { input buffer pointer in DS:SI }πadd     bx, siπcld                         { clear DF for stosb }πcmp     cl, 0               { was last byte a count? }πjne     @multi_data         { yes, so next is data }πjmp     @getbyte            { no, so find out what next is }ππ{ -------------- Procedure to write EGA/VGA image to video -------------- }ππ@writebyte:πstosb                       { AL into ES:DI, inc DI }πinc     dl                  { increment column }πcmp     dl, ah              { reached end of scanline? }πje      @doneline           { yes }πloop    @writebyte          { no, do another }πjmp     @getbyte            {   or get more data }π@doneline:πshl     bp, 1               { shift to next plane }πcmp     bp, 8               { done 4 planes? }πjle     @setindex           { no }πmov     bp, 1               { yes, reset plane to 1 but don't reset index }πjmp     @setplaneπ@setindex:πsub     di, dx              { reset to start of line }π@setplane:πpush    ax                  { save AX }πcli                         { no interrupts }πmov     ax, bp              { plane is 1, 2, 4, or 8 }πmov     dx, 3C5h            { sequencer data register }πout     dx, al              { mask out 3 planes }πsti                         { enable interrupts }πpop     ax                  { restore AX }πxor     dx, dx              { reset column count }πloop    @writebyte          { do it again, or fetch more data }ππ@getbyte:                   { last byte was not a count }πcmp     si, bx              { end of input buffer? }πje      @exit               { yes, quit }πlodsb                       { get a byte from DS:SI into AL, increment SI }πcmp     al, 192             { test high bits }πjb      @one_data           { not set, it's data to be written once }π { It's a count byte: }πxor     al, 192             { get count from 6 low bits }πmov     cl, al              { store repeat count }πcmp     si, bx              { end of input buffer? }πje      @exit               { yes, quit }π@multi_data:πlodsb                       { get data byte }πjmp     @writebyte          { write it CL times }π@one_data:πmov     cl, 1               { write byte once }πjmp     @writebyteππ{ ---------------------- Finished with buffer --------------------------- }ππ@exit:πpop     ds                  { restore Turbo's data segment }πmov     plane, bp           { save status for next run thru buffer }πmov     repeatcount, clπmov     columncount, dxπmov     video_index, diπpop     bpπend;  { asm }ππ{ ===================== CGA 2- and 4-color files ======================== }ππprocedure DECODE_CGA; assembler;ππasmππpush    bpπjmp     @startprocππ{ ------------- Procedure to store CGA image in buffers ----------------- }ππ@storebyte:πstosb                       { AL into ES:DI, increment DI }πinc     dx                  { increment column count }πcmp     dl, ah              { reached end of line? }πje      @row_ends           { yes }πloop    @storebyte          { not end of row, do another byte }πretπ@row_ends:πxor     bp, 1               { switch banks }πcmp     bp, 1               { is bank 1? }πje      @bank1              { yes }πmov     word ptr abuff1, di { no, save index into bank 1 }πles     di, abuff0          { bank 0 pointer into ES:DI }πxor     dx, dx              { reset column counter }πloop    @storebyteπretπ@bank1:πmov     word ptr abuff0, di { save index into bank 0 }πles     di, abuff1          { bank 1 pointer into ES:DI }πxor     dx, dx              { reset column counter }πloop    @storebyteπretππ{ ---------------- Main assembler procedure for CGA --------------------- }ππ@startproc:πmov     bp, 0                        { bank in BP }πmov     es, word ptr abuff0[2]       { segment of bank 0 buffer }πmov     di, word ptr abuff0          { offset of buffer }πmov     ah, byte ptr bytes_per_line  { line length in AH }πmov     bx, datalength               { no. of bytes to read }πxor     cx, cx                       { clean up CX for loop counter }πxor     dx, dx                       { initialize column counter }πmov     si, dx                       { initialize input index }πcld                                  { clear DF for stosb }ππ{ -------------------- Loop through input buffer ------------------------ }ππ@getbyte:πcmp     si, bx              { end of input buffer? }πje      @exit               { yes, quit }πpush    es                  { save output pointer }πpush    diπles     di, scratch         { get input pointer in ES:DI }πadd     di, si              { add current offset }πmov     al, [es:di]         { get a byte }πinc     si                  { advance input index }πpop     di                  { restore output pointer }πpop     esπcmp     cl, 0               { was previous byte a count? }πjg      @multi_data         { yes, this is data }πcmp     al, 192             { no, test high bits }πjb      @one_data           { not set, not a count }π { It's a count byte: }πxor     al, 192             { get count from 6 low bits }πmov     cl, al              { store repeat count }πjmp     @getbyte            { go get data byte }π@one_data:πmov     cl, 1               { write byte once }πcall    @storebyteπjmp     @getbyteπ@multi_data:πcall    @storebyte          { CL already set }πjmp     @getbyteππ{ ---------------------- Finished with buffer --------------------------- }ππ@exit:πpop     bpπend;  { asm }ππ{ ============= Main procedure for CGA and 16-color files =============== }ππprocedure READ_PCX_FILE(gdriver: integer; pfilename: pathstr);ππtype    ptrrec = recordπ                   segm, offs: word;π                 end;ππvar     entry, gun, pcxcode, mask, colorID: byte;π        palbuf: array[0..66] of byte;π        pcxfile: file;ππbegin   { READ_PCX_FILE }πis_CGA:= (gdriver = CGA);   { 2 or 4 colors }πis_VGA:= (gdriver = VGA);   { 16 of 256K possible colors }π                            { Otherwise EGA - 16 of 64 possible colors }πassign(pcxfile, pfilename);π{$I-} reset(pcxfile, 1);  {$I+}πfile_error:= (IOresult <> 0);πif file_error then exit;ππgetmem(scratch, buffsize);                 { Allocate scratchpad }πblockread(pcxfile, scratch^, 128);         { Get header into scratchpad }ππmove(scratch^, palbuf, 67);πbytes_per_line:= palbuf[66];ππ{------------------------ Setup for CGA ---------------------------------}ππif is_CGA thenπbeginπ  getmem(buff0, 8000);      { Allocate memory for output }π  getmem(buff1, 8000);π  abuff0:= buff0;           { Make copies of pointers }π  abuff1:= buff1;πend elseππ{----------------------- Setup for EGA/VGA ------------------------------}ππbeginπ  video_index:= 0;π  port[$3C4]:= 2;           { Index to map mask register }π  plane:= 1;                { Initialize plane }π  port[$3C5]:= plane;       { Set sequencer to mask out other planes }ππ  for entry:= 0 to 15 doπ  beginπ    colorID:= 0;π    for gun:= 0 to 2 doπ    beginπ      pcxcode:= palbuf[16 + entry * 3 + gun];   { Get primary color value }π      if not is_VGA thenπ      begin                                     { Interpret for EGA }π        case (pcxcode div $40) ofπ          0: mask:= $00;    { 000000 }π          1: mask:= $20;    { 100000 }π          2: mask:= $04;    { 000100 }π          3: mask:= $24;    { 100100 }π        end;π        colorID:= colorID or (mask shr gun);    { Define two bits }π      end  { not is_VGA }π      elseπ      begin  { is_VGA }π        with RGBpal[entry] do                   { Interpret for VGA }π        case gun ofπ          0: redval:= pcxcode div 4;π          1: greenval:= pcxcode div 4;π          2: blueval:= pcxcode div 4;π        end;π      end;  { is_VGA }π    end;  { gun }π    if is_VGA then pal.colors[entry]:= entryπ              else pal.colors[entry]:= colorID;π  end;  { entry }π  pal.size:= 16;πend;   { not is_CGA }ππ{ ---------------- Read and decode the image data ----------------------- }ππrepeatcount:= 0;                        { Initialize assembler vars. }πcolumncount:= 0;πrepeatπ  blockread(pcxfile, scratch^, buffsize, datalength);π  if is_CGA then decode_CGA else decode_16;   { Call assembler routine }πuntil eof(pcxfile);πclose(pcxfile);πif not is_CGA then port[$3C5]:= $F;     { Reset mask map }πfreemem(scratch,buffsize);              { Discard scratchpad }πend;  { READ_PCX_FILE }ππ{ ========================= 256-color files ============================= }ππprocedure DECODE_PCX256; assembler;ππasmπmov     es, page_addr       { video segment }πmov     di, video_index     { index into video }πxor     cx, cx              { clean up loop counter }πmov     cl, repeatcount     { count in CL }πmov     bx, datalength      { end of input buffer }πpush    ds                  { save DS }πlds     si, scratch         { pointer to input in DS:SI }πadd     bx, si              { adjust datalength - SI may not be 0 }πcld                         { clear DF }πcmp     cl, 0               { was last byte a count? }πjne     @multi_data         { yes, so next is data }ππ{ --------------------- Loop through input buffer ----------------------- }ππ@getbyte:                   { last byte was not a count }πcmp     si, bx              { end of input buffer? }πje      @exit               { yes, quit }πlodsb                       { get byte into AL, increment SI }πcmp     al, 192             { test high bits }πjb      @one_data           { not set, not a count }π{ It's a count byte }πxor     al, 192             { get count from 6 low bits }πmov     cl, al              { store repeat count }πcmp     si, bx              { end of input buffer? }πje      @exit               { yes, quit }π@multi_data:πlodsb                       { get byte into AL, increment SI }πrep     stosb               { write byte CX times }πjmp     @getbyteπ@one_data:πstosb                       { byte into video }πjmp     @getbyteππ{ ------------------------- Finished with buffer ------------------------ }ππ@exit:πpop     ds                  { restore Turbo's data segment }πmov     video_index, di     { save status for next run thru buffer }πmov     repeatcount, clπend;  { asm }ππ{ ================= Main procedure for 256-color files ================== }ππprocedure READ_PCX256(pfilename: pathstr);ππvar     x, gun, pcxcode: byte;π        pcxfile: file;π        palette_start, total_read: longint;π        palette_flag: byte;π        version: word;ππprocedure CLEANUP;ππbeginπclose(pcxfile);πfreemem(scratch, buffsize);πend;ππbegin    { READ_PCX256 }πassign(pcxfile, pfilename);π{$I-} reset(pcxfile, 1);  {$I+}πfile_error:= (IOresult <> 0);πif file_error then exit;πgetmem(scratch, buffsize);                  { Allocate scratchpad }πblockread(pcxfile, version, 2);             { Read first two bytes }πfile_error:= (hi(version) < 5);             { No palette info. }πif file_error thenπbeginπ  cleanup; exit;πend;πpalette_start:= filesize(pcxfile) - 769;ππseek(pcxfile, 128);                        { Scrap file header }πtotal_read:= 128;ππrepeatcount:= 0;                           { Initialize assembler vars. }πvideo_index:= 0;ππrepeatπ  blockread(pcxfile, scratch^, buffsize, datalength);π  inc(total_read, datalength);π  if (total_read > palette_start) thenπ      dec(datalength, total_read - palette_start);π  decode_pcx256;πuntil (eof(pcxfile)) or (total_read>= palette_start);ππseek(pcxfile, palette_start);πblockread(pcxfile, palette_flag, 1);πfile_error:= (palette_flag <> 12);πif file_error thenπbeginπ  cleanup; exit;πend;πblockread(pcxfile, RGB256, 768);         { Get palette info. }πfor x:= 0 to 255 doπwith RGB256[x] doπbeginπ  redval:= redval shr 2;π  greenval:= greenval shr 2;π  blueval:= blueval shr 2;πend;πcleanup;πend;  { READ_PCX256 }ππ{ ========================== Initialization ============================= }ππBEGINπpage_addr:= page0;                      { Destination for EGA/VGA data }πEND.π                                                                                                                         59     01-27-9412:18ALL                      DAVID DAHL               Plasma                   IMPORT              33     ╓O¼ {$G+} { Enable 286 Instructions }π{$N+} { Enable Math Coprocessor - Delete This Line If You Don't Have One }πProgram FractalPlasma;ππ{ Programmed By David Dahl }ππ(* PUBLIC DOMAIN *)ππUsesπ  CRT,π  Palette;ππConstπ  Rug = 0.2;ππTypeπ  VGAPtr  = ^VGAType;π  VGAType = Array [0..199, 0..319] of Byte;ππVarπ  Screen    : VGAPtr;ππ  PlasmaMap : VGAPtr;π  PlasmaPal : PaletteType;ππProcedure GeneratePlasma(P : VGAPtr);π{                                                                 }π{ This procedure uses an algorithm to generate a fractal surface. }π{                                                                 }π{ Algorithm from page 359 of _Computer_Graphics:_the_Principles_  }π{ _Behind_the_Art_And_Science_ by Pokorny and Gerald.             }π{                                                                 }π  Procedure FractPlasma(il, jl, ih, jh : Integer);π  Varπ    im, jm : Integer;π  Beginπ    im := (il + ih + 1) DIV 2;π    jm := (jl + jh + 1) DIV 2;ππ    If jm < jh thenπ    Beginπ      If P^[il,jm] = 0 Thenπ        P^[il,jm] := Trunc(((P^[il,jl] + P^[il,jh]) / 2) +π                              Random*Rug*(jh-jl));π      If il < ih Thenπ        P^[ih,jm] := Trunc(((P^[ih,jl] + P^[ih,jh]) / 2) +π                              Random*Rug*(jh-jl));π    End;ππ    If im < ih thenπ    Beginπ      If P^[im,jl] = 0 Thenπ        P^[im,jl] := Trunc(((P^[il,jl] + P^[ih,jl]) / 2) +π                              Random*Rug*(ih-il));π      If jl < jh Thenπ        P^[im,jh] := Trunc(((P^[il,jh] + P^[ih,jh]) / 2) +π                              Random*Rug*(jh-jl));π    End;ππ    If (im < ih) AND (jm < jh) Thenπ      P^[im,jm] := Trunc(((P^[il,jl] + P^[ih,jl] +π                           P^[il,jh] + P^[ih, jh]) / 4) +π                           Random*Rug*(ABS(ih-il)+abs(jh-jl)));π    If (im < ih) OR (jm < jh) Thenπ    Beginπ      FractPlasma(il, jl, im, jm);π      FractPlasma(il, jm, im, jh);π      FractPlasma(im, jl, ih, jm);π      FractPlasma(im, jm, ih, jh);π    End;π  End;ππBeginπ  FractPlasma(0, 0, 199, 319);πEnd;ππProcedure InitVGA13h; Assembler;πAsmπ  MOV AX, $0013π  INT $10πEnd;ππProcedure CalculatePalette(Var PalOut : PaletteType);πVarπ  RA, GA, BA : Integer;π  RF, GF, BF : Integer;π  RS, GS, BS : Integer;π  Counter    : Word;πBeginπ  RA := 16 + Random(32-16);π  GA := 16 + Random(32-16);π  BA := 16 + Random(32-16);ππ  RF := 2 + Random(5);π  GF := 2 + Random(5);π  BF := 2 + Random(5);ππ  RS := Random(64);π  GS := Random(64);π  BS := Random(64);πππ  For Counter := 0 to 255 doπ  With PalOut[Counter] doπ  Beginπ    Red   := 32 + Round(RA * Sin((RS + Counter * RF) * Pi / 128));π    Green := 32 + Round(GA * Sin((GS + Counter * GF) * Pi / 128));π    Blue  := 32 + Round(BA * Sin((BS + Counter * BF) * Pi / 128));π  End;πEnd;ππProcedure RotatePalette(Var PalIn : PaletteType);πVarπ  TRGB : PaletteRec;πBeginπ  TRGB := PalIn[0];π  Move (PalIn[1], PalIn[0], 255 * 3);π  PalIn[255] := TRGB;πEnd;ππVarπ  Int : Integer;π  Key : Char;πBeginπ  DirectVideo := False;π  Randomize;ππ  InitVGA13h;ππ  Screen := Ptr($A000,$0000);π  New(PlasmaMap);ππ  { Initialize Workspace }π  FillChar(PlasmaMap^, 320 * 200 , 0);ππ  { Calculate Smooth Random Colors }π  CalculatePalette(PlasmaPal);ππ  GotoXY(12, 12);π  Writeln('Generating Plasma');π  GotoXY(14, 14);π  Writeln('Please Wait...');ππ  GeneratePlasma(PlasmaMap);ππ  { Set All Colors to Black }π  BlackPalette;π  { Copy Fractal To Screen }π  Screen^ := PlasmaMap^;ππ  { Rotate Palette And Fade It In Slowly }π  For Int := 1 to 32 doπ  Beginπ    RotatePalette(PlasmaPal);π    FadeInFromBlackQ(PlasmaPal, Int);π  End;ππ  { Rotate Full Intensity Palette And Wait For KeyPress }π  Repeatπ    RotatePalette(PlasmaPal);π    SetPalette(PlasmaPal);π  Until KeyPressed;ππ  { Rotate Palette and Fade It Out Slowly }π  For Int := 31 downto 0 doπ  Beginπ    RotatePalette(PlasmaPal);π    FadeInFromBlackQ(PlasmaPal, Int);π  End;ππ  Dispose(PlasmaMap);ππ  TextMode(C80);ππ  { Flush Keyboard Buffer }π  While KeyPressed doπ    Key := ReadKey;πEnd.π                                                                                      60     01-27-9412:18ALL                      SEAN PALMER              Poly Drawing             IMPORT              30     ╓τ% (*π> It's not that slow. I can get about 60 good-sizedπ> poly's in a second on my dinky 386sx-20. It also doesπ> ^ ^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^π> I don't know what a good speed is for polyfills, but this sounds quiteπ> good! Thanks heaps (and stacks?  :^) for the post!ππYou're welcome. I just now converted it to 99% assembler, 386+, just gottaπtest it out.ππ> One question to follow:ππ> {  fillWord(mem[$A000:0],64000,0);  {clear}π> ^^^                                ^stick closer ("}") hereππ> You'll probably recognize the above as the main routine of the polygonπ> fill snippet (the tester part).  Please note the part I under-caretedπ> (or -caretted).  There is no closing comment before the next openingπ> comment. Should the closer be placed where indicated by me?  Orπ> was the opener a typo?π> Not a big deal, but I want this to work so I can be impressed!  :^)ππIt works like that, at least in TP/BP. The open comment in effect keeps theπcompiler from ever seeing the next open brace. So the second brace's closingπbrace actually closes the first one. A trick I learned since I started atπdeltaComm. No, I actually wanted that commented out, because clearing theπscreen between each one slows it down.ππActually, I noticed a strange behaviour in the fill, where if you have oneπvertex = (x,y) and the next vertex = (x+40,y+1) then you'll end up with a dotπon one line and the next line entirely filled. Not what was intended. I came upπwith a fix for it:ππIt basically just centers the stairstep zigzag by adding half a step before itπstarts.π*)ππfunction lSar(L:longint):longint;assembler;asmπ db $66; mov ax,L       {mov eax,L}π db $66; sar ax,1       {sar eax,1}π db $66,$0F,$A4,$C2,$10 {shld edx,eax,16}π end;πππprocedure draw(color:byte);πvar i,l,r,lv,rv,top,bottom,topVert:integer; var lstep,lpos,rstep,rpos:fixed;πvar ldest,rdest:tPoint; beginπ {find top and bottom vertices}π topVert:=numVerts-1;π top:=vertex[topVert].y; bottom:=top;π for i:=numVerts-2 downto 0 doπ   if (vertex[i].Y < top) then beginπ    top:=vertex[i].Y;π    topVert:=i;π    endπ   else if (vertex[i].Y > bottom) thenπ    bottom:=vertex[i].Y;π if bottom>maxY then bottom:=maxY;       {clip bottom}π if top>bottom then exit;π lv:=topVert; rv:=topVert;π ldest:=vertex[topVert]; rdest:=ldest;π i:=top;π repeatπ  if i<bottom then beginππ{π^^^^^^^^^^^^^^^^^^^^^^^^^ keep from getting wierd effects from theπ                          adjustment on the last row.π}π   if i>=ldest.y then beginπ    lpos.f:=0; lpos.i:=ldest.x;π    dec(lv); if lv<0 then lv:=numVerts-1;π    ldest:=vertex[lv];π    if ldest.y=i then beginπ      if ldest.x<lpos.i then lpos.i:=ldest.x;π      lstep.l:=0;π      endπ    else beginπ      lstep.l:=fixedDiv(ldest.x-lpos.i,ldest.y-i);π      inc(lpos.l,lSar(lstep.l));ππ      ^^^^^^^^^^^^^^^^^^^^^^^^^^  Center the stairstep patternππ      end;π    end;π   if i>=rdest.y then beginπ    rpos.f:=0; rpos.i:=rdest.x;π    inc(rv); if rv>=numVerts then rv:=0;π    rdest:=vertex[rv];π    if rdest.y=i then beginπ      if rdest.x>rpos.i then rpos.i:=rdest.x;π      rstep.l:=0;π      endπ    else beginπ      rstep.l:=fixedDiv(rdest.x-rpos.i,rdest.y-i);π      inc(rpos.l,lSar(rStep.l));ππ      ^^^^^^^^^^^^^^^^^^^^^^^^^^  Center the stairstep patternππ      end;π    end;π   end;π  if i>=minY then begin                             {clip top}π   if lpos.i>minX then l:=lpos.i else l:=minX;      {clip left}π   if rpos.i<maxX then r:=rpos.i else r:=maxX;      {clip right}π   if (l<=r) thenπ    fillWord(mem[$A000:i*320+l],r-l+1,color);π   end;π  inc(lpos.l,lstep.l);π  inc(rpos.l,rstep.l);π  inc(i);π  until i>bottom;π end;π                                                                                       61     01-27-9412:20ALL                      KAI ROHRBACHER           COD Images               IMPORT              16     ╓╛j {π> This doesn't have anything to do with the flicker problem, but I wasπ> wondering if you could tell me how to scale and rotate .COD images.ππAlthough  I  posted  some code to flip COD's horizontally & verticallyπsome  time  ago,  I  won't make it a regular feature of AniVGA, as I'mπworking on compiled bitmaps and thus, altering the "data" after havingπit compiled into a procedure is close to impossible...πHowever,  if  you are speaking about scaling & rotation in MAKES: yes,πone  could  include  it.  To be honest, I was just to lazy to code allπthat matrix crap necessary.πFor  the  interested  reader: to scale the points (x,y) of a matrix byπsome factor f, you just have to apply the matrixπ(f 0)π(0 f)πto all its points.πA  rotation  by  an  angle  of  z  degrees  counterclockwise about theπrotation  center (u,v) is more complex: one first has to transform theπpoint coordinates to homogeneous coordinates (that is: append a one asπthe  3rd  component: (x,y) -> (x,y,1); if during computations this 3rdπcomponent  "c"  of  a vector (a,b,c) becomes <>1, then renormalize theπvector to (a/c,b/c,1)).πHaving done so, the rotation consists of three steps:πa) make (u,v) the new origin of your pixels (instead of (0,0))πb) rotate the data by z degrees about the new origin (0,0)πc) retransform the true (0,0) originππStep  a)  consists  of  applying the following matrix M1 to the pixelsπ(x,y,1):π( 1  0 0)π( 0  1 0)π(-u -v 1)ππLikewise, step b) is done by the matrix M2:π( cos(z) sin(z) 0 )π(-sin(z) cos(z) 0 )π(   0      0    1 )ππAnd step c) is done by M3:π( 1  0 0)π( 0  1 0)π(+u +v 1)ππThese  three  steps  can  be  squeezed  into one matrix application byπcombining  the  three  matrices into one matrix M=M1*M2*M3 (with "*" =πmatrix multiplication operator from linear algebra).ππ                                                                                                                            62     01-27-9412:21ALL                      BAS VAN GAALEN           Shade Bobs               IMPORT              26     ╓äà {π>> 1. Scrolling 256c fonts Fast and Smooth.π>> 2. Now to do it on top of graphics...π>> 3. 3D object engine - If someone can post me one or direct meπ>> to build one.π>> 4. Shade Bobs/Whatever it called - Taking a shape and moving itπ>> across the screen when it leaves trail.  Then, moving againπ>> on the trail will couse a stronger color to appear. n' on...π>> 5. Moving floor that is NOT a couse of a palette rotetion.π>> 6. 2D Scale procedure.π>> 7. Centered Stars. And SMOOTH ones.π>> 8. Vector BallsππI don't want to give it all away, but I just made some Shaded-bobs (orπwhatever). It realy isn't difficult. It worked right away. Now YOU make a nicerπsin-curve and palette. Here's some source:π}ππ{$G+}ππprogram ShadingBobs;πconstπ  Gseg : word = $a000;π  Sofs = 75; Samp = 75; Slen = 255;π  SprPic : array[0..15,0..15] of byte = (π    (0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0),π    (0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0),π    (0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0),π    (0,0,1,1,1,1,1,2,2,1,1,1,1,1,0,0),π    (0,1,1,1,1,1,2,2,2,2,1,1,1,1,1,0),π    (0,1,1,1,1,2,2,3,3,2,2,1,1,1,1,0),π    (1,1,1,1,2,2,3,3,3,3,2,2,1,1,1,1),π    (1,1,1,1,2,2,3,4,4,3,2,2,1,1,1,1),π    (1,1,1,1,2,2,3,3,3,3,2,2,1,1,1,1),π    (0,1,1,1,1,2,2,3,3,2,2,1,1,1,1,0),π    (0,1,1,1,1,1,2,2,2,2,1,1,1,1,1,0),π    (0,0,1,1,1,1,1,2,2,1,1,1,1,1,0,0),π    (0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0),π    (0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0),π    (0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0),π    (0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0));πtype SinArray = array[0..Slen] of word;πvar Stab : SinArray;ππprocedure CalcSinus; var I : word; beginπ  for I := 0 to Slen do Stab[I] := round(sin(I*4*pi/Slen)*Samp)+Sofs; end;ππprocedure SetGraphics(Mode : word); assembler; asmπ  mov ax,Mode; int 10h end;ππfunction keypressed : boolean; assembler; asmπ  mov ah,0bh; int 21h; and al,0feh; end;ππprocedure DrawSprite(X,Y : integer; W,H : byte; Sprite : pointer); assembler;πasmπ  push dsπ  lds si,[Sprite]π  mov es,Gsegπ  cldπ  mov ax,[Y]π  shl ax,6π  mov di,axπ  shl ax,2π  add di,axπ  add di,[X]π  mov bh,[H]π  mov cx,320π  sub cl,[W]π  sbb ch,0π @L:π  mov bl,[W]π @L2:π  lodsbπ  or al,alπ  jz @Sπ  mov dl,[es:di]π  add dl,alπ  mov [es:di],dlπ @S:π  inc diπ  dec blπ  jnz @L2π  add di,cxπ  dec bhπ  jnz @Lπ  pop dsπend;ππprocedure Retrace; assembler; asmπ  mov dx,3dah;π  @l1: in al,dx; test al,8; jnz @l1;π  @l2: in al,dx; test al,8; jz @l2; end;ππprocedure Setpalette;πvar I : byte;πbeginπ  for I := 0 to 255 do beginπ    port[$3c8] := I;π    port[$3c9] := I div 3;π    port[$3c9] := I div 2;π    port[$3c9] := I;π  end;πend;ππprocedure Bobs;πvar X,Y : integer; I,J : byte;πbeginπ  I := 0; J := 25;π  repeatπ    X := 2*Stab[I]; Y := Stab[J];π    inc(I); inc(J);π    Retrace;π    DrawSprite(X,Y,16,16,addr(SprPic));π  until keypressed;πend;ππbeginπ  CalcSinus;π  SetGraphics($13);π{  SetPalette;}π  Bobs;π  SetGraphics(3);πend.ππ{ DrawSprite procedure taken from Sean Palmer (again).π  It contained some minor bugs: [X] was added to AX, should be DI, andπ  jz @S was jnz @S, so the sprite wasn't drawn. Now it is...π  And of course it was changed to INCREASE the video-mem, not to poke it.ππ  If you get rid of the Retrace it goes a LOT faster. }ππ                               63     01-27-9412:22ALL                      SEAN PALMER              Sprite Talk              IMPORT              22     ╓0▀ {π>Try converting it to use pointers instead of accessing the array withπ>indexes, and use a pointer to video memory for direct plotsπ>instead of using the putPixel routine. Also it's quicker toπ>check against 0 for the background than to check againstπ>255.ππ> I found a copy of "The Visible Computer: 8088" in my bookshelves andπ> tried rewriting my assembly routines.  Here's what I finally got:ππ> procedure MaskPut(x,y: word; p: pointer); assembler;π> varπ> XX,YY: byte;π> asmπ> LES SI,pπ> MOV [XX],0π> MOV [YY],0π> MOV CX,256π> XOR DX,DXπ> CLDπ> @Loopit:SEGES LODSBπ> MOV DL,ALπ> PUSH ESπ> PUSH SIπ> CMP DL,255π> JZ @Doneπ> MOV AX,0A000hπ> MOV ES,AXπ> MOV AX,320π> MOV BX,[Y]π> ADD BL,[YY]π> PUSH DXπ> MUL BXπ> POP DXπ> MOV BX,[X]π> ADD BL,[XX]π> ADD AX,BXπ> MOV SI,AXπ> MOV ES:[SI],DLπ> @Done:  INC [XX]π> CMP [XX],16π> JNZ @Okayπ> MOV [XX],0π> INC [YY]π> @Okay:  POP SIπ> POP ESπ> LOOP @Loopitπ> end;ππ> It works fine.  I didn't notice much of a difference in speed though.π> I tested it and I can plot about 1103 sprites/second in ASM and 828π> sprites/sec. with my original TP code.  Please keep in mind I'm notπ> much of an assembly programmer. Can anyone help me optimize this codeπ> (into 286 would be good too). Thanx for your help!ππI'll try. I notice you're using memory variables for loop counters in thatπcode. Also seem to be reloading the segment registers each time through theπloop, and general sundry pushes, pops, and such which are unnecesary. I don'tπhave time to rewrite your code from scratch today but I'll post my transparentπbitmap routine for Mode 13 for you to use/learn from. K?ππthis is untested, I was fixing it up after I found it my optimization getsπbetter over time, and it's been a while since I've worked on this Mode 13hπstuff.π}ππ{$G+}ππprocedure drawSprite(x, y : integer; w, h : byte; sprite : pointer); assembler;πasmπ push dsπ lds si,[sprite]π mov ax,$A000π mov es,axπ cldπ mov ax,[y]     {y * 320}π shl ax,6π mov di,axπ shl ax,2π add di,axπ add ax,[x]     {+ x}π mov bh,[h]π mov cx,320     {dif between rows}π sub cl,[w]π sbb ch,0π@L:π mov bl,[w]π@L2:π lodsbπ or al,al       {test for 0. For 255 you'd use inc al here instead}π                {heck dx and ah are free, you could store theπ                  comparison value in one of those}π jnz @Sπ                {for 255 you'd also need a dec al here}π mov [es:di],alπ@S:π inc diπ dec blπ jnz @L2π add di,cxπ dec bhπ jnz @Lπ pop dsπ end;ππ{πAnd I'll bet you notice a difference in speed with this puppy. 8)ππIf you could guarantee that the width would be an even number you couldπoptimize it to use word moves, otherwise it wouldn't be worth it.π}π                                      64     01-27-9412:22ALL                      HARALDS JAKOVELS         Sprite Info              IMPORT              24     ╓(" {π> Another problem is plotting sprites with "invisible" pixels.  In otherπ> words, all pixels in the sprite are plotted except for ones with a colorπ> of 255 (I think I've heard that Origin used this method in Ultima 6).π> Because of my unsuccessful try with asm earlier, I didn't even bother toπ> try this in asm.  Unfortunately, the following is MUCH too slow:ππtry this!π}πuses crt;πtype SpriteType = array[0..15,0..15] of byte;ππvar sprite : spritetype;π    f : file of spritetype;     {sprite's image is stored in file}π    x, y : word;ππprocedure putinvspriteinasm(x, y : word; sprite : spritetype);πvar p : pointer;π    segm, offs : word;π    {these are used to calculate destination addressπ     in video memory}ππbeginπ  p := addr(sprite[0,0]);π  {this pointer is used only to cheat tp. tp doesn't allow to use addr orπ   @ operators in inline asm - or i don't know how to do it}π  segm := $a000 + (320 * y) div 16;π  offs := x;π  {segm:offs is address of upper left corner of sprite in video RAM}π      asmπ          push   dsπ  {ds is one of the important registers in tp and must be saved}π          lds    si, pπ  {ds:si now is source address for sprite's array}π          mov    es, segmπ          mov    di, offsπ  {es:di now is target address in VRAM}π          mov    bh, 16π  {counter for outer loop}π@loop2:   mov    bl, 16π@loop1:   mov    al, [ds:si]π  {innner loop (marked with label @loop1) is used to draw each line ofπ   sprite}π          cmp    al, $ffπ   {make sure if pixel is $ff or not}π          je     @skipπ   {it is - so we don't draw it}π          mov    [es:di], alπ   {no, it's not - draw!}π@skip:    inc    siπ          inc    diπ          dec    blπ          jnz    @loop1π   {we haven't finished to draw this line if bl > 0}π          dec    bhπ   {we haven't finished to draw all image if bh > 0}π          jz     @endπ          add    di, 320 - 16π   {calculate beginning of next line}π          jmp    @loop2π@end:π          pop    dsππ      endπend;ππbeginπ  asm mov ax, 0013hπ      int 10hπ  end;π  assign(f, 'sprite');π  reset(f);π  read(f, sprite);π  close(f);π  randomize;π  repeatπ    x := random(320);π    y := random(200);π    putinvspriteinasm(x, y, sprite);π  until keypressed;πend.π{πi added into code some quick'n'dirty comments to let you understandπhow assembly works. i've tested this code and found that it won't work withπMicrosoft's workgrp.sys driver - the programm simply crashes when you press aπkey. (workgrp.sys driver is one of the Windows for Workgroups drivers).πstrange... with all other things (qemm386, lan drivers etc.) programm seems toπwork fine. one more thing i must add that better is to pass to procedureπputsprite not array with sprite's data but only pointer to it - because tpπmoves all this data around memory - and in this case it's 256 bytes.π}π                                                                                                                 65     01-27-9412:23ALL                      VARIOUS - SEE BELOW      Textures                 IMPORT              51     ╓Zg π{πANDREW FORTπ> That's fast, but that's just one bitmap. I really need to sit down andπ> optimize my texture mapper...ππ> You have to use 386 instructions cuz 32-bit division is way too slowπ> otherwise. I'd have to see the code to tell if it's efficient or not. It'sπ> a simple algorithm, just figuring out where in the bitmap to start andπ> what the step value is for each scan line is the hard part. Then just doπ> 320 pixels real quick... don't worry, cuz with 256x256 bitmaps, everythingπ> just works itself out real nice.ππyes i realize it works out real nice with 256x256 bitmaps, because you canπshift/carry or whatever to get the particular point in the bitmap you wantπeasily.ππyes it uses 32 bit instructions, but since it's so short, it's not a problemπcoding it in BASM.. and here it is:ππ** this code was written by The Faker of Aardvark **π}ππPROCEDURE PutTexture(IncX, IncY : Integer; P : Pointer);πVARπ  Y, PosX,π  PosY,π  PX, PY : Integer;πBEGINπ  PosX := -(ScreenX SHR 1) * IncX;   { ScreenX,-Y are size of screen    }π  PosY := -(ScreenY SHR 1) * IncY;   { PosX,y set so rotation is around }π  FOR Y := 0 TO ScreenY-1 DO       { the middle (of 'p')              }π  BEGINπ    PX := PosX;   { PosX,-Y is updated every line, PX,-y derived   }π    PY := PosY;π    ASMπ      push dsπ      mov  ax, 0a000hπ      mov  es, axπ      mov  ax, yπ      xchg al, ahπ      mov  di, axπ      shr  di, 2π      add  di, axπ      lds  si, p   { in P there should be a 256x256 bitmap }π      mov  cx, screenx shr 1π      cldπ      mov  ax, incxπ      shl  eax, 16π      mov  ax, incyπ      mov  esi, eaxπ      mov  dx, pxπ      shl  edx, 16π      mov  dx, pyπ     @1:π      add  edx, esiπ      mov  ebx, edxπ      shr  ebx, 16π      mov  bl, dhπ      mov  al, [bx]π      add  edx, esiπ      mov  ebx, edxπ      shr  ebx, 16π      mov  bl, dhπ      mov  ah, [bx]π      stoswπ      dec  cxπ      jnz  @1π      pop  dsπ    END;π    Inc(PosX, IncY);π    Inc(PosY, -IncX);π  END;πEND;ππ{πas you can see, very methodical coding, but it's quite fast, and does theπjob....ππ>> It was coded before 2nd reality was released, but didn't get releasedπ>> till after because of distribution problems..ππ> Second Reality was ok, but they coulda done better. I did like theπ> bubbling landscape demo (voxel stuff)ππtry, although i was disappointed that they didn't really do much new (thoseπblue bolls were nice though, although they flickered quite alot.. but hey! i'mπhardly paying for the demo, am i!)ππbut yeah, the voxel stuff was nice.. after reciving email from Lord Logics (ofπAvalanche), he says that he's been working on some voxel stuff, although heπdidn't get it finished because of getting a job, although he intends to finishπit and release it in a demo for avalanche.. so that'd be nice to see..ππtell me if the code is efficent or not! :-)π}ππ(*πSEAN PALMERππ> yes i realize it works out real nice with 256x256 bitmaps, because youπ> can shift/carry or whatever to get the particular point in theπ> bitmap you want easily.ππNo, you don't have to do diddly squat to extract it. Just move the byte out.πSince one's in the hi byte of a 32-bit register though, it's harder to extract.ππ> yes it uses 32 bit instructions, but since it's so short, it's not aπ> problem coding it in BASM.. and here it is:ππOf course you know that BP 7.0 won't do 386 instructions. So this wouldn'tπcompile as is. Needs a lot of DB $66's, etc.ππ> ** this code was written by The Faker of Aardvark **ππHi Faker! Sorry to botch your code below. 8)ππ> PROCEDURE PutTexture(IncX,IncY:Integer; P:Pointer);π> VARπ> Y,PosX,PosY,PX,PY:Integer;π> BEGINπ> PosX:=-(ScreenX SHR 1)*IncX;   { ScreenX,-Y are size of screen}π> PosY:=-(ScreenY SHR 1)*IncY;   { PosX,y set so rotation is around}π> FOR Y:=0 TO ScreenY-1 DO       { the middle (of 'p')}π> BEGINπ> PX:=PosX;   { PosX,-Y is updated every line, PX,-y derived}π> PY:=PosY;π> ASMπ> push dsπ> mov ax,0a000hπ> mov es,axπ> mov ax,yπ     shl ax,8    {this is same speed, but cleaner}π> mov di,ax      {lessee... ends up y*320. Faster than MUL. But should}π> shr di,2       {be incrementally calculated instead.}π> add di,axπ> lds si,p       { in P there should be a 256x256 bitmap }π> mov cx,screenx shr 1π> cldπ                        {cleaned out the intermediate use of eax}π     mov si,incxπ     shl esi,16π     mov si,incyπ> mov dx,pxπ> shl edx,16π> mov dx,pyπ> @1: add edx,esiπ     shld ebx,edx,16    {do move and shift all at once. Save 2 cycles}π> mov bl,dhπ> mov al,[bx]π> add edx,esiπ     shld ebx,edx,16    {ditto. I like this unrolled loop! 8) }π> mov bl,dhπ> mov ah,[bx]π> stosw              {word access. Sweet.}π> dec cx             {better than LOOP on a 386+}π> jnz @1π> pop dsπ> END;π> Inc(PosX,IncY);π     Dec(PosY,IncX);    {avoid neg operation}π> END;π> END;ππ> as you can see, very methodical coding, but it's quite fast, and doesπ> the job....ππYep. I haven't coded it up where it'll compile and run it yet, but Should BeπPretty Darn Quick. Seems like it's gonna have a problem with the carry from dxπto the hi word of edx (your position will be off, barely, every time itπwraps.... shouldn't matter much)ππ> but yeah, the voxel stuff was nice.. after reciving email from Lordπ> Logics (of Avalanche), he says that he's been working on someπ> voxel stuff, although he didn't get it finished because ofπ> getting a job, although he intends to finish it and release itπ> in a demo for avalanche.. so that'd be nice to see..ππI'm gonna have to code something like that up for a BattleTech type game. Bestπidea I've seen so far for terrain... If you see any code to get me started,πplease route it my way.ππ> tell me if the code is efficent or not! :-)ππOnly one optimization I can spot right now (aside from coding the outer loop inπASM as well...) Is that he has to shift the 32-bit registers around to get atπthe upper word. (the 386 needs more data registers!!!!!! ARE YOU LISTENINGπINTEL!!!) So using the SHLD instruction like I re-coded above should speed itπup some. Avoid the intermediate register move.ππI've commented above. You could put alot of the setup stuff outside the loop ifπyou wrote it all in BASM. Wouldn't have to push/pop for each scan line, etc.πBut that's a minor speedup.ππIn the future, try to gain access to the FIDO 80XXX echo. It's a much betterπplace to talk about (mostly) assembly stuff.ππ*)                                       66     01-27-9412:25ALL                      WILLIAM PLANKE           PCX Writing              IMPORT              99     ╓≈ó {πAs I follow this forum, many requests are made for PCX graphicsπfile routines. Those that are looking for Read_PCX info canπfind it on the ZSoft BBS in a wonderful Pascal example: ShowPCX.ππOn the other hand, there is next to zilch out there on how toπWrite_PCX files. I know.... I searched and searched and couldn'tπfind a thing! So with a little brute force  and a few ZSoftπC language snippets <groan>, I got this together:ππPCX_W.Write_PCX (Name:Str80);πgiven to the public domain and commonweal.πpseudocode:π           set 640x480x16 VGAhi graphics mode only for nowπ           getimage 1 row at a timeπ           reorganize the BGI color planes into PCX format orderπ           encode the raw PCX line into a run length limitedπ             compressed PCX lineπ           blockwrite the compressed PCX line to your.PCX fileπ}ππ{$R-}    {Range checking, turn off when debugged}ππunit PCX_W;ππ{ --------------------- Interface ----------------- }ππinterfaceππtypeπ    Str80 = string [80];ππprocedure Write_PCX  (Name:Str80);πππ{ ===================== Implementation ============ }ππimplementationππusesπ    Graph;πππ{-------------- Write_PCX --------------}ππprocedure Write_PCX (Name:Str80);ππconstπ     RED1   = 0;π     GREEN1 = 1;π     BLUE1  = 2;ππtypeπ    ArrayPal   = array [0..15, RED1..BLUE1] of byte;ππconstπ     MAX_WIDTH  = 4000;    { arbitrary - maximum width (in bytes) ofπ                             a PCX image }π     INTENSTART =   $5;π     BLUESTART  =  $55;π     GREENSTART =  $A5;π     REDSTART   =  $F5;ππtypeπ    Pcx_Header = recordπ    {comments from ZSoft ShowPCX pascal example}ππ        Manufacturer: byte;     { Always 10 for PCX file }ππ        Version: byte;          { 2 - old PCX - no palette (not usedπ                                      anymore),π                                  3 - no palette,π                                  4 - Microsoft Windows - no paletteπ                                      (only in old files, new Windowsπ                                      version uses 3),π                                  5 - with palette }ππ        Encoding: byte;         { 1 is PCX, it is possible that we mayπ                                  add additional encoding methods in theπ                                  future }ππ        Bits_per_pixel: byte;   { Number of bits to represent a pixelπ                                  (per plane) - 1, 2, 4, or 8 }ππ        Xmin: integer;          { Image window dimensions (inclusive) }π        Ymin: integer;          { Xmin, Ymin are usually zero (not always)}π        Xmax: integer;π        Ymax: integer;ππ        Hdpi: integer;          { Resolution of image (dots per inch) }π        Vdpi: integer;          { Set to scanner resolution - 300 isπ                                  default }ππ        ColorMap: ArrayPal;π                                { RGB palette data (16 colors or less)π                                  256 color palette is appended to endπ                                  of file }ππ        Reserved: byte;         { (used to contain video mode)π                                  now it is ignored - just set to zero }ππ        Nplanes: byte;          { Number of planes }ππ        Bytes_per_line_per_plane: integer;   { Number of bytes toπ                                               allocate for a scanlineπ                                               plane. MUST be an an EVENπ                                               number! Do NOT calculateπ                                               from Xmax-Xmin! }ππ        PaletteInfo: integer;   { 1 = black & white or color image,π                                  2 = grayscale image - ignored in PB4,π                                      PB4+ palette must also be set toπ                                      shades of gray! }ππ        HscreenSize: integer;   { added for PC Paintbrush IV Plusπ                                  ver 1.0,  }π        VscreenSize: integer;   { PC Paintbrush IV ver 1.02 (and later)}π                                { I know it is tempting to use theseπ                                  fields to determine what video modeπ                                  should be used to display the imageπ                                  - but it is NOT recommended since theπ                                  fields will probably just containπ                                  garbage. It is better to have theπ                                  user install for the graphics mode heπ                                  wants to use... }ππ        Filler: array [74..127] of byte;     { Just set to zeros }π    end;ππ    Array80    = array [1..80]        of byte;π    ArrayLnImg = array [1..326]       of byte; { 6 extra bytes atπ     beginng of line that BGI uses for size info}π    Line_Array = array [0..MAX_WIDTH] of byte;π    ArrayLnPCX = array [1..4]         of Array80;ππvarπ   PCXName   : File;π   Header    : Pcx_Header;                 { PCX file header }π   ImgLn     : ArrayLnImg;π   PCXLn     : ArrayLnPCX;π   RedLn,π   BlueLn,π   GreenLn,π   IntenLn   : Array80;π   Img       : pointer;πππ{-------------- BuildHeader- -----------}ππprocedure BuildHeader;ππconstπ     PALETTEMAP: ArrayPal=π                 {  R    G    B                    }π                (($00, $00, $00),  {  black        }π                 ($00, $00, $AA),  {  blue         }π                 ($00, $AA, $00),  {  green        }π                 ($00, $AA, $AA),  {  cyan         }π                 ($AA, $00, $00),  {  red          }π                 ($AA, $00, $AA),  {  magenta      }π                 ($AA, $55, $00),  {  brown        }π                 ($AA, $AA, $AA),  {  lightgray    }π                 ($55, $55, $55),  {  darkgray     }π                 ($55, $55, $FF),  {  lightblue    }π                 ($55, $FF, $55),  {  lightgreen   }π                 ($55, $FF, $FF),  {  lightcyan    }π                 ($FF, $55, $55),  {  lightred     }π                 ($FF, $55, $FF),  {  lightmagenta }π                 ($FF, $FF, $55),  {  yellow       }π                 ($FF, $FF, $FF) );{  white        }ππvarπ   i : word;ππbeginπ     with Header doπ          beginπ               Manufacturer  := 10;π               Version  := 5;π               Encoding := 1;π               Bits_per_pixel := 1;π               Xmin := 0;π               Ymin := 0;π               Xmax := 639;π               Ymax := 479;π               Hdpi := 640;π               Vdpi := 480;π               ColorMap := PALETTEMAP;π               Reserved := 0;π               Nplanes  := 4; { Red, Green, Blue, Intensity }π               Bytes_per_line_per_plane := 80;π               PaletteInfo := 1;π               HscreenSize := 0;π               VscreenSize := 0;π               for i := 74 to 127 doπ                   Filler [i] := 0;π          end;πend;πππ{-------------- GetBGIPlane ------------}ππprocedure GetBGIPlane (Start:word; var Plane:Array80);ππvarπ   i : word;ππbeginπ     for i:= 1 to Header.Bytes_per_line_per_plane doπ         Plane [i] := ImgLn [Start +i -1]πend;ππ{-------------- BuildPCXPlane ----------}ππprocedure BuildPCXPlane (Start:word; Plane:Array80);ππvarπ   i : word;ππbeginπ     for i := 1 to Header.Bytes_per_line_per_plane doπ         PCXLn [Start] [i] := Plane [i];πend;πππ{-------------- EncPCXLine -------------}ππprocedure EncPCXLine (PlaneLine : word); { Encode a PCX line }ππvarπ   This,π   Last,π   RunCount : byte;π   i,π   j        : word;πππ  {-------------- EncPut -----------------}ππ  procedure EncPut (Byt, Cnt :byte);ππ  constπ       COMPRESS_NUM = $C0;  { this is the upper two bits thatπ                              indicate a count }ππ  varπ     Holder : byte;ππ  beginπ  {$I-}π       if (Cnt = 1) and (COMPRESS_NUM <> (COMPRESS_NUM and Byt)) thenπ          blockwrite (PCXName, Byt,1)          { single occurance }π          {good place for file error handler!}π       elseπ           beginπ                Holder := (COMPRESS_NUM or Cnt);π                blockwrite (PCXName, Holder, 1); { number of times theπ                                                   following colorπ                                                   occurs }π                blockwrite (PCXName, Byt, 1);π           end;π  {$I+}π  end;πππbeginπ     i := 1;         { used in PCXLn }π     RunCount := 1;π     Last := PCXLn [PlaneLine][i];π     for j := 1 to Header.Bytes_per_line_per_plane -1 doπ         beginπ              inc (i);π              This := PCXLn [PlaneLine][i];π              if This = Last thenπ                 beginπ                      inc (RunCount);π                      if RunCount = 63 then   { reached PCX run lengthπ                                                limited max yet? }π                         beginπ                              EncPut (Last, RunCount);π                              RunCount := 0;π                         end;π                 endπ              elseπ                  beginπ                       if RunCount >= 1 thenπ                          Encput (Last, RunCount);π                       Last := This;π                       RunCount := 1;π                  end;π         end;π     if RunCount >= 1 then  { any left over ? }π        Encput (Last, RunCount);πend;ππ            { - - -W-R-I-T-E-_-P-C-X- - - - - - - - }ππconstπ     XMAX = 639;π     YMAX = 479;ππvarπ   i, j, Size : word;ππbeginπ     BuildHeader;π     assign     (PCXName,Name);π{$I-}π     rewrite    (PCXName,1);π     blockwrite (PCXName,Header,sizeof (Header));π     {good place for file error handler!}π{$I+}π     setviewport (0,0,XMAX,YMAX, ClipOn);π     Size := imagesize (0,0,XMAX,0); { size of a single row }π     getmem (Img,Size);ππ     for i := 0 to YMAX doπ         beginπ              getimage (0,i,XMAX,i,Img^);  { Grab 1 line from theπ                                             screen store in Imgπ                                             buffer  }π              move (Img^,ImgLn,Size {326});ππ              GetBGIPlane (INTENSTART, IntenLn);π              GetBGIPlane (BLUESTART,  BlueLn );π              GetBGIPlane (GREENSTART, GreenLn);π              GetBGIPlane (REDSTART,   RedLn  );π              BuildPCXPlane (1, RedLn  );π              BuildPCXPlane (2, GreenLn);π              BuildPCXPlane (3, BlueLn );π              BuildPCXPlane (4, IntenLn); { 320 bytes/lineπ                                            uncompressed }π              for j := 1 to Header.NPlanes doππ                  EncPCXLine (j);π         end;π     freemem (Img,Size);           (* Release the memory        *)π{$I-}π     close (PCXName);              (* Save the Image            *)π{$I+}πend;ππend {PCX.TPU} .πππ{ -----------------------Test Program -------------------------- }ππprogram WritePCX;ππusesπ    Graph, PCX_W;ππ{-------------- DrawHorizBars ----------}ππprocedure DrawHorizBars;ππvarπ   i, Color : word;ππbeginπ     cleardevice;π     Color := 15;π     for i := 0 to 15 doπ         beginπ              setfillstyle (solidfill,Color);π              bar (0,i*30,639,i*30+30);       { 16*30 = 480 }π              dec (Color);π         end;πend;ππ{-------------- Main -------------------}ππvarπ   NameW : Str80;π   Gd,π   Gm    : integer;ππbeginπ     writeln;π     if (ParamCount = 0) then           { no DOS command lineπ                                          parameters }π        beginπ             write ('Enter name of PCX picture file to write: ');π             readln (NameW);π             writeln;π        endπ     elseπ         beginπ              NameW := paramstr (1);  { get filename from DOSπ                                        command line }π         end;ππ     if (Pos ('.', NameW) = 0) then   { make sure the filenameπ                                        has PCX extension }π        NameW := Concat (NameW, '.pcx');ππ     Gd:=VGA;π     Gm:=VGAhi; {640x480, 16 colors}π     initgraph (Gd,Gm,'..\bgi');  { path to your EGAVGA.BGI }ππ     DrawHorizBars;ππ     readln;π     Write_PCX (NameW); { PCX_W.TPU }π     closegraph;                    { Close graphics    }π     textmode (co80);               { back to text mode }πend.  { Write_PCX }ππ{πOK, everybody, I hope this gets you started. I had a lot ofπfun setting it up. There are some obvious places that needπoptimization... especially the disk intensive blockwrites. Ifπsomeone could please figure out holding about 4k or so in pointersπof the encoded PCX file before writing, I'd sure appreciate it!.π(please post for everyone, if you do.)ππ}                                                                           67     01-27-9413:32ALL                      GREG ESTABROOKS          Mode 13 Demo             IMPORT              12     ╓úN PROGRAM Mode13Demo;             { Oct 10/93, Greg Estabrooks.       }πVARπ   CurCol,π   OldMode:BYTE;π   CurPos,π   X,Y :WORD;π   ScrBuff :ARRAY[1..64000] OF BYTE;ππPROCEDURE SetVidMode( Mode :BYTE ); ASSEMBLER;π        {  Routine to set video mode                        }πASMπ  Mov AH,00                     {  Function to set mode             }π  Mov AL,Mode                   {  Mode to change to                }π  Int $10                       {  Call dos                         }πEND;{SetVidMode}ππPROCEDURE PutPixel( X,Y :WORD; Color :BYTE );πBEGINπ  Mem[$A000:(320*Y)+X]:= Color;πEND;ππBEGINπ  SetVidMode($13);              { Set Mode to 320x200x256.          }π  FOR Y := 0 To 199 DO          { Loop through all lines.           }π    FOR X := 0 To 319 DO        { Loop through all columns.         }π    PutPixel(X,Y,Random(255));π  CurCol := 0;π  CurPos := 0;π  FOR Y := 0 To 199 DO          { Loop through all lines.           }π   BEGINπ    Inc(CurCol);π    FOR X := 0 To 319 DO        { Loop through all columns.         }π     BEGINπ       Inc(CurPos);π       ScrBuff[CurPos] := CurCol;π     END;π   END;π  Writeln('Press Enter to see the Faster way!');π  Readln;π  Move(ScrBuff,Mem[$A000:0],SizeOf(ScrBuff));π  Readln;π  SetVidMode(3);                { Set Mode 3,80x25.                 }πEND.π                                                                                                         68     01-27-9413:32ALL                      GREG ESTABROOKS          Misc Graphic Functions   IMPORT              45     ╓ùf UNIT GrStuff;       {  Misc Graphic Functions, Last Updated  Nov 11/93 }π            {  Copyright (C), Greg Estabrooks, 1993            }ππINTERFACEπ(***********************************************************************)ππFUNCTION MonitorType :BYTE;               {  Determines Monitor In Use  }πPROCEDURE SetVidMode( Mode :BYTE );       {  Set video mode             }πPROCEDURE SetPage( Page :BYTE );          {  Set current screen page    }πPROCEDURE BiosPutPix( Col,Page :BYTE;X,Y :WORD ); { Plot pixel at X,Y   }πFUNCTION TSeng :BOOLEAN;        {  Determine if graph card a TSENG labs }πFUNCTION GetVideoMode :BYTE;π              {  Routine to determine current video mode        }πPROCEDURE Set80x30Mode;πPROCEDURE DrawBar( X1,Y1,X2,Y2 :WORD; Color :BYTE );πPROCEDURE SetColor( Color2Set, Red, Green, Blue :BYTE );πPROCEDURE GetColor( Color2Get :BYTE; VAR Red,Green,Blue :BYTE );ππIMPLEMENTATIONπ(***********************************************************************)πFUNCTION MonitorType :BYTE; ASSEMBLER;π               {  Determines Type of Monitor In Use.        }πASMπ  Mov AH,$1A                    {  Function Determine Display Code      }π  Mov AL,0                      {  AL,0 = Read Code  AL,1 = Set Code    }π  Int $10                       {  Call Dos                             }π  Mov AL,BL;                    {  Move result to proper register       }π    {  0 - no Display       4 - Ega Standard Color     7 - VGA MONO }π    {  1 - MDA              5 - Ega MonoChrome         8 - VGA      }π    {  2 - CGA              6 - PGA                                 }πEND;{MonitorType}ππPROCEDURE SetVidMode( Mode :BYTE ); ASSEMBLER;π        {  Routine to set video mode                            }πASMπ  Mov AH,00                     {  Function to set mode                 }π  Mov AL,Mode                   {  Mode to change to                    }π  Int $10                       {  Call dos                             }πEND;{SetVidMode}ππPROCEDURE SetPage( Page :BYTE ); ASSEMBLER;π        {  Routine to change screen pages                       }πASMπ  Mov AH,$05                    {  Function to change pages             }π  Mov AL,Page                   {  Page to change to                    }π  Int $10                       {  Call dos                             }πEND;{SetPage}ππPROCEDURE BiosPutPix( Col,Page :BYTE; X,Y :WORD ); ASSEMBLER;π        {  Routine to plot a pixel on the screen using INT 10h. }πASMπ  Mov AH,$0C                    {  Function to plot a pixel             }π  Mov AL,Col                    {  Color to make it                     }π  Mov BH,Page;                  {  Page to write it to                  }π  Mov CX,X                      {  Column to put it at                  }π  Mov DX,Y                      {  Row to place it                      }π  Int $10                       {  call dos                             }πEND;{BiosPutPix}ππFUNCTION TSeng :BOOLEAN;π        {  Routine to determine if Graphics card is a TSENG labs}πVARπ    Old,New :BYTE;πBEGINπ  Old := Port[$3CD];            {  Save original card register value    }π  Port[$3CD] := $55;            {  change it                            }π  New := Port[$3CD];            {  read in new value                    }π  Port[$3CD] := Old;            {  restore old value                    }π  TSENG := ( New = $55 );       {  if value same as what we sent (TRUE) }πEND;ππFUNCTION GetVideoMode :BYTE; ASSEMBLER;π              {  Routine to determine current video mode        }πASMπ  Mov AX,$0F00                  {  SubFunction Return Video Info        }π  Int $10                       {  Call Dos                             }πEND;{GetVideoMode}ππPROCEDURE Set80x30Mode;πVAR CrtcReg:ARRAY[1..8] OF WORD;π    Offset :WORD;π    I,Data :BYTE;πBEGINπ  CrtcReg[1]:=$0C11;           {Vertical Display End (unprotect regs. 0-7)}π  CrtcReg[2]:=$0D06;           {Vertical Total}π  CrtcReg[3]:=$3E07;           {Overflow}π  CrtcReg[4]:=$EA10;           {Vertical Retrace Start}π  CrtcReg[5]:=$8C11;           {Vertical Retrace End (& protect regs. 0-7)}π  CrtcReg[6]:=$DF12;           {Vertical Display Enable End}π  CrtcReg[7]:=$E715;           {Start Vertical Blanking}π  CrtcReg[8]:=$0616;           {End Vertical Blanking}ππ  MemW[$0040:$004C]:=8192;     {Change page size in bytes}π  Mem[$0040:$0084]:=29;        {Change page length}π  Offset:=MemW[$0040:$0063];   {Base of CRTRC}π  ASMπ    Cli                        {Clear Interrupts}π  END;ππ  FOR I:=1 TO 8 DOπ    PortW[Offset]:=CrtcReg[i]; {Load Registers}ππ  Data:=PORT[$03CC];π  Data:=Data AND $33;π  Data:=Data OR $C4;π  PORT[$03c2]:=Data;π  ASMπ   Sti                         {Set Interrupts}π   Mov AH,12h                  {Select alternate printing routine}π   Mov BL,20hπ   Int 10hπ  END;πEND; {Of Procedure}ππPROCEDURE DrawBar( X1,Y1,X2,Y2 :WORD; Color :BYTE );π                   { Bar drawing routine. Specifically set up for mode  }π                   { 13h. Much faster than the BGI one.                 }πVARπ   Row     :WORD;πBEGINπ  FOR Row := Y1 TO Y2 DOπ    FillChar(MEM[$A000:(320*Row)+X1],X2-X1,Color);πEND;πππPROCEDURE SetColor( Color2Set, Red, Green, Blue :BYTE );π                    { Routine to Change the palette value of Color2Set. }πBEGINπ    PORT[$3C8] := Color2Set;π    PORT[$3C9] := Red;π    PORT[$3C9] := Green;π    PORT[$3C9] := Blue;πEND;ππPROCEDURE GetColor( Color2Get :BYTE; VAR Red,Green,Blue :BYTE );π                    { Routine to determine the Palette value of Color2Get}πBEGINπ    PORT[$3C8] := Color2Get;π    Red := PORT[$3C9];π    Green := PORT[$3C9];π    Blue := PORT[$3C9];πEND;ππBEGINπEND.π                                                                       69     01-27-9417:32ALL                      PETER KOLDING            3D Graphics Box          IMPORT              52     ╓â¿ {πFrom: PETER KOLDINGπSubj: 3D GraphicsππMB>  Hello, I'm trying to write a simple program that will plot points in threeπMB>  dimensions and allow you to rotate them,or view them from differentπangles.πMB>  need a lot of help. I'm trying to make a data file of points in the formatπMB>  (x,y,z) and then have the program read the points in to display. So far noπMB>  luck. If anyone has any code that is simple enough for me to understand IπMB>  would appreciate it. Also if anyone has any code for doing fast vgaπMB>  animations(in assembly) could they please post it? Thanks in advance.π}ππprogram boxrot;ππ{PUBLIC DOMAIN  1993 Peter M. Gruhn}ππ{Program draws a box on screen. Allows user to rotate the box aroundπ the three primary axes. Viewing transform is simple ignore z.}ππ{I used _Computer_Graphics:_Principles_and_Practice_, Foley et alπ ISBN 0-201-12110-7 as a reference}ππ{RUNNING:π Borland Pascal 7. Should run on any graphics device supported by BGI.π If you have smaller than 280 resolution, change '+200' to somethingπ smaller and/or change 75 to something smaller.ππ Since this machine isπ not really set up for doing DOS graphics, I hard coded my BGI path, soπ you have to find 'initgraph' and change the bgi path to something thatπ works on your machine. Try ''.πππ{Okey dokey. This is kinda slow, and does a nice job of demonstrating theπ problems of repeatedly modifying the same data set. That is, the more andπ more you rotate the box, the more and more distorted it gets. This isπ because computers are not perfect at calculations, and all of those littleπ errors add up quite quickly.ππ It's because of that that I used reals, not reals. I used floating pointπ because the guy doesn't know what is going on at all with 3d, so better toπ look at only the math that is really happening. Besides, I still have toπ think to use fixed point. Whaddaya want for .5 hour programming.ππ DIRECTIONS:π   ',' - rotates around the x axisπ   '.' - rotates around the y axisπ   '/' - rotates around the z axisπ   'q' - quitsππ   All rotations are done around global axes, not object axes.}ππuses graph,crt;ππconst radtheta=1{degrees}*3.1415926535{radians}/180{per degrees};π      {sin and cos on computers are done in radians.}ππtype tpointr=record   {Just a record to hold 3d points}π       x,y,z:real;π       end;ππvar box:array[0..7] of tpointr;   {The box we will manipulate}π    c:char;                    {Our input mechanism}ππprocedure init;πvar gd,gm:integer;π{turns on graphics and creates a cube. Since the rotation routinesπ rotate around the origin, I have centered the cube on the origin, soπ that it stays in place and only spins.} beginπ  gd:=detect; initgraph(gd,gm,'d:\turbo\tp\');π  box[0].x:=-75;  box[0].y:=-75;  box[0].z:=-75;π  box[1].x:=75;   box[1].y:=-75;  box[1].z:=-75;π  box[2].x:=75;   box[2].y:=75;   box[2].z:=-75;π  box[3].x:=-75;  box[3].y:=75;   box[3].z:=-75;π  box[4].x:=-75;  box[4].y:=-75;  box[4].z:=75;π  box[5].x:=75;   box[5].y:=-75;  box[5].z:=75;π  box[6].x:=75;   box[6].y:=75;   box[6].z:=75;π  box[7].x:=-75;  box[7].y:=75;   box[7].z:=75; end;ππprocedure myline(x1,y1,z1,x2,y2,z2:real); {Keeps the draw routine pretty.πPixels are integers, so I round. Since theπ cube is centered around 0,0 I move it over 200 to put it on screen.} beginπ{if you think those real mults are slow, here's some rounds too...}ππ{hey, you may wonder, what happened to the stinking z coordinate? Ah, says I,π this is the simplest of 3d viewing transforms. You just take the z coord outπ of things and boom. Looking straight down the z axis on the object. If I getπ inspired, I will add simple perspective transform to these.} {There, gotπinspired. Made mistakes. Foley et al are not very good atπ tutoring perspective and I'm kinda ready to be done and post this.}π  line(round(x1)+200,round(y1)+200,π       round(x2)+200,round(y2)+200);πend;ππprocedure draw;π{my model is hard coded. No cool things like vertex and edge and faceπ lists.}ππbeginπ  myline(box[0].x,box[0].y,box[0].z, box[1].x,box[1].y,box[1].z);π  myline(box[1].x,box[1].y,box[1].z, box[2].x,box[2].y,box[2].z);π  myline(box[2].x,box[2].y,box[2].z, box[3].x,box[3].y,box[3].z);π  myline(box[3].x,box[3].y,box[3].z, box[0].x,box[0].y,box[0].z);ππ  myline(box[4].x,box[4].y,box[4].z, box[5].x,box[5].y,box[5].z);π  myline(box[5].x,box[5].y,box[5].z, box[6].x,box[6].y,box[6].z);π  myline(box[6].x,box[6].y,box[6].z, box[7].x,box[7].y,box[7].z);π  myline(box[7].x,box[7].y,box[7].z, box[4].x,box[4].y,box[4].z);ππ  myline(box[0].x,box[0].y,box[0].z, box[4].x,box[4].y,box[4].z);π  myline(box[1].x,box[1].y,box[1].z, box[5].x,box[5].y,box[5].z);π  myline(box[2].x,box[2].y,box[2].z, box[6].x,box[6].y,box[6].z);π  myline(box[3].x,box[3].y,box[3].z, box[7].x,box[7].y,box[7].z);ππ  myline(box[0].x,box[0].y,box[0].z, box[5].x,box[5].y,box[5].z);π  myline(box[1].x,box[1].y,box[1].z, box[4].x,box[4].y,box[4].z); end;ππprocedure rotx;π{if you know your matrix multiplication, the following equationsπ are derived fromππ [x   [ 1  0  0  0   [x',y',z',1]π  y     0  c -s  0 =π  z     0  s  c  0π  1]    0  0  0  1]π}πvar i:integer;πbeginπ  setcolor(0);π  draw;π  for i:=0 to 7 doπ    beginπ    box[i].x:= box[i].x;π    box[i].y:= box[i].y*cos(radTheta) + box[i].z*sin(radTheta);π    box[i].z:=-box[i].y*sin(radTheta) + box[i].z*cos(radTheta);π    end;π  setcolor(15);π  draw;πend;ππprocedure roty;π{if you know your matrix multiplication, the following equationsπ are derived fromπ [x   [ c  0  s  0   [x',y',z',1]π  y     0  1  0  0 =π  z    -s  0  c  0π  1]    0  0  0  1]π}πvar i:integer;πbeginπ  setcolor(0);π  draw;π  for i:=0 to 7 doπ    beginπ    box[i].x:= box[i].x*cos(radTheta) - box[i].z*sin(radTheta);π    box[i].y:= box[i].y;π    box[i].z:= box[i].x*sin(radTheta) + box[i].z*cos(radTheta);π    end;π  setcolor(15);π  draw;πend;ππprocedure rotz;π{if you know your matrix multiplication, the following equationsπ are derived fromππ [x   [ c -s  0  0   [x',y',z',1]π  y     s  c  0  0 =π  z     0  0  1  0π  1]    0  0  0  1]π}πvar i:integer;πbeginπ  setcolor(0);π  draw;π  for i:=0 to 7 doπ    beginπ    box[i].x:= box[i].x*cos(radTheta) + box[i].y*sin(radTheta);π    box[i].y:=-box[i].x*sin(radTheta) + box[i].y*cos(radTheta);π    box[i].z:= box[i].z;π    end;π  setcolor(15);π  draw;πend;πππbeginπ  init;π  setcolor(14); draw;π  repeatπ    c:=readkey;π    case c ofπ      ',' : rotx;π      '.' : roty;π      '/' : rotz;π      else {who gives a};π      end; {case}π  until c='q';π  closegraph;πend.π                       70     01-27-9417:37ALL                      BAS VAN GAALEN           Moving a Shape across CRTIMPORT              28     ╓═W {πFrom: BAS VAN GAALENπSubj: Sin-curver Spritesπ---------------------------------------------------------------------------ππ OB>> 1. Scrolling 256c fonts Fast and Smooth.π OB>> 2. Now to do it on top of graphics...π OB>> 3. 3D object engine - If someone can post me one or direct meπ OB>> to build one.π OB>> 4. Shade Bobs/Whatever it called - Taking a shape and moving itπ OB>> across the screen when it leaves trail.  Then, moving againπ OB>> on the trail will couse a stronger color to appear. n' on...π OB>> 5. Moving floor that is NOT a couse of a palette rotetion.π OB>> 6. 2D Scale procedure.π OB>> 7. Centered Stars. And SMOOTH ones.π OB>> 8. Vector BallsππI don't want to give it all away, but I just made some Shaded-bobs (orπwhatever). It realy isn't difficult. It worked right away. Now YOU make a nicerπsin-curve and palette. Here's some source:ππ{ --- cut here --- }ππ{$G+}ππprogram ShadingBobs;πconstπ  Gseg : word = $a000;π  Sofs = 75; Samp = 75; Slen = 255;π  SprPic : array[0..15,0..15] of byte = (π    (0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0),π    (0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0),π    (0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0),π    (0,0,1,1,1,1,1,2,2,1,1,1,1,1,0,0),π    (0,1,1,1,1,1,2,2,2,2,1,1,1,1,1,0),π    (0,1,1,1,1,2,2,3,3,2,2,1,1,1,1,0),π    (1,1,1,1,2,2,3,3,3,3,2,2,1,1,1,1),π    (1,1,1,1,2,2,3,4,4,3,2,2,1,1,1,1),π    (1,1,1,1,2,2,3,3,3,3,2,2,1,1,1,1),π    (0,1,1,1,1,2,2,3,3,2,2,1,1,1,1,0),π    (0,1,1,1,1,1,2,2,2,2,1,1,1,1,1,0),π    (0,0,1,1,1,1,1,2,2,1,1,1,1,1,0,0),π    (0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0),π    (0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0),π    (0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0),π    (0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0));πtype SinArray = array[0..Slen] of word;πvar Stab : SinArray;ππprocedure CalcSinus; var I : word; beginπ  for I := 0 to Slen do Stab[I] := round(sin(I*4*pi/Slen)*Samp)+Sofs; end;ππprocedure SetGraphics(Mode : word); assembler; asmπ  mov ax,Mode; int 10h end;ππfunction keypressed : boolean; assembler; asmπ  mov ah,0bh; int 21h; and al,0feh; end;ππprocedure DrawSprite(X,Y : integer; W,H : byte; Sprite : pointer); assembler;πasmπ  push dsπ  lds si,[Sprite]π  mov es,Gsegπ  cldπ  mov ax,[Y]π  shl ax,6π  mov di,axπ  shl ax,2π  add di,axπ  add di,[X]π  mov bh,[H]π  mov cx,320π  sub cl,[W]π  sbb ch,0π @L:π  mov bl,[W]π @L2:π  lodsbπ  or al,alπ  jz @Sπ  mov dl,[es:di]π  add dl,alπ  mov [es:di],dlπ @S:π  inc diπ  dec blπ  jnz @L2π  add di,cxπ  dec bhπ  jnz @Lπ  pop dsπend;ππprocedure Retrace; assembler; asmπ  mov dx,3dah;π  @l1: in al,dx; test al,8; jnz @l1;π  @l2: in al,dx; test al,8; jz @l2; end;ππprocedure Setpalette;πvar I : byte;πbeginπ  for I := 0 to 255 do beginπ    port[$3c8] := I;π    port[$3c9] := I div 3;π    port[$3c9] := I div 2;π    port[$3c9] := I;π  end;πend;ππprocedure Bobs;πvar X,Y : integer; I,J : byte;πbeginπ  I := 0; J := 25;π  repeatπ    X := 2*Stab[I]; Y := Stab[J];π    inc(I); inc(J);π    Retrace;π    DrawSprite(X,Y,16,16,addr(SprPic));π  until keypressed;πend;ππbeginπ  CalcSinus;π  SetGraphics($13);π  SetPalette;π  Bobs;π  SetGraphics(3);πend.ππ{ DrawSprite procedure taken from Sean Palmer (again).π  It contained some minor bugs: [X] was added to AX, should be DI, andπ  jz @S was jnz @S, so the sprite wasn't drawn. Now it is...π  And of course it was changed to INCREASE the video-mem, not to poke it.ππ  If you get rid of the Retrace it goes a LOT faster. }ππ                                                                                                                 71     01-27-9417:46ALL                      SEAN PALMER              3D Landscape Source      IMPORT              23     ╓≡ {πFrom: SEAN PALMERπSubj: 3d Landscape srcπ---------------------------------------------------------------------------πCheck it out! Clean-room reverse-engineering of something pretty damnπsimilar to Comanche's patented Voxel-space technology... In Turbo!!ππ{by Sean Palmer}π{use I,J,K,L to look around, ESC ends}ππuses crt;ππconstπ xSize=256;           {90 degrees}π ySize=128;           {60 degrees}π angleMask=xSize*4-1; {xSize must be power of 2 or and's won't work}π mapSize=128;ππvarπ sinTab:array[0..angleMask]of integer;  {sin(xyAngle)*$7FFF}π tanTab:array[0..ySize-1]of integer; {tan(zAngle)*$7FFF}ππ map:array[0..mapSize-1,0..mapSize-1]of byte;ππtypeπ fixed=record case boolean ofπ  false:(l:longint);π  true:(f:word;i:integer);π  end;ππprocedure drawScene(x,y,z,rot:integer);πvar lastTan,lastAngle,h:integer;π    mapTan:longint;πvar scrn:word;πvar color,height:byte;πvar xs,ys,ds:longint;πvar xp,yp,dp:fixed;πbeginπ fillchar(mem[$A000:0],320*200,0);π for h:=0 to xSize-1 do beginπ  lastAngle:=0;π  scrn:=h+320*(ySize-1);π  lastTan:=tanTab[lastAngle];π  xp.i:=x; xp.f:=0;π  yp.i:=y; yp.f:=0;π  dp.l:=0;π  xs:=longint(sinTab[(h+rot-(xSize shr 1))and angleMask])*2;π  ys:=longint(sinTab[(h+rot-(xSize shr 1)+xSize)and angleMask])*2; {cos}π  ds:=$FFFE;π  inc(xp.l,xs*16);π  inc(yp.l,ys*16);π  inc(dp.l,ds*16);π  while lastAngle<ySize do beginπ   inc(xp.l,xs*2);π   inc(yp.l,ys*2);π   inc(dp.l,ds*2);π   inc(xs,xs div 32);π   inc(ys,ys div 32);π   inc(ds,ds shr 5);π   if word(xp.i)>mapSize-1 thenπ    break;π   if word(yp.i)>mapSize-1 thenπ    break;π   height:=map[xp.i,yp.i];π   mapTan:=(longint(height-z)*$7FFF)div dp.i;π   color:=32+(z-height);π   while(lastTan<=mapTan)and(lastAngle<ySize)do beginπ    mem[$A000:scrn]:=color;π    dec(scrn,320);π    inc(lastAngle);π    lastTan:=tanTab[lastAngle];π    end;π   end;π  end;π end;πππprocedure initTables; var i:integer; r:real; beginπ for i:=0 to angleMask doπ  sinTab[i]:=round(sin(i*pi/512)*$7FFF);π for i:=0 to ySize-1 do beginπ  r:=(i-64)*pi/(3*ySize);π  tanTab[i]:=round(sin(r)/cos(r)*$7FFF);π  end;π end;ππprocedure initMap; var x,y:integer; beginπ for x:=0 to 127 doπ  for y:=0 to 127 doπ   map[x,y]:=((longint(sinTab[(y*21-12)and angleMask])+sinTab[(x*31+296)and angleMask]div 2)shr 12)+120;π end;πππvar c:char;π x,y,z,r,a:integer;π i:word;ππbeginπ asm mov ax,$13; int $10; end;π initTables;π initMap;π randomize;π x:=50+random(29);π y:=50+random(29);π z:=125+random(10);π r:=random(angleMask);π a:=64;π repeatπ  drawScene(x,y,z,r);π  c:=upcase(readkey);π  case c ofπ   'I':if tanTab[ySize-1]<30000 then for i:=0 to ySize-1 do inc(tanTab[i],500);π   'K':if tanTab[0]>-30000 then for i:=0 to ySize-1 do dec(tanTab[i],500);π   'J':r:=(r-32)and angleMask;π   'L':r:=(r+32)and angleMask;π   end;π  until c=^[;π textMode(lastMode);π end.ππ                72     01-27-9417:46ALL                      BERNIE PALLEK            MODE 13H Graphics Unit   IMPORT              60     ╓╩ⁿ {πFrom: BERNIE PALLEKπSubj: GRAF_13H.PASπ---------------------------------------------------------------------------π}π(**************************************************)π(*                                                *)π(*         GRAPHICS ROUTINES FOR MODE 13H         *)π(*         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~         *)π(*        320x200x256 (linearly-addressed)        *)π(*  Collected from routines in the Public Domain  *)π(*          Assembled by Bernie Pallek            *)π(*                                                *)π(**************************************************)ππ{ DISCLAIMER: Use this unit at your own risk.  I will not be liableπ              for anything negative resulting from use of this unit. }ππUNIT Graf_13h;ππINTERFACEππCONSTπ  Color : Byte = 0;ππTYPEπ  RGBPalette = Array[0..767] of Byte;ππFUNCTION  GetVideoMode : Byte;πPROCEDURE SetVideoMode(desiredVideoMode : Byte);πFUNCTION  GetPixel(pix2get_x, pix2get_y : Word) : Byte;πPROCEDURE SetPixel(pix2set_x, pix2set_y : Word; pix2set_c : Byte);πPROCEDURE Ellipse(exc, eyc, ea, eb : Integer);πPROCEDURE Line(lnx1, lny1, lnx2, lny2 : Integer);πPROCEDURE GetPalette(index2get : Byte; VAR r_inte, g_inte, b_inte : Byte);πPROCEDURE SetPalette(index2set, r_inte, g_inte, b_inte : Byte);πPROCEDURE BurstSetPalette(burstPalette : RGBPalette);πPROCEDURE ScaleBitmap(VAR bmp2scale; bwidth, bheight : Byte;π  bstrtx, bstrty, bendx, bendy : Word);πPROCEDURE WaitForRetrace;πPROCEDURE ClearScr;πππIMPLEMENTATIONπππ{ private type used by ScaleBitmap() }πTYPEπ  Fixed = RECORD CASE Boolean OFπ    True  : (w : LongInt);π    False : (f, i : Word);π  END;ππFUNCTION GetVideoMode : Byte;πVARπ  tempVMode : Byte;πBEGINπ  ASMπ    mov ah,$0fπ    int $10π    mov tempvmode,alπ  END;π  GetVideoMode := tempVMode;πEND;ππPROCEDURE SetVideoMode(desiredVideoMode : Byte);π{ desiredVideoMode = $03 : 80x25 colour textπ                     $13 : 320x200x256 monoplanedπ                           video data from $A000:0000 to $A000:FFFFπ}πBEGINπ  ASMπ    mov ah,0π    mov al,desiredvideomode;π    int $10π  END;πEND;ππFUNCTION GetPixel(pix2get_x, pix2get_y : Word) : Byte;πBEGINπ  GetPixel := Mem[$A000 : pix2get_y * 320 + pix2get_x];πEND;ππPROCEDURE SetPixel(pix2set_x, pix2set_y : Word; pix2set_c : Byte);πBEGINπ  Mem[$A000 : pix2set_y * 320 + pix2set_x] := pix2set_c;πEND;ππ{ originally by Sean Palmer, I just mangled it  :^) }πPROCEDURE Ellipse(exc, eyc, ea, eb : Integer);πVARπ  elx, ely : Integer;π  aa, aa2, bb, bb2, d, dx, dy : LongInt;πBEGINπ  elx := 0; ely := eb; aa := LongInt(ea) * ea; aa2 := 2 * aa;π  bb := LongInt(eb) * eb; bb2 := 2 * bb;π  d := bb - aa * eb + aa DIV 4; dx := 0; dy := aa2 * eb;π  SetPixel(exc, eyc - ely, Color); SetPixel(exc, eyc + ely, Color);π  SetPixel(exc - ea, eyc, Color); SetPixel(exc + ea, eyc, Color);ππ  WHILE (dx < dy) DO BEGINπ    IF (d > 0) THEN BEGIN Dec(ely); Dec(dy, aa2); Dec(d, dy); END;π    Inc(elx); Inc(dx, bb2); Inc(d, bb + dx);π    SetPixel(exc + elx, eyc + ely, Color);π    SetPixel(exc - elx, eyc + ely, Color);π    SetPixel(exc + elx, eyc - ely, Color);π    SetPixel(exc - elx, eyc - ely, Color);π  END;π  Inc(d, (3 * (aa - bb) DIV 2 - (dx + dy)) DIV 2);π  WHILE (ely > 0) DO BEGINπ    IF (d < 0) THEN BEGIN Inc(elx); Inc(dx, bb2); Inc(d, bb + dx); END;π    Dec(ely); Dec(dy, aa2); Inc(d, aa - dy);π    SetPixel(exc + elx, eyc + ely, Color);π    SetPixel(exc - elx, eyc + ely, Color);π    SetPixel(exc + elx, eyc - ely, Color);π    SetPixel(exc - elx, eyc - ely, Color);π  END;πEND;ππ{ originally by Sean Palmer, I just mangled it }πPROCEDURE Line(lnx1, lny1, lnx2, lny2 : Integer);πVARπ  lndd, lndx, lndy, lnai, lnbi, lnxi, lnyi : Integer;πBEGINπ  IF (lnx1 < lnx2) THEN BEGIN lnxi := 1; lndx := lnx2 - lnx1;π  END ELSE BEGIN lnxi := (-1); lndx := lnx1 - lnx2; END;π  IF (lny1 < lny2) THEN BEGIN lnyi := 1; lndy := lny2 - lny1;π  END ELSE BEGIN lnyi := (-1); lndy := lny1 - lny2; END;π  SetPixel(lnx1, lny1, Color);π  IF (lndx > lndy) THEN BEGIN lnai := (lndy - lndx) * 2;π    lnbi := lndy * 2;π    lndd := lnbi - lndx;π    REPEAT IF (lndd >= 0) THEN BEGIN Inc(lny1, lnyi);π      Inc(lndd, lnai); END ELSE Inc(lndd, lnbi);π      Inc(lnx1, lnxi); SetPixel(lnx1, lny1, Color);π    UNTIL (lnx1 = lnx2);π  END ELSE BEGIN lnai := (lndx - lndy) * 2; lnbi := lndx * 2;π    lndd := lnbi - lndy;π    REPEAT IF (lndd >= 0) THEN BEGIN Inc(lnx1, lnxi);π      Inc(lndd, lnai); END ELSE Inc(lndd, lnbi);π      Inc(lny1, lnyi); SetPixel(lnx1, lny1, Color);π    UNTIL (lny1 = lny2);π  END;πEND;ππPROCEDURE GetPalette(index2get : Byte; VAR r_inte, g_inte, b_inte : Byte);π{ returns the r, g, and b values of a palette index }πBEGINπ  Port[$3C7] := index2get;π  r_inte := Port[$3C9];π  g_inte := Port[$3C9];π  b_inte := Port[$3C9];πEND;ππPROCEDURE SetPalette(index2set, r_inte, g_inte, b_inte : Byte);π{ sets the r, g, and b values of a palette index }πBEGINπ  Port[$3C8] := index2set;π  Port[$3C9] := r_inte;π  Port[$3C9] := g_inte;π  Port[$3C9] := b_inte;πEND;ππPROCEDURE BurstSetPalette(burstPalette : RGBPalette);πVARπ  burstCount : Word;πBEGINπ  Port[$3C8] := 0;π  FOR burstCount := 0 TO 767 DO Port[$3C9] := burstPalette[burstCount];πEND;ππ{ originally by Sean Palmer, I just mangled it }πPROCEDURE ScaleBitmap(VAR bmp2scale; bwidth, bheight : Byte;π  bstrtx, bstrty, bendx, bendy : Word);π{ - bmp2scale is an array [0..bwidth, 0..bheight] of byte      }π{   which contains the original bitmap                         }π{ - bwidth and bheight are the actual width - 1 and the actual }π{   height - 1 of the normal bitmap                            }π{ - bstrtx and bstrty are the x and y values for the upper-    }π{   left-hand corner of the scaled bitmap                      }π{ - bendx and bendy are the lower-right-hand corner of the     }π{   scaled version of the original bitmap                      }π{ - eg. to paste an unscaled version of a bitmap that is 64x64 }π{   pixels in size in the top left-hand corner of the screen,  }π{   fill the array with data and call:                         }π{     ScaleBitmap(bitmap, 64, 64, 0, 0, 63, 63);               }π{ - to create an array for the bitmap, make it like this:      }π{     VAR myBitmap : Array[0..bmpHeight, 0..bmpWidth] of Byte; }π{   where bmpHeight is the actual height of the normal-size    }π{   bitmap less one, and bmpWidth is the actual width less one }πVARπ  bmp_sx, bmp_sy, bmp_cy : Fixed;π  bmp_s, bmp_w, bmp_h    : Word;ππBEGINπ  bmp_w := bendx - bstrtx + 1; bmp_h := bendy - bstrty + 1;π  bmp_sx.w := bwidth * $10000 DIV bmp_w;π  bmp_sy.w := bheight * $10000 DIV bmp_h;π  bmp_s := 320 - bmp_w; bmp_cy.w := 0;π  ASMπ    push ds; mov ds,word ptr bmp2scale + 2;π    mov ax,$a000; mov es,ax; cld; mov ax,320;π    mul bstrty; add ax,bstrtx; mov di,ax;π   @l2:π    mov ax,bmp_cy.i; mul bwidth; mov bx,ax;π    add bx,word ptr bmp2scale;π    mov cx,bmp_w; mov si,0; mov dx,bmp_sx.f;π   @l:π    mov al,[bx]; stosb; add si,dx; adc bx,bmp_sx.i;π    loop @l;π    add di,bmp_s; mov ax,bmp_sy.f; mov bx,bmp_sy.i;π    add bmp_cy.f,ax; adc bmp_cy.i,bx;π    dec word ptr bmp_h; jnz @l2; pop ds;π  END;πEND;ππPROCEDURE WaitForRetrace;π{ waits for a vertical retrace to reduce flicker }πBEGINπ  REPEAT UNTIL (Port[$3DA] AND 8) = 8;πEND;ππPROCEDURE ClearScr;πBEGINπ  FillChar(Mem[$A000:0000], 64000, 0);πEND;ππEND.  { of unit }ππThat's it!  It's not complete, but it's meant as a starter for all who areπinterested in VGA graphics.  Happy programming!ππBernie.πππ--- Maximus/2 2.01wbπ * Origin: * idiot savant * +1 905 935 6628 * (1:247/128)π                                     73     02-03-9409:18ALL                      SEAN PALMER              RIP Bezier Curves        IMPORT              23     ╓ε▒ {πFrom: SEAN PALMERπSubj: RIP Bezier Curveπ---------------------------------------------------------------------------π NO> Does anyone have any code for constructing a RIP Bezier curve that isπ NO> exactly the same as the one used by Telegrafix developers. I have someπ NO> code that comes close, but close isn't good enough. I need this to beπ NO> dead on accurate.π NO> PS. I'm willing to share my code with others that are interested inπ NO> RIP.ππ{Public domain by Sean Palmer}π{converted from Steve Enns' original Basic subroutines by Sean Palmer}ππvar color:byte;πprocedure plot(x,y:word);beginπ mem[$A000:y*320+x]:=color;π end;ππtypeπ coord=record x,y:integer; end;π CurveDataRec=array[0..65521 div sizeof(coord)]of coord;ππprocedure drawBSpline(var d0:coord;nPoints,nSteps:word);π const nsa=1/6; nsb=2/3;π varπ  i,i2,xx,yy:integer;π  t,ta,t2,t2a,t3,t3a,nc1,nc2,nc3,nc4,step:real;π  d:curveDataRec absolute d0;πbeginπ step:=1/nSteps;π for i:=0 to nPoints-4 do beginπ  color:=i+32+2;π  t:=0.0;π  for i2:=pred(nSteps)downto 0 do beginπ   t:=t+step;π   ta:=t*0.5; t2:=t*t; t2A:=t2*0.5; t3:=t2*t; t3A:=t3*0.5;π   nc1:=-nsa*t3+t2A-ta+nsa;π   nc2:=t3a-t2+nsb;π   nc3:=-t3a+t2a+ta+nsa;π   nc4:=nsa*t3;π   xx:=round(nc1*d[i].x+nc2*d[succ(i)].x+nc3*d[i+2].x+nc4*d[i+3].x);π   yy:=round(nc1*d[i].y+nc2*d[succ(i)].y+nc3*d[i+2].y+nc4*d[i+3].y);π   plot(xx,yy);π   end;π  end;π end;ππprocedure drawBezier(var d0:coord;nPoints,nSteps:word);π const nsa=1/6; nsb=2/3;π varπ  i,i2,i3,xx,yy:integer;π  t,tm3,t2,t2m3,t3,t3m3,nc1,nc2,nc3,nc4,step:real;π  d:curveDataRec absolute d0;πbeginπ step:=1/nSteps;π for i2:=0 to pred(nPoints) div 4 do beginπ  i:=i2*4;π  t:=0.0;π  for i3:=pred(nSteps) downto 0 do beginπ   t:=t+step;π   tm3:=t*3.0; t2:=t*t; t2m3:=t2*3.0; t3:=t2*t; t3m3:=t3*3.0;π   nc1:=1-tm3+t2m3-t3;π   nc2:=t3m3-2.0*t2m3+tm3;π   nc3:=t2m3-t3m3;π   nc4:=t3;ππ   xx:=round(nc1*d[i].x+nc2*d[succ(i)].x+nc3*d[i+2].x+nc4*d[i+3].x);π   yy:=round(nc1*d[i].y+nc2*d[succ(i)].y+nc3*d[i+2].y+nc4*d[i+3].y);π   plot(xx,yy);π   end;π  end;π end;ππconst numpoints=40;ππvar c:array[-1..2+numPoints]of coord;πvar i:integer;πbeginπ asm mov ax,$13; int $10; end;  {init vga/mcga graphics}π randomize;π for i:=1 to numPoints do with c[i] do beginπ  x:=i*(319 div numPoints);    {for precision demo}π {x:=random(320);}             {for fun demo}π  y:=random(200);π  end;π for i:=1 to numPoints div 2 do c[i*2+1].y:=c[i*2].y;    {fit closer}π for i:=1 to numPoints do with c[i] do begin color:=i+32; plot(x,y); end;π c[-1]:=c[1]; c[0]:=c[1];  {replicate end points so curves fit to input}π c[numPoints+1]:=c[numPoints]; c[numPoints+2]:=c[numPoints];π drawBSpline(c[-1],numPoints+4,256); {set third parm to 256 for precision, 64 f}π readln;π asm mov ax,3; int $10; end;  {text mode again}π end.ππ                                           74     02-03-9409:19ALL                      SCOTT BRADSHAW           More RIP Bezier Curves   IMPORT              11     ╓═W {πFrom: SCOTT BRADSHAWπSubj: RIP BEZIER CURVESπ---------------------------------------------------------------------------πWell, I had a whole RIP unit I made for Turbo Pascal over the modem,πbut it got lost in a HD crash. I am really not that interested inπRIP anymore, but I will give you mu source to the Bezier Curve. Itπshould be pretty close to what your looking for...π}πprogram bezier;πuses graph,crt;ππprocedure Bezier_2D_Curve( x, y, cx,cy,a,b,ca,cb:integer;incr:real);πvarπ   qx, qy :real;π   q1, q2, q3, q4:real;π   plotx, ploty:integer;π   t:real;ππ    beginπ      t := 0;π    while (t <= 1) do beginπ      q1 := t*t*t*-1 + t*t*3 + t*-3 + 1;π      q2 := t*t*t*3 + t*t*-6 + t*3;π      q3 := t*t*t*-3 + t*t*3;π      q4 := t*t*t;π      qx := q1*x + q2*cx + q3*a + q4*ca;π      qy := q1*y + q2*cy + q3*b + q4*cb;π      plotx := round(qx);π      ploty := round(qy);π      putpixel( plotx, ploty, 15);π      t := t + incr;π   end;πend;ππvar gd,gm:integer;π    c:char;πbeginπ   gd := VGA;π   gm := VGAHI;π   initgraph(gd,gm,'\turbo\tp');π   setcolor( BLUE );π   Bezier_2D_Curve( 100, 400, 25, 450, 120, 275, 300, 455,0.003 );π   c:=readkey;π   Bezier_2D_Curve( 310, 200, 360, 150, 510, 200, 460, 250,0.003 );π   c:=readkey;πend.ππ                                            75     02-03-9409:19ALL                      NICK ONOUFRIOU           Another Bezier Curve     IMPORT              12     ╓═W {πFrom: NICK ONOUFRIOUπSubj: RIP Bezier Curvesπ---------------------------------------------------------------------------πSP> I can't post the code I have that IS Telegrafix-compatible (for obviousπSP> reasons) but if you post your code I can try and modify it to make itπSP> work correctly.ππHere it is. It comes close, but can't get it to create the same curves thatπTelegrafix creates. Thanks for any help Sean. Are you writing the RIP codeπfor TELIX?π}ππprocedure DrawBezierCurve(px1,py1,px2,py2,px3,py3,px4,py4,count : integer);ππfunction pow(x : real; y : word) : real;πvarπ  nt     : word;π  result : real;πbeginπ result := 1;π for nt := 1 to y doπ     result := result * x;π pow := result;πend;ππprocedure Bezier(t : real; var x, y : integer);πbeginπ x := round(pow(1 - t, 3) * px1 + 3 * t * pow(1 - t, 2) * px2 +π                3 * t * t * (1 - t) * px3 + pow(t, 3) * px4);π y := round(pow(1 - t, 3) * py1 + 3 * t * pow(1 - t, 2) * py2 +π                3 * t * t * (1 - t) * py3 + pow(t, 3) * py4);πend;ππvarπ resolution,t : real;π xc, yc       : integer;πbeginπ        if count = 0 then exit;π        resolution:=1/count;ππ        Moveto(px1,py1);π        t := 0;π        while t < 1 do beginπ           Bezier(t, xc, yc);π           lineto(xc, yc);π           t := t + resolution;π        end;π        LineTo(px4,py4);πend;ππ                                                                     76     02-03-9410:55ALL                      FIASAL JUMA              Fire Graphic             IMPORT              89     ╓?╦ {π---------------------------------------------------------------------------ππ    This is a PD source that I came across not too long ago.. It displays aπsimulation of flames or fire.. Its pretty good..π}ππ{*        credit were given, however. If you have any improvements,       *}π{*        find any bugs etc. mail me at mackey@aqueous.ml.csiro.au        *}π{*        with MARK: in the subject header.                               *}π{*                                                                        *}π{*************************************************************************}πππuses crt;πtype bigarr=array[0..102,0..159] of integer;πvar f:bigarr;π    i,j,k,l:word;π    delta:integer;π    pal:array[0..255,1..3] of byte;π    ch:char;ππprocedure setmode13;πassembler;πasmπ  mov ax,13hπ  int 10hπend;ππprocedure setpalette;πvar mapfile:text;π    i,j:integer;ππbeginπ  assign(mapfile,'flames5.map');  {kludgy, but it works!}π  reset(mapfile);π  for i:=0 to 255 doπ  for j:=1 to 3 doπ  beginπ    read(mapfile,pal[i,j]);π    pal[i,j]:=pal[i,j] shr 2;π  end;π  asmπ    mov si,offset palπ    mov cx,768      {no of colour registers}π    mov dx,03c8hπ    xor al,al     {First colour to change pal for = 0}π    out dx,alπ    inc dxπ@1: outsbπ    dec cx        {safer than rep outsb}π    jnz @1π  end;πend;ππbeginπ  setmode13;π  setpalette;π  randomize;π  ch:=' ';π  for i:=0 to 102 doπ  for j:=0 to 159 doπ    f[i,j]:=0;        {initialise array}ππ  repeatπ    asm                {move lines up, averaging}π      mov cx,16159;    {no. elements to change}π      mov di,offset fπ      add di,320   {di points to 1st element of f in upper row (320 bytes/row)}π@1:π      mov ax,ds:[di-2]π      add ax,ds:[di]π      add ax,ds:[di+2]π      add ax,ds:[di+320]π      shr ax,2     {divide by 4: average 4 elements of f}π      jz @2π      sub ax,1π@2:   mov word ptr ds:[di-320],axπ      add di,2π      dec cxπ      jnz @1    {faster than _loop_ on 486}π    end;πππ    for j:=0 to 159 do  {set new bottom line}ππ--- Maximus 2.01wbπ * Origin: *THE K-W AMATEUR RADIO BBS-(VE3MTS)* ->DS16.8<- (1:221/177)π===========================================================================π BBS: Canada Remote SystemsπDate: 12-02-93 (17:42)             Number: 46962πFrom: FIASAL JUMA                  Refer#: NONEπ  To: ALL                           Recvd: NO  πSubj: Fire                           Conf: (1221) F-PASCALπ---------------------------------------------------------------------------πππ       This is a PD source that I came across a while ago.. It simulates flamesπor fire.. its pretty good source..ππprogram flames;π{**************************************************************************}π{*                                                                        *}π{*    FLAMES by M.D.Mackey  (C) 1993                                      *}π{*        This code released into the public domain. It may be freely     *}π{*        used, distributed and modified. I would appreciate it if        *}π{*        credit were given, however. If you have any improvements,       *}π{*        find any bugs etc. mail me at mackey@aqueous.ml.csiro.au        *}π{*        with MARK: in the subject header.                               *}π{*                                                                        *}π{**************************************************************************}πππuses crt;ππConst pal : array [1..768] of Byte =( 0,  0,  0,  0,  0, 24,  0,  0, 24,  0,π0, 28,π                          0,  0, 32,  0,  0, 32,  0,  0, 36,  0,  0, 40,π                           8,  0, 40, 16,  0, 36, 24,  0, 36, 32,  0, 32,π                          40,  0, 28, 48,  0, 28, 56,  0, 24, 64,  0, 20,π                          72,  0, 20, 80,  0, 16, 88,  0, 16, 96,  0, 12,π                         104,  0,  8,112,  0,  8,120,  0,  4,128,  0,  0,π                         128,  0,  0,132,  0,  0,136,  0,  0,140,  0,  0,π                         144,  0,  0,144,  0,  0,148,  0,  0,152,  0,  0,π                         156,  0,  0,160,  0,  0,160,  0,  0,164,  0,  0,π                         168,  0,  0,172,  0,  0,176,  0,  0,180,  0,  0,π                         184,  4,  0,188,  4,  0,192,  8,  0,196,  8,  0,π                         200, 12,  0,204, 12,  0,208, 16,  0,212, 16,  0,π                         216, 20,  0,220, 20,  0,224, 24,  0,228, 24,  0,π                         232, 28,  0,236, 28,  0,240, 32,  0,244, 32,  0,π                         252, 36,  0,252, 36,  0,252, 40,  0,252, 40,  0,π                         252, 44,  0,252, 44,  0,252, 48,  0,252, 48,  0,π                         252, 52,  0,252, 52,  0,252, 56,  0,252, 56,  0,π                         252, 60,  0,252, 60,  0,252, 64,  0,252, 64,  0,π                         252, 68,  0,252, 68,  0,252, 72,  0,252, 72,  0,π                         252, 76,  0,252, 76,  0,252, 80,  0,252, 80,  0,π                         252, 84,  0,252, 84,  0,252, 88,  0,252, 88,  0,π                         252, 92,  0,252, 96,  0,252, 96,  0,252,100,  0,π                         252,100,  0,252,104,  0,252,104,  0,252,108,  0,π                         252,108,  0,252,112,  0,252,112,  0,252,116,  0,π                         252,116,  0,252,120,  0,252,120,  0,252,124,  0,π                         252,124,  0,252,128,  0,252,128,  0,252,132,  0,π                         252,132,  0,252,136,  0,252, 136,   0,252, 140,   0,π                         252, 140,   0,252, 144,   0,252, 144,   0,252, 148,π0,π                         252, 152,   0,252, 152,   0,252, 156,   0,252, 156,π0,π                         252, 160,   0,252, 160,   0,252, 164,   0,252, 164,π0,π                         252, 168,   0,252, 168,   0,252, 172,   0,252, 172,π0,π                         252, 176,   0,252, 176,   0,252, 180,   0,252, 180,π0,π                         252, 184,   0,252, 184,   0,252, 188,   0,252, 188,π0,π                         252, 192,   0,252, 192,   0,252, 196,   0,252, 196,π0,π                         252, 200,   0,252, 200,   0,252, 204,   0,252, 208,π0,π                         252, 208,   0,252, 208,   0,252, 208,   0,252, 208,π0,π                         252, 212,   0,252, 212,   0,252, 212,   0,252, 212,π0,π                         252, 216,   0,252, 216,   0,252, 216,   0,252, 216,π0,π                         252, 216,   0,252, 220,   0,252, 220,   0,252, 220,π0,π                         252, 220,   0,252, 224,   0,252, 224,   0,252, 224,π0,π                         252, 224,   0,252, 228,   0,252, 228,   0,252, 228,π0,π                         252, 228,   0,252, 228,   0,252, 232,   0,252, 232,π0,π                         252, 232,   0,252, 232,   0,252, 236,   0,252, 236,π0,π                         252, 236,   0,252, 236,   0,252, 240,   0,252, 240,π0,ππ--- Maximus 2.01wbπ * Origin: *THE K-W AMATEUR RADIO BBS-(VE3MTS)* ->DS16.8<- (1:221/177)π===========================================================================π BBS: Canada Remote SystemsπDate: 12-02-93 (17:45)             Number: 46963πFrom: FIASAL JUMA                  Refer#: NONEπ  To: ALL                           Recvd: NO  πSubj: Fire II                        Conf: (1221) F-PASCALπ---------------------------------------------------------------------------πContinue.....ππ                252, 244,   0,252, 244,   0,252, 244,   0,252, 248,   0,π                252, 248,   0,252, 248,   0,252, 248,   0,252, 252,   0,π                252, 252,   4,252, 252,   8,252, 252,  12,252, 252,  16,π                252, 252,  20,252, 252,  24,252, 252,  28,252, 252,  32,π                252, 252,  36,252, 252,  40,252, 252,  40,252, 252,  44,π                252, 252,  48,252, 252,  52,252, 252,  56,252, 252,  60,π                252, 252,  64,252, 252,  68,252, 252,  72,252, 252,  76,π                252, 252,  80,252, 252,  84,252, 252,  84,252, 252,  88,π                252, 252,  92,252, 252,  96,252, 252, 100,252, 252, 104,π                252, 252, 108,252, 252, 112,252, 252, 116,252, 252, 120,π                252, 252, 124,252, 252, 124,252, 252, 128,252, 252, 132,π                252, 252, 136,252, 252, 140,252, 252, 144,252, 252, 148,π                252, 252, 152,252, 252, 156,252, 252, 160,252, 252, 164,π                252, 252, 168,252, 252, 168,252, 252, 172,252, 252, 176,π                252, 252, 180,252, 252, 184,252, 252, 188,252, 252, 192,π                252, 252, 196,252, 252, 200,252, 252, 204,252, 252, 208,π                252, 252, 208,252, 252, 212,252, 252, 216,252, 252, 220,π                252, 252, 224,252, 252, 228,252, 252, 232,252, 252, 236,π                252, 252, 240,252, 252, 244,252, 252, 248,252, 252, 252);πππtype bigarr=array[0..102,0..159] of integer;πvar f:bigarr;π    i,j,k,l:word;π    delta:integer;π    pal:array[0..255,1..3] of byte;π    ch:char;ππprocedure setmode13;πassembler;πasmπ  mov ax,13hπ  int 10hπend;ππprocedure setpalette;πvar mapfile:text;π    i,j:integer;ππbeginπ  for j:=1 to 768 doπ  beginπ    pal[j]:=pal[j] shr 2;π  end;ππ  asmπ    mov si,offset palπ    mov cx,768π    mov dx,03c8hπ    xor al,alπ    out dx,alπ    inc dxπ@1:π    outsbπ    dec cxπ    jnz @1π  end;πend;ππbeginπ  setmode13;π  setpalette;π  randomize;π  ch:=' ';π  for i:=0 to 102 doπ  for j:=0 to 159 doπ    f[i,j]:=0;        {initialise array}ππ  repeatπ    asm                {move lines up, averaging}π      mov cx,16159;    {no. elements to change}π      mov di,offset fπ      add di,320   {di points to 1st element of f in upper row (320 bytes/row)}π@1:π      mov ax,ds:[di-2]π      add ax,ds:[di]π      add ax,ds:[di+2]π      add ax,ds:[di+320]π      shr ax,2     {divide by 4: average 4 elements of f}π      jz @2π      sub ax,1π@2:   mov word ptr ds:[di-320],axπ      add di,2π      dec cxπ      jnz @1    {faster than _loop_ on 486}π    end;πππ    for j:=0 to 159 do  {set new bottom line}π    beginπ      if random<0.4 thenπ        delta:=random(2)*255;π      f[101,j]:=delta;π      f[102,j]:=delta;π    end;ππ--- Maximus 2.01wbπ * Origin: *THE K-W AMATEUR RADIO BBS-(VE3MTS)* ->DS16.8<- (1:221/177)π===========================================================================π BBS: Canada Remote SystemsπDate: 12-02-93 (17:47)             Number: 46964πFrom: FIASAL JUMA                  Refer#: NONEπ  To: ALL                           Recvd: NO  πSubj: Fire III                       Conf: (1221) F-PASCALπ---------------------------------------------------------------------------πContinue..ππ    asm                 {output to screen}π      mov si,offset fπ      mov ax,0a000hπ      mov es,axπ      mov di,0π      mov dx,100π@3:π      mov bx,2π@2:π      mov cx,160π@1:π      mov al,[si]π      mov ah,alπ      mov es:[di],ax     {word aligned write to display mem}π      add di,2π      add si,2π      dec cxπ      jnz @1ππ      sub si,320π      dec bxπ      jnz @2ππ      add si,320π      dec dxπ      jnz @3π    end;π    if keypressed then ch:=readkey;π  until ch=#27;π  asm   {restore text mode}π    mov ax,03hπ    int 10hπ  end;πend.ππ      There is a million things you can do to modify that code to look betterπor run faster.. Making it work in modex is one good possibility and its notπthat hard.. laterπ                                                                                                               77     02-03-9410:58ALL                      SWAG SUPPORT TEAM        Writing Text in Graphics IMPORT              31     ╓p╩ (*πWrite a unit, that assigns an text file to the Graphics Screen and thenπassign output with this proc, then use rewrite(output) and you canπuse write/writeln in Graphics mode as well. Don't forgetπAssign(output,'');rewrite(output) orπCrtAssign(output);rewrite(output) when back in Text Mode!πYou can even implement read/readln in graphics mode, but this is moreπ complicated.πOne difference to text mode: use MoveTo instead of GotoXY!ππI've neither my unit nor the TP manual available just now,πbut it works like this (output only!):π*)πunit GrpWrite;ππinterfaceππuses Graph,Dos,BGIFont,BGIDriv;ππprocedure GraphAssign(var F:text);ππimplementationπ{$R-,S-}ππvarπ  GraphDriver, GraphMode, Error : integer;π  a : string;ππprocedure Abort(Msg : string);πbeginπ  Writeln(Msg, ': ', GraphErrorMsg(GraphResult));π  Halt(1);πend;ππ{$F+} {DO NOT FORGET}ππfunction GraphFlush(var F:TextRec):integer;πbeginπ  GraphFlush := 0;πend;ππfunction GraphClose(var F:TextRec):integer;π beginπ   GraphClose := 0;π end;       {There's nothing to close}πππfunction GraphWrite(var F:TextRec):integer;π varπ  s : string;π  P : word;π beginπ with F doπ beginπ   P := 0;π   while P<BufPos doπ   beginπ     OutText(BufPtr^[P]);π     Inc(P);π   end;π   BufPos := 0;π end;π{               (may need more than one OutText...)}π  (*... {Clear buffer}*)π  GraphWrite := 0;π end;πππfunction GraphOpen(var F:TextRec):integer;π beginπ   { Register all the drivers }π  if RegisterBGIdriver(@CGADriverProc) < 0 thenπ    Abort('CGA');π  if RegisterBGIdriver(@EGAVGADriverProc) < 0 thenπ    Abort('EGA/VGA');π  if RegisterBGIdriver(@HercDriverProc) < 0 thenπ    Abort('Herc');π  if RegisterBGIdriver(@ATTDriverProc) < 0 thenπ    Abort('AT&T');π  if RegisterBGIdriver(@PC3270DriverProc) < 0 thenπ    Abort('PC 3270');πππ  { Register all the fonts }π  if RegisterBGIfont(@GothicFontProc) < 0 thenπ    Abort('Gothic');π  if RegisterBGIfont(@SansSerifFontProc) < 0 thenπ    Abort('SansSerif');π  if RegisterBGIfont(@SmallFontProc) < 0 thenπ    Abort('Small');π  if RegisterBGIfont(@TriplexFontProc) < 0 thenπ    Abort('Triplex');ππ  GraphDriver := Detect;                  { autodetect the hardware }π  InitGraph(GraphDriver, GraphMode, '');  { activate graphics }π  if GraphResult <> grOk then             { any errors? }π  beginπ    Writeln('Graphics init error: ', GraphErrorMsg(GraphDriver));π    Halt(1);π  end;π  with F doπ  beginπ  Closefunc:=@GraphClose;π  InOutFunc:=@GraphWrite;π  FlushFunc:=@GraphFlush;π  end;π  GraphOpen := 0;π(*  ... {Initialisations, see your TP manual}*)π end;π{$F-}πprocedure GraphAssign;π beginπ  with TextRec(F) doπ   beginπ     Mode := fmClosed;π     BufSize := SizeOf(Buffer);π     BufPtr := @Buffer;π     Name[0] := #0;π     OpenFunc:= @GraphOpen;π    {You can make some initialisations already here}π   endπ end;πend.π=================WRTGRTST.PAS follows==================π{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+}π{$M 16384,0,655360}πuses Crt,π     Graph,     { library of graphics routines }π     GrWrite;πvarπ  GraphDriver, GraphMode, Error : integer;π  a : string;π  GrOutput:Text;ππprocedure Abort(Msg : string);πbeginπ  Writeln(Msg, ': ', GraphErrorMsg(GraphResult));π  Halt(1);πend;ππbeginπ GraphAssign(Output);  {Standard output to graphics screen}π {$I-}π rewrite(Output); {actually calls GraphOpen}π  {$I+}π if IoResult <> 0 then halt;ππ(* ....*)π MoveTo(65,90);π a := 'this is a string';π write('this is an embedded string');   {write to graphics screen}π MoveTo(65,120);π write(' and this is the second');π Close(Output); {nothing shows on the screen until this is executed}π ReadLn(a);π CloseGraph;π {Standard output to text screen}π Assign(output,'');π rewrite(output);π GotoXY(5,20); {THIS WORKS}π write(a);{nothing happens here}             {write to textscreen}πend.ππ                                        78     02-03-9416:17ALL                      OLAF BARTELT             Loading PCX Files        IMPORT              24     ╓rΓ {ππ SL> Does someone has a pascalsource for showing a PCX file with a resolutionπ SL> of 640x400x256 /or a automatic build-in convertor who wil let the drawingππSure thing, the following code will load PCX files with 256 colors and variableπheight and width (it looks into the header):  (Sorry about the german comments,πbut I've got no time to erase them right now :-(( ) }ππUNIT uVESAPcx;                                { (c) 1993 by NEBULA-Software }π     { PCX-Darstellungsroutinen f. VESA     } { Olaf Bartelt & Oliver Carow }ππINTERFACE                                     { Interface-Teil der Unit     }ππ{ ───────────────────────────────── Typen ───────────────────────────────── }πTYPE  pVESAPcx   = ^tVESAPcx;                 { Zeiger auf Objekt           }π      tVESAPcx   = OBJECT                     { Objekt für PCX-Dateien      }π                     PROCEDURE load(f : STRING; dx, dy : WORD);π                   END;ππ{ ──────────────────────────────── Variablen ────────────────────────────── }πVAR   vVESAPcx  : pVESAPcx;                   { Instanz des Objekts tPcx    }πππIMPLEMENTATION                                { Implementation-Teil d. Unit }ππUSES uVesa;                                   { Einbinden der Units         }π{ CAN BE FOUND IN SWAG }ππ{ ──────────────────────────────── tVESAPcx ─────────────────────────────── }πPROCEDURE  tVESAPcx.load(f : STRING; dx, dy : WORD);πVAR q                          : FILE;π    b                          : ARRAY[0..2047] OF BYTE;π    anz, pos, c, w, h, e, pack : WORD;π    x, y                       : WORD;ππLABEL ende_background;ππBEGINπ  x := 0; y := 0;ππ  ASSIGN(q, f); {$I-} RESET(q, 1); {$I+}π  IF IORESULT <> 0 THENπ    GOTO ende_background;ππ  BLOCKREAD(q, b, 128, anz);π  IF (b[0] <> 10) OR (b[3] <> 8) THENπ  BEGINπ    CLOSE(q);π    EXIT;π  END;π  w := SUCC((b[9] - b[5]) SHL 8 + b[8] - b[4]);π  h := SUCC((b[11] - b[7]) SHL 8 + b[10] - b[6]);π  pack := 0; c := 0; e := y + h;π  REPEATπ    BLOCKREAD(q, b, 2048, anz);π    pos := 0;π    WHILE (pos < anz) AND (y < e) DOπ    BEGINπ      IF pack <> 0 THENπ      BEGINπ        FOR c := c TO c + pack DOπ          vVesa^.putpixel(x + c+dx, y+dy, b[pos]);π        pack := 0;π      ENDπ      ELSEπ        IF (b[pos] AND $C0) = $C0 THENπ          pack := b[pos] AND $3Fπ        ELSEπ        BEGINπ          vVesa^.putpixel(x + c+dx, y+dy, b[pos]);π          INC(c);π        END;π      INC(pos);π      IF c = w THENπ      BEGINπ        c := 0;π        INC(y);π      END;π    END;π  UNTIL (anz = 0) OR (y = e);π  SEEK(q, FILESIZE(q) - 3 SHL 8 - 1);π  BLOCKREAD(q, b, 3 SHL 8 + 1);π  IF b[0] = 12 THENπ    FOR x := 1 TO 3 SHL 8 + 1 DOπ      b[x] := b[x] SHR 2;π  CLOSE(q);ππ  ende_background:πEND;πππ{ ────────────────────────────── Hauptprogramm ──────────────────────────── }πBEGINπ  NEW(vVESAPcx);πEND.ππRemember to put in *your* putpixel routines there!ππscroll from top till bottom.(VGA/SVGAcompat./TPASCAL6.0)ππ     79     02-03-9416:18ALL                      DON LABARRE              Making VGA Rain          IMPORT              13     ╓c
  3.  {πIt's not often that I post anything but since I started getting into it Iπfigured I'd post something worth while. Heres some code I wrote to produce someπ"blood" rain. It isn't much but it's cool to look at :)ππ{This code is release freely to anyone that wants it. I couldn't care lessπ what you do with it. It is being used in my demo so if I see it in yoursπ i will find you and kill you. Nemesis 1994}ππprogram rain;πvar p:integer;ππfunction keypressed : boolean; assembler; asmπ  mov ah,0bh; int 21h; and al,0feh; end;ππProcedure RotatePal;πVar a:Word;πBeginπ  inc(p);π  port[968]:=35;π  a:=100;ππ  while port[$3da] and 8 <> 0 do;π  while port[$3da] and 8 = 0 do;ππ  while a>1 doπ  beginπ    port[969]:=1-((a+p) and 60);π    port[969]:=0;π    {If you want a better palette selection and more play then removeπ     the above line and replace with the one below. It will allow youπ     to get to the blues and greens and yellows but I made mine red soπ     did not require those}π    {port[969]:=1-((a+p) and 60);}π    port[969]:=1-((a+p) and 65);π    dec(a);π    end;πend;ππProcedure makerain;πVarπ  x,y,c,d:word;πbeginπ  d:=1;π  randomize;π  for x:=0 to 320 doπ  Beginπ    c:=random(65);π    for y:=0 to 200 doπ    Beginπ      if c>64 then c:=1;π      mem[$a000:x+320*y]:=c+35;π      inc(c,d);π    end;π    d:=random(5)+1;π  end;πend;πππbeginπasmπ  mov ax,$0013π  int 10hπ  end;πmakerain;πrepeatπRotatePal;πuntil keypressed;πasmπ  mov ax,$0002π  int 10hπend;πend.ππ                                                                 80     02-03-9416:19ALL                      BAS VAN GAALEN           Vector coding            IMPORT              39     ╓╠     π{$g+}πprogram rotationalfield;π{ Source by Bas van Gaalen, Holland, PD }πuses crt,dos;πconstπ  gseg : word = $a000;π  dots = 459;π  dist : word = 250;π  sintab : array[0..255] of integer = (π    0,3,6,9,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,60,63,66,68,π    71,74,76,79,81,84,86,88,91,93,95,97,99,101,103,105,106,108,110,111,π    113,114,116,117,118,119,121,122,122,123,124,125,126,126,127,127,127,π    128,128,128,128,128,128,128,127,127,127,126,126,125,124,123,122,122,π    121,119,118,117,116,114,113,111,110,108,106,105,103,101,99,97,95,93,π    91,88,86,84,81,79,76,74,71,68,66,63,60,58,55,52,49,46,43,40,37,34,31,π    28,25,22,19,16,13,9,6,3,0,-3,-6,-9,-13,-16,-19,-22,-25,-28,-31,-34,π    -37,-40,-43,-46,-49,-52,-55,-58,-60,-63,-66,-68,-71,-74,-76,-79,-81,π    -84,-86,-88,-91,-93,-95,-97,-99,-101,-103,-105,-106,-108,-110,-111,π    -113,-114,-116,-117,-118,-119,-121,-122,-122,-123,-124,-125,-126,π    -126,-127,-127,-127,-128,-128,-128,-128,-128,-128,-128,-127,-127,π    -127,-126,-126,-125,-124,-123,-122,-122,-121,-119,-118,-117,-116,π    -114,-113,-111,-110,-108,-106,-105,-103,-101,-99,-97,-95,-93,-91,π    -88,-86,-84,-81,-79,-76,-74,-71,-68,-66,-63,-60,-58,-55,-52,-49,π    -46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-13,-9,-6,-3);πtypeπ  dotrec = record x,y,z : integer; end;π  dotpos = array[0..dots] of dotrec;πvar dot : dotpos;ππ{----------------------------------------------------------------------------}ππprocedure setpal(col,r,g,b : byte); assembler; asmπ  mov dx,03c8h; mov al,col; out dx,al; inc dx; mov al,rπ  out dx,al; mov al,g; out dx,al; mov al,b; out dx,al; end;ππprocedure setvideo(mode : word); assembler; asmπ  mov ax,mode; int 10h end;ππfunction esc : boolean; beginπ  esc := port[$60] = 1; end;ππ{----------------------------------------------------------------------------}ππprocedure init;πvar i : word; x,z : integer;πbeginπ  i := 0;π  z := -100;π  while z < 100 do beginπ    x := -100;π    while x < 100 do beginπ      dot[i].x := x;π      dot[i].y := -45;π      dot[i].z := z;π      inc(i);π      inc(x,10);π    end;π    inc(z,9);π  end;π  for i := 0 to 63 do setpal(i,0,i,i);πend;ππ{----------------------------------------------------------------------------}ππprocedure rotation;πconst yst = 1;πvarπ  xp : array[0..dots] of word;π  yp : array[0..dots] of byte;π  x,z : integer; n : word; phiy : byte;πbeginπ  asm mov phiy,0; mov es,gseg; cli; end;π  repeatπ    asmπ      mov dx,03dahπ     @l1:π      in al,dxπ      test al,8π      jnz @l1π     @l2:π      in al,dxπ      test al,8π      jz @l2π    end;π    setpal(0,0,0,10);π    for n := 0 to dots do beginπ      asmπ        mov si,nπ        mov al,byte ptr yp[si]π        cmp al,200π        jae @skipπ        shl si,1π        mov bx,word ptr xp[si]π        cmp bx,320π        jae @skipπ        shl ax,6π        mov di,axπ        shl ax,2π        add di,axπ        add di,bxπ        xor al,alπ        mov [es:di],alπ       @skip:π      end;ππ      x := (sintab[(phiy+192) mod 255] * dot[n].xπ     {^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ ^^^^^^^^π      9     1                          3 2 }ππ            - sintab[phiy] * dot[n].z) div 128;π          { ^ ^^^^^^^^^^^^ ^ ^^^^^^^^  ^^^^^^^π            7 4            6 5         8 }ππ      (*π      asmπ        xor ah,ah                      { 1 }π        mov al,phiyπ        add al,192π        mov si,axπ        mov ax,word ptr sintab[si]π        mov si,n                       { 2 }π        mov dx,word ptr dot[si].xπ        mul dx                         { 3 }π        mov cx,axπ        mov dx,word ptr dot[si].z      { 5 }π        mov al,phiy                    { 4 }π        mov si,axπ        mov ax,word ptr sintab[si]π        mul dx                         { 6 }π        sub cx,ax                      { 7 }π        shr cx,7                       { 8 }π        mov x,cx                       { 9 }π      end;π      *)ππ      z := (sintab[(phiy+192) mod 255]*dot[n].z+sintab[phiy]*dot[n].x) div 128;π      xp[n] := 160+(x*dist) div (z-dist);π      yp[n] := 100+(dot[n].y*dist) div (z-dist);ππ      {π      asmπ        mov ax,xπ        mov dx,distπ        mul dxπ        mov dx,zπ        sub dx,distπ        div dxπ        add ax,160ππ        (* can't assign ax to xp[n] !? *)ππ      end;π      }ππ      asmπ        mov si,nπ        mov al,byte ptr yp[si]π        cmp al,200π        jae @skipπ        shl si,1π        mov bx,word ptr xp[si]π        cmp bx,320π        jae @skipπ        shl ax,6π        mov di,axπ        shl ax,2π        add di,axπ        add di,bxπ        mov ax,zπ        shr ax,3π        add ax,30π        mov [es:di],alπ       @skip:π      end;π    end;π    asm inc phiy end;π    setpal(0,0,0,0);π  until esc;π  asm sti end;πend;ππ{----------------------------------------------------------------------------}ππbeginπ  setvideo($13);π  Init;π  rotation;π  textmode(lastmode);πend.π        81     02-05-9407:56ALL                      BAS VAN GAALEN           Moving landscape         IMPORT              41     ╓╞ π{ NEEDS A MOUSE !!!πAnd here as promised to several fellows, the moving landscape!πIt needs a mouse, as you can see...πAgain nothing realy nifty (imho), no bankswitching, no mode-x, no virtualπscreens, no palette tricks, just some hard math! ;-) Have fun with it...ππ--- cut here ---}ππprogram landscape_2d;π{ 2D landscape (without rotating). Made by Bas van Gaalen, Holland, PD }πconstπ  vseg = $a000;π  a_density = 4;π  roughness = 20;π  maxx_scape = 320; maxy_scape = 200;π  maxh = 128;π  maxx = 250 div a_density; maxy = 110 div a_density;πvar landscape : array[0..maxx_scape*maxy_scape] of byte;ππ{ mouse routines ------------------------------------------------------------}ππfunction mouseinstalled : boolean; assembler; asmπ  xor ax,ax; int 33h; cmp ax,-1; je @skip; xor al,al; @skip: end;ππfunction getmousex : word; assembler; asmπ  mov ax,3; int 33h; mov ax,cx end;ππfunction getmousey : word; assembler; asmπ  mov ax,3; int 33h; mov ax,dx end;ππfunction leftpressed : boolean; assembler; asmπ  mov ax,3; int 33h; and bx,1; mov ax,bx end;ππprocedure mousesensetivity(x,y : word); assembler; asmπ  mov ax,1ah; mov bx,x; mov cx,y; xor dx,dx; int 33h end;ππprocedure mousewindow(l,t,r,b : word); assembler; asmπ  mov ax,7; mov cx,l; mov dx,r; int 33h; mov ax,8π  mov cx,t; mov dx,b; int 33h end;ππ{ lowlevel video routines ---------------------------------------------------}ππprocedure setvideo(m : word); assembler; asmπ  mov ax,m; int 10h end;ππprocedure putpixel(x,y : word; c : byte); assembler; asmπ  mov ax,vseg; mov es,ax; mov ax,y; mov dx,320; mul dxπ  mov di,ax; add di,x; mov al,c; mov [es:di],al end;ππfunction getpixel(x,y : word) : byte; assembler; asmπ  mov ax,vseg; mov es,ax; mov ax,y; mov dx,320; mul dxπ  mov di,ax; add di,x; mov al,[es:di] end;ππprocedure setpal(c,r,g,b : byte); assembler; asmπ  mov dx,03c8h; 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;ππprocedure retrace; assembler; asmπ  mov dx,03dah; @l1: in al,dx; test al,8; jnz @l1π  @l2: in al,dx; test al,8; jz @l2 end;ππ{ initialize palette colors -------------------------------------------------}ππprocedure initcolors;πvar i : byte;πbeginπ  for i := 0 to 63 do beginπ    setpal(i+1,21+i div 3,21+i div 3,63-i);π    setpal(i+65,42-i div 3,42+i div 3,i div 3);π  end;πend;ππ{ landscape generating routines ---------------------------------------------}ππprocedure adjust(xa,ya,x,y,xb,yb : integer);πvar d,c : integer;πbeginπ  if getpixel(x,y) <> 0 then exit;π  d := abs(xa-xb)+abs(ya-yb);π  c := (50*(getpixel(xa,ya)+getpixel(xb,yb))+trunc((10*random-5)*d*roughness))πdiv 100;π  if c < 1 then c := 1;π  if c >= maxh then c := maxh;π  putpixel(x,y,c);πend;ππprocedure subdivide(l,t,r,b : integer);πvar x,y : integer; c : integer;πbeginπ  if (r-l < 2) and (b-t < 2) then exit;π  x := (l+r) div 2; y := (t+b) div 2;π  adjust(l,t,X,t,r,t);π  adjust(r,t,r,Y,r,b);π  adjust(l,b,X,b,r,b);π  adjust(l,t,l,Y,l,b);π  if getpixel(x,y) = 0 then beginπ    c := (getpixel(l,t)+getpixel(r,t)+getpixel(r,b)+getpixel(l,b)) div 4;π    putpixel(x,y,c);π  end;π  subdivide(l,t,x,y);π  subdivide(x,t,r,y);π  subdivide(l,y,x,b);π  subdivide(x,y,r,b);πend;ππprocedure generatelandscape;πvar image : file; vidram : byte absolute vseg:0000; i : word;πbeginπ  assign(image,'plasma.img');π  {$I-} reset(image,1); {$I+}π  if ioresult <> 0 then beginπ    randomize;π    putpixel(0,0,random(maxh));π    putpixel(maxx_scape-1,0,random(maxh));π    putpixel(maxx_scape-1,maxy_scape-1,random(maxh));π    putpixel(0,maxy_scape-1,random(maxh));π    subdivide(0,0,maxx_scape,maxy_scape);π    rewrite(image,1);π    blockwrite(image,mem[vseg:0],maxx_scape*maxy_scape);π  end else blockread(image,mem[vseg:0],maxx_scape*maxy_scape);π  close(image);π  move(vidram,landscape,sizeof(landscape));π  fillchar(vidram,maxx_scape*maxy_scape,0);π  for i := 0 to maxx_scape*maxy_scape-1 do landscape[i] := 110+Landscape[i] divπ2;πend;ππ{ the actual displaying of the whole thing! ---------------------------------}ππprocedure displayscape;πvar i,j,previ,prevj,n : word; x : integer;πbeginπ  i := 0; j := 0;π  repeatπ    {retrace;}π    previ := i; i := getmousex; prevj := j; j := getmousey;π    for n := 0 to maxx*maxy-1 do beginπ      x := -(a_density*(integer(n mod maxx)-(maxx shr 1)-1)*45) div (integer(nπdiv maxx)-45)-90;π      if (x >= -250) and (X <= 60) then beginπ        mem[vseg:320*(a_density*integer(n div maxx)-landscape[n modπmaxx+previ+(n div maxx+prevj)*maxx_scape])+x] := 0;π        mem[vseg:320*(a_density*integer(n div maxx)-landscape[n mod maxx+i+(nπdiv maxx+j)*maxx_scape])+x] :=π          landscape[(integer(n mod maxx)+i)+(integer(n divπmaxx)+j)*maxx_scape]-100;π      end;π    end;π  until leftpressed;πend;ππ{ main routine --------------------------------------------------------------}ππbeginπ  if mouseinstalled then beginπ    setvideo($13);π    initcolors;π    generatelandscape;π    mousewindow(0,0,maxx_scape-maxx,maxy_scape-maxy);π    mousesensetivity(25,25);π    displayscape;π    setvideo(3);π  end else writeln('This interactive thing realy needs a mouse...');πend.ππ                        82     02-09-9411:50ALL                      DAVID DAHL               CheckerBoard             IMPORT              46     ╓"¢ πProgram CheckerBoard;ππ{=============================================ππ             CheckerBoard Exampleπ           Programmed by David Dahlπ                  01/06/94π   This program and source are PUBLIC DOMAINππ ---------------------------------------------ππ   This program is an example of how to makeπ   a moving 3D checkerboard pattern on theπ   screen like many demos do.ππ   This program requires VGA.ππ =============================================}ππUses CRT;ππConst TileMaxX = 10;  { Horiz Size Of Tile }π      TileMaxY = 10;  { Vert Size Of Tile }ππ      ViewerDist = 400;  { Distance Of Viewer From Screen }ππType TileArray = Array [0..TileMaxX-1, 0..TileMaxY-1] of Byte;ππ     PaletteRec  = Recordπ                         Red,π                         Green,π                         Blue  : Byte;π                   End;π     PaletteType = Array[0..255] of PaletteRec;πππVar Tile    : TileArray;π    TilePal : PaletteType;ππProcedure GoMode13; Assembler;πASMπ   MOV AX, $0013π   INT $10πEnd;ππ{-[ Set Value Of All DAC Registers ]--------------------------------------}πProcedure SetPalette (Var PalBuf : PaletteType); Assembler;πAsmπ    PUSH DSππ    XOR AX, AXπ    MOV CX, 0300h / 2π    LDS SI, PalBufππ    MOV DX, 03C8hπ    OUT DX, ALππ    INC DXπ    MOV BX, DXπ    CLDππ    MOV DX, 03DAhπ    @VSYNC0:π      IN   AL, DXπ      TEST AL, 8π    JZ @VSYNC0ππ    MOV DX, BXπ    repπ       OUTSBππ    MOV BX, DXπ    MOV CX, 0300h / 2πππ    MOV DX, 03DAhπ    @VSYNC1:π      IN   AL, DXπ      TEST AL, 8π    JZ @VSYNC1ππ    MOV DX, BXπ    REPπ       OUTSBππ    POP DSπEnd;π{-[ Get Value Of All DAC Registers ]--------------------------------------}πProcedure GetPalette (Var PalBuf : PaletteType); Assembler;πAsmπ    PUSH DSππ    XOR AX, AXπ    MOV CX, 0300hπ    LES DI, PalBufππ    MOV DX, 03C7hπ    OUT DX, ALπ    INC DXππ    REPπ       INSBππ    POP DSπEnd;π{-[ Only Set DAC Regs 1 Through (TileMaxX * TileMaxY) ]-------------------}πProcedure SetTileColors (Var PalBuf : PaletteType); Assembler;πASMπ   PUSH DSππ   MOV CX, TileMaxX * TileMaxY * 3π   MOV AX, 1π   LDS SI, PalBufπ   INC SIπ   INC SIπ   INC SIπ   MOV DX, 03C8hπ   OUT DX, ALπ   INC DXπ   MOV BX, DXππ   MOV DX, 03DAhπ   @VSYNC0:π     IN   AL, DXπ     TEST AL, 8π   JZ @VSYNC0ππ   MOV DX, BXπ   REPπ      OUTSBππ   POP DSπEnd;π{-[ Define The Bitmap Of The Tile ]---------------------------------------}πProcedure DefineTile;πVar CounterX,π    CounterY  : Word;πBeginπ     For CounterY := 0 to TileMaxY-1 doπ         For CounterX := 0 to TileMaxX-1 doπ             Tile[CounterX, CounterY] := 1 + CounterX +π                                         (CounterY * TileMaxX);πEnd;π{-[ Define The Colors Of The Tile ]---------------------------------------}πProcedure DefinePalette;πVar PalXCounter : Byte;π    PalYCounter : Byte;π    PalSize     : Byte;πBeginπ     GetPalette (TilePal);ππ     PalSize := (TileMaxX * TileMaxY);ππ     For PalYCounter := 1 to PalSize doπ     With TilePal[PalYCounter] doπ     Beginπ          Red   := 0;π          Green := 0;π          Blue  := 63;π     End;ππ     For PalYCounter := 0 to ((TileMaxY - 1) DIV 2) doπ         For PalXCounter := 0 to ((TileMaxX - 1) DIV 2) doπ         Beginπ              With TilePal[1 + PalXCounter + (PalYCounter*TileMaxX)] doπ              Beginπ                   Red   := 63;π                   Green := 63;π                   Blue  := 63;π              End;ππ              With TilePal[1 + (TileMaxX DIV 2) +π                               PalXCounter +π                               ((TileMaxY DIV 2) * TileMaxX) +π                               (PalYCounter*TileMaxX)] doπ              Beginπ                   Red   := 63;π                   Green := 63;π                   Blue  := 63;π              End;π         End;ππEnd;π{-[ Display Tiles On Screen ]---------------------------------------------}πProcedure DisplayCheckerBoard;πVar CounterX,π    CounterY  : Integer;ππ    X,π    Y,π    Z         : LongInt;πBeginπ     For CounterY := 110 to 199 doπ     Beginπ          Z := -1600 + (CounterY * 16) + ViewerDist;ππ          If Z = 0 THEN Z :=1;ππ          For CounterX := 0 to 319 doπ          Beginππ               X := 159 + (longInt(CounterX - 159 ) * ViewerDist) DIV Z;ππ               Y := (LongInt(CounterY + 100) * ViewerDist) DIV Z;ππ               MEM[$A000:CounterX + (CounterY * 320)] :=π                   Tile[X MOD TileMaxX, Y MOD TileMaxY]π          End;π     End;ππEnd;π{-[ Rotate The Palette Of The Board To Give Illusion Of Movement Over It ]-}πProcedure MoveForwardOverBoard;πType  TempPalType = Array[1..TileMaxX] of PaletteRec;πVar   TempPal     : TempPalType;π      CounterX,π      CounterY    : Word;πBeginπ     For CounterX := 1 to TileMaxX doπ         TempPal[CounterX] := TilePal[CounterX];ππ     For CounterY := 0 to (TileMaxY-1) doπ         For CounterX := 0 to (TileMaxX-1) doπ             TilePal[1 + CounterX + (CounterY * TileMaxX)] :=π                    TilePal[1 + CounterX + ((CounterY+1) * TileMaxX)];ππ     For CounterX := 1 to TileMaxX doπ         TilePal[CounterX + ((TileMaxY-1) * TileMaxX)] :=π                TempPal[CounterX];πEnd;π{-[ Flush the Keyboard Buffer ]--------------------------------------------}πProcedure FlushKeyboard;πVar Key : Char;πBeginπ     While KeyPressed doπ           Key := ReadKey;πEnd;ππ{=[ Main Program ]=========================================================}πBeginππ     GoMode13;π     DefineTile;π     DefinePalette;ππ     SetPalette(TilePal);ππ     DisplayCheckerboard;ππ     FlushKeyboard;ππ     Repeatπ           MoveForwardOverBoard;π           SetTileColors(TilePal);π     Until KeyPressed;ππ     FlushKeyboard;ππ     TextMode(C80);πEnd.π                                                                                           83     02-18-9406:59ALL                      LENNERT BAKKER           Textmode Effects         IMPORT              128    ╓   π{Hi Dudes...ππDunno if you can do anything with this code; It sure is crappy!πAnywayzz, this kinda looks nice on my computer but I'm not sureπon how the timing will be on other systems... Might cause aπhelluvalot of flicker...ππWell, what can I say? Have Phun 8-)}ππProgram LooksLikeSomeTextModeEffectsToMe_YeahIGuessSo;ππ{$X+,E-,N-,I-,S-,R-,O-}ππType BigChar=Array[1..3,1..3] of Byte;π     MoveRecord = Recordπ                   XPos,YPos : Integer;π                   XSpeed,YSpeed : Integer;π                   Counter : Word;π                  End;ππConst BigFont : Array[1..40] of BigChar = (π      ((192,196,182),(195,196,191),(188,032,188)), {A}π      ((192,196,182),(195,196,191),(193,196,183)), {B}π      ((192,196,190),(187,032,032),(193,196,190)), {C}π      ((192,190,187),(187,032,187),(193,196,183)), {D}π      ((192,196,190),(195,190,032),(193,196,190)), {E}π      ((192,196,190),(195,190,032),(188,032,032)), {F}π      ((192,196,190),(187,194,182),(193,196,183)), {G}π      ((189,032,189),(195,196,191),(188,032,188)), {H}π      ((194,196,190),(032,187,032),(194,196,190)), {I}π      ((192,196,182),(195,196,191),(188,032,198)), {J}π      ((192,196,182),(195,196,191),(188,032,198)), {K}π      ((189,032,032),(187,032,032),(193,196,190)), {L}π      ((192,196,182),(187,189,187),(188,188,188)), {M}π      ((192,196,182),(187,032,187),(188,032,188)), {N}π      ((192,196,182),(187,032,187),(193,196,183)), {O}π      ((192,196,182),(187,032,187),(187,194,183)), {P}π      ((192,196,182),(195,196,191),(188,032,198)), {Q}π      ((192,196,182),(195,196,198),(188,032,197)), {R}π      ((192,196,190),(193,196,182),(194,196,183)), {S}π      ((194,196,190),(032,187,032),(032,188,032)), {T}π      ((189,032,189),(187,032,187),(193,196,183)), {U}π      ((189,032,187),(188,032,187),(194,196,183)), {V}π      ((189,189,189),(187,188,187),(193,196,183)), {W}π      ((189,032,189),(192,196,183),(188,032,187)), {X}π      ((189,032,189),(193,196,183),(032,188,032)), {Y}π      ((192,196,182),(195,196,191),(188,032,198)), {Z}π      ((032,032,032),(032,032,032),(185,185,185)), {...}π      ((032,187,032),(032,188,032),(032,185,032)), {!}π      ((192,196,182),(187,186,187),(193,196,183)), {0}π      ((194,182,032),(032,187,032),(194,196,190)), {1}π      ((194,196,182),(192,196,183),(193,196,190)), {2}π      ((194,196,182),(032,194,191),(194,196,183)), {3}π      ((189,032,189),(193,196,191),(032,032,188)), {4}π      ((192,196,190),(193,196,182),(194,196,183)), {5}π      ((192,196,190),(195,196,182),(193,196,183)), {6}π      ((194,196,182),(032,032,187),(032,032,188)), {7}π      ((192,196,182),(195,196,191),(193,196,183)), {8}π      ((192,196,182),(193,196,191),(194,196,183)), {9}π      ((032,032,032),(194,196,190),(032,032,032)), {-}π      ((032,032,032),(032,032,032),(032,032,032)));{ }ππ      ScrWidth : Word = 160;π      StartDat : Array[0..15] of Byte = (8,0,1,2,3,4,5,6,7,6,5,4,3,2,1,0);π      BarRes   = 270;π      BarRad   = 260 Div 2;π      Mes      : String = '';ππ      ScrollMessage : String = 'Hi there possoms! howst hanging. How about some simple TextMode Scroller.    ';π      ScrollOfs     : Byte = 9;π      ScrollPos     : Byte = 0;π      CharOfs       : Byte = 2;πππVar BarCols  : Array[0..399] of Byte;π    Bars     : Array[1..4] of Recordπ                               StartCol : Byte;π                               YPos     : Integer;π                              End;π    BarPos   : Array[1..BarRes] of Integer;π    MyPal    : Array[0..767] of Byte;π    MoveMes,MoveSplit : MoveRecord;ππProcedure CharMap; Assembler;πAsmπ  db      0,0,0,0,0,0,192,240,248,252,252,60,60,60,60,60           {┐}π  db      60,60,60,60,60,252,252,248,240,192,0,0,0,0,0,0           {┘}π  db      24,60,60,60, 60,60,60,60, 60,60,60,24, 0,0,0,0π  db      0,0,0,0, 60,126,255,255, 255,255,126,60, 0,0,0,0π  db      96,240,240,248, 248,120,124,60, 60,62,30,31, 31,15,15,6π  db      60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60π  db      60,60,60,60,60,60,60,60,60,60,60, 24, 0,0,0,0π  db      0,0,0,0, 24,60,60,60,60,60,60,60,60,60,60,60π  db      0,0,0,0,0,0,254,255,255,254,0,0,0,0,0,0           {->}π  db      60,60,60,60,60,124,252,252,252,252,124,60,60,60,60,60π  db      0,0,0,0,0,0,3,15,31,63,62,62,60,60,60,60          {┌}π  db      60,60,60,60,62,62,63,31,15,3,0,0,0,0,0,0          {└}π  db      0,0,0,0,0,0,127,255,255,127,0,0,0,0,0,0           {<-}π  db      60,60,60,60,60,62,63,63, 63,63,62,60, 60,60,60,60 {├}π  db      0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0           {─}π  db      240,120,120,120,120,120,60,60, 60,60,60,24, 0,0,0,0   {\}π  db      60,60,60,60,60,252,252,248,240,224,224,240,240,240,240,240πEnd;ππProcedure SetCharset; Assembler;πAsmπ Push Bpπ mov ax,cs                       { Set character set for logo }π mov es,axπ mov bp,cs:offset charmapπ mov ax,1100hπ mov bx,1000hπ mov cx,17π mov dx,182π int 10hπ Pop BpπEnd;ππProcedure Standard_Palette; Assembler;  { DP ][ Ext. Compatible }πAsmπdb 0,0,0,0,0,42,0,42,0,0,42,42,42,0,0,42,0,42,42,21,0,42,42πdb 42,21,21,21,21,21,63,21,63,21,21,63,63,63,21,21,63,21,63,63,63,21,63πdb 63,63,59,59,59,55,55,55,52,52,52,48,48,48,45,45,45,42,42,42,38,38,38πdb 35,35,35,31,31,31,28,28,28,25,25,25,21,21,21,18,18,18,14,14,14,11,11πdb 11,8,8,8,63,0,0,59,0,0,56,0,0,53,0,0,50,0,0,47,0,0,44πdb 0,0,41,0,0,38,0,0,34,0,0,31,0,0,28,0,0,25,0,0,22,0,0πdb 19,0,0,16,0,0,63,54,54,63,46,46,63,39,39,63,31,31,63,23,23,63,16πdb 16,63,8,8,63,0,0,63,42,23,63,38,16,63,34,8,63,30,0,57,27,0,51πdb 24,0,45,21,0,39,19,0,63,63,54,63,63,46,63,63,39,63,63,31,63,62,23πdb 63,61,16,63,61,8,63,61,0,57,54,0,51,49,0,45,43,0,39,39,0,33,33πdb 0,28,27,0,22,21,0,16,16,0,52,63,23,49,63,16,45,63,8,40,63,0,36πdb 57,0,32,51,0,29,45,0,24,39,0,54,63,54,47,63,46,39,63,39,32,63,31πdb 24,63,23,16,63,16,8,63,8,0,63,0,0,63,0,0,59,0,0,56,0,0,53πdb 0,1,50,0,1,47,0,1,44,0,1,41,0,1,38,0,1,34,0,1,31,0,1πdb 28,0,1,25,0,1,22,0,1,19,0,1,16,0,54,63,63,46,63,63,39,63,63πdb 31,63,62,23,63,63,16,63,63,8,63,63,0,63,63,0,57,57,0,51,51,0,45πdb 45,0,39,39,0,33,33,0,28,28,0,22,22,0,16,16,23,47,63,16,44,63,8πdb 42,63,0,39,63,0,35,57,0,31,51,0,27,45,0,23,39,54,54,63,46,47,63πdb 39,39,63,31,32,63,23,24,63,16,16,63,8,9,63,0,1,63,0,0,63,0,0πdb 59,0,0,56,0,0,53,0,0,50,0,0,47,0,0,44,0,0,41,0,0,38,0πdb 0,34,0,0,31,0,0,28,0,0,25,0,0,22,0,0,19,0,0,16,60,54,63πdb 57,46,63,54,39,63,52,31,63,50,23,63,47,16,63,45,8,63,42,0,63,38,0πdb 57,32,0,51,29,0,45,24,0,39,20,0,33,17,0,28,13,0,22,10,0,16,63πdb 54,63,63,46,63,63,39,63,63,31,63,63,23,63,63,16,63,63,8,63,63,0,63πdb 56,0,57,50,0,51,45,0,45,39,0,39,33,0,33,27,0,28,22,0,22,16,0πdb 16,63,58,55,63,56,52,63,54,49,63,53,47,63,51,44,63,49,41,63,47,39,63πdb 46,36,63,44,32,63,41,28,63,39,24,60,37,23,58,35,22,55,34,21,52,32,20πdb 50,31,19,47,30,18,45,28,17,42,26,16,40,25,15,39,24,14,36,23,13,34,22πdb 12,32,20,11,29,19,10,27,18,9,23,16,8,21,15,7,18,14,6,16,12,6,14πdb 11,5,10,8,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0πdb 0,0,0,0,0,0,49,10,10,49,19,10,49,29,10,49,39,10,49,49,10,39,49πdb 10,29,49,10,19,49,10,10,49,12,10,49,23,10,49,34,10,49,45,10,42,49,10πdb 31,49,10,20,49,11,10,49,22,10,49,33,10,49,44,10,49,49,10,43,49,10,32πdb 49,10,21,49,10,10,63,63,63πEnd;ππFunction KeyPressed : Boolean; Assembler;πAsmπ Mov Ah,0Bhπ Int 21hπEnd;ππProcedure WriteBigMessage(X,Y,Color:Byte; Message:String);πVar B,D    : Byte;π    ScrOfs : Word;ππConst TransTab : Array[0..255] of Byte =π      (32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, {15}π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, {31}π       40,28,32,32,32,32,32,32,32,32,32,32,32,39,27,32, {47}π       29,30,31,32,33,34,35,36,37,38,32,32,32,32,32,32, {63}π       32, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, {79}π       16,17,18,19,20,21,22,23,24,25,26,32,32,32,32,32, {95}π       32, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, {111}π       16,17,18,19,20,21,22,23,24,25,26,32,32,32,32,32, {127}π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,π       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32);ππBeginπ Mes:=Message;π D:=Length(Mes);π If D=0 then Exit;π ScrOfs:=(Y-1)*ScrWidth+2*X+2;ππ  Asmπ    Mov Ax,$B800              { Set starting address on screen }π    Mov Es,Axπ    Mov Di,ScrOfsππ    Mov B,1                   { Start with first character ;-) }π   @StringLoop:π    Xor Bh,Bhπ    Mov Bl,Bπ    Mov Al,Ds:[Offset Mes+Bx] { Get Next Character from String }π    Mov Bx,Offset TransTabπ    XLat                      { And translate into real value }ππ    Dec Alπ    Mov Bl,9π    Mul Blπ    Mov Si,Offset BigFont     { Character offset in Font-Table }π    Add Si,Axππ    Mov Ah,Colorπ    Mov Dx,3π   @FontColumn:               { Loop three Rows... }π    Mov Cx,3π   @FontRow:                  { and three columns }π    LodsBπ    StosWπ    Loop @FontRowπ    Add Di,ScrWidthπ    Sub Di,6π    Dec Dxπ    Jnz @FontColumnππ    Mov Ax,3                  { prepare screen address for next character }π    Mul ScrWidthπ    Sub Di,Axπ    Add Di,8ππ    Inc Bπ    Mov Al,Dπ    Cmp B,Alπ    Jng @StringLoopπ   End;πEnd;ππProcedure WriteCenteredBig(Y,Color:Byte; Message:String);πBeginπ WriteBigMessage(((ScrWidth Div 4)+2)-(Length(Message)*2),Y,Color,Message);πEnd;ππProcedure MakePal;πVar A:Word;πBeginπ For A:=0 to 255 doπ  Beginπ   Mypal[A]:=Mem[Seg(Standard_Palette):Ofs(Standard_Palette)+A*3];π   Mypal[A+256]:=Mem[Seg(Standard_Palette):Ofs(Standard_Palette)+A*3+1];π   Mypal[A+512]:=Mem[Seg(Standard_Palette):Ofs(Standard_Palette)+A*3+2];π  End;πEnd;ππProcedure SetupBars;πVar V : Integer;πBeginπ  For V:=1 To BarRes Doπ   BarPos[V]:=Round(BarRad*Sin((2*Pi/BarRes)*V))+BarRad+1;π For V:=1 to 4 doπ  With Bars[V] doπ   Beginπ    StartCol:=V*16;π    if v=3 then startcol:=96;π    if v=4 then startcol:=144;π    if v=5 then startcol:=160;π    YPos:=14*V;π   End;π For V:=304 to 319 do Barcols[V]:=(15-(V mod 16))+160;π For V:=320 to 335 do Barcols[V]:=V mod 16+160;πEnd;ππProcedure UpdateBars;πVar V,U,Y : Integer;πBeginπ  For V:=1 To 4 doπ   For U:=0 to 31 do BarCols[barpos[Bars[V].YPos]+U]:=0;π For V:=1 To 4 doπ  Beginπ   Inc(Bars[V].YPos);π    If Bars[V].YPos>BarRes then Bars[V].YPos:=1;π   Y:=BarPos[Bars[V].YPos];π   For U:=0 to 15 do BarCols[Y+U]:=Bars[V].StartCol+15-U;π   For U:=16 to 31 do BarCols[Y+U]:=Bars[V].StartCol+U-16;π  End;πEnd;ππProcedure ColorBars; Assembler;πAsmπ  MOV DX,$03DAπ  In AL,DXπ  MOV DX,$03C0   { assume color nr 0 = default Text background.. }π  MOV AL,$20+0   { set color nr 0 .. }π  OUT DX,ALπ  MOV AL,0       { .. to DAC color 0 }π  OUT DX,ALππ  Xor SI,SIπ  CLIπ  MOV DX,$03DAπ  MOV AH,8π@Wau: in AL,DXπ  TEST AL,AHπ  JNZ @Wau       { wait Until out of retrace }π@Wai: in AL,DXπ  TEST AL,AHπ  JZ @Wai        { wait Until inside retrace }π@Doline:π  STIπ  Mov Bl,[Offset BarCols+Si]π  Mov Di,Offset MyPalπ  Add Di,Bxππ  MOV DX,$03C8  { point to DAC[0] }π  MOV AL,0π  OUT DX,ALππ  CLIπ  MOV DX,$03DAπ@Whu: in AL,DXπ  RCR AL,1π  JC @Whu       { wait Until out of horizontal retrace }π@Whi: in AL,DXπ  RCR AL,1π  JNC @Whi      { wait Until inside retrace }ππ  Inc Si        { line counter }π                { prepare For color effect }ππ  MOV DX,$03C9π  Mov Al,[Di]π  OUT DX,Al   { Dynamic Red }π  Mov Al,[Di+256]π  OUT DX,AL   { Dynamic Green }π  mov Al,[Di+512]π  OUT DX,AL   { Dynamic Blue }ππ  CMP SI,296  { Paint just about 3/4 screen }π  JBE  @dolineπ  STIπEnd;ππPROCEDURE Split(Row:Integer);πBEGINπ     ASMπ        mov dx,$3d4π        mov ax,rowπ        mov bh,ahπ        mov bl,ahπ        and bx,201hπ        mov cl,4π        shl bx,clπ        mov ah,alπ        mov al,18hπ        out dx,axπ        mov al,7π        cliπ        out dx,alπ        inc dxπ        in al,dxπ        stiπ        dec dxπ        mov ah,alπ        and ah,0efhπ        or ah,blπ        mov al,7π        out dx,axπ        mov al,9π        cliπ        out dx,alπ        inc dxπ        in al,dxπ        stiπ        dec dxπ        mov ah,alπ        and ah,0bfhπ        shl bh,1π        shl bh,1π        or ah,bhπ        mov al,9π        out dx,axπ     END;πEND;ππProcedure FastWrite(Col,Row,Attrib:Byte; Str:String);πVar MemPos : Word;π    A      : Byte;πBeginπ MemPos:=(Col*2)+(Row*ScrWidth)-ScrWidth-2;π A:=Length(Str);π  For A:=1 to Length(Str) doπ   Beginπ    MemW[$B800:MemPos]:=Ord(Str[A])+Attrib*256;π    MemPos:=MemPos+2;π   End;πEnd;ππProcedure CenterWrite(Y,Color:Byte;Mes:String);πBeginπ FastWrite(41-((Length(Mes)-1) Div 2),Y,Color,Mes);πEnd;ππProcedure CursorOff; Assembler;πAsmπ  Mov Ax,0100hπ  Mov Cx,2000hπ  Int 10hπEnd;ππProcedure CursorOn; Assembler;πAsmπ  Mov Ax,0100hπ  Mov Cx,0607hπ  Int 10hπEnd;ππProcedure ScrollText(Nr:Word); Assembler;πAsmπ  mov ax,nrπ  mov cx,$40π  mov es,cxπ  mov cl,es:[$85]π  div clπ  mov cx,axπ  mov dx,es:[$63]π  push dxπ  mov al,$13π  cliπ  out dx,alπ  inc dxπ  in al,dxπ  stiπ  mul clπ  shl ax,1π  mov es:[$4e],axπ  pop dxπ  mov cl,alπ  mov al,$cπ  out dx,axπ  mov al,$dπ  mov ah,clπ  out dx,axπ  mov ah,chπ  mov al,8π  out dx,axπEnd;πππFunction ReadKey : Char; Assembler;πAsmπ Mov Ah,07hπ Int 21hπEnd;ππProcedure SetHorizOfs(Count:Byte);πVar I : Byte;πBeginπ I:=Port[$3DA];π Port[$3C0]:=$33;π Port[$3C0]:=StartDat[Count Mod 16];πEnd;ππProcedure Sync; Assembler;πAsmπ  Mov Dx,3DAhπ@LoopIt:π  In Al,Dxπ  Test Al,8π  Jz @LoopItπEnd;ππProcedure DoubleWidth; Assembler;πAsmπ Mov Dx,3D4hπ Mov Ax,5013hπ Out Dx,Axπ Mov ScrWidth,320πEnd;ππProcedure SetPELReset; Assembler;πAsmπ Mov Dx,3DAhπ In Al,Dxπ Mov Dx,3C0hπ Mov Al,30hπ Out Dx,Alπ Mov Al,2Chπ Out Dx,AlπEnd;ππProcedure SetView(X,Y:Word);πVar PelPos:Byte;πBeginπ PelPos:=StartDat[X Mod 9];π X:=(X Div 9)+(Y Div 16)*160;π  Asmπ    Mov Dx,3D4h    { Set Screen offset in bytes:}π    Mov Bx,Xπ    Mov Ah,Bhπ    Mov Al,0Chπ    Out Dx,Axπ    Mov Ah,Blπ    Inc Alπ    Out Dx,Axππ    Mov Al,8       { Set Y-Offset within Character-Row: }π    Mov Bx,Yπ    And Bl,15π    Mov Ah,Blπ    Out Dx,Axππ    Mov Dx,3C0h    { Set X-Offset within Character-Column: }π    Mov Al,33hπ    Out Dx,Alπ    Mov Al,PelPosπ    Out Dx,Alπ End;πEnd;ππProcedure UpDateScroller;πBeginπ If ScrollOfs=9 thenπ  Beginπ   ScrollOfs:=0;ππ   Move(Mem[$B800:14*320+2],Mem[$B800:14*320],3*320-2);π   Inc(CharOfs);π   If CharOfs=4 thenπ    Beginπ     Inc(ScrollPos);π     WriteBigMessage(84-CharOfs,15,14,ScrollMessage[ScrollPos]);π     If ScrollPos=Length(ScrollMessage) Then ScrollPos:=0;π     CharOfs:=0;π    End;π  Endπ elseπ  Inc(ScrollOfs,9);π SetHorizOfs(ScrollOfs);πEnd;ππππBeginπ CursorOff;π FillChar(Mem[$B800:0000],4000,0);ππ  With MoveMes doπ   Beginπ    YPos:=110;π    YSpeed:=2;π    XPos:=40*8;π    XSpeed:=3;π    Counter:=0;π   End;ππ  With MoveSplit Doπ   Beginπ    YPos:=295;π    YSpeed:=2;π   End;ππ DoubleWidth;π SetPelReset;π ScrollText(MoveMes.YPos);π Split(MoveSplit.YPos);π Setupbars;π MakePal;π SetCharSet;π Sync;π CenterWrite(1,14,#194'─────────────────────────────────────────────────────────────────────────────'#190);π WriteBigMessage(1,2,4,'GAME - Gotta Get it!');π CenterWrite(5,14,#194'─────────────────────────────────────────────────────────────────────────────'#190);ππ  Repeatπ    With MoveMes doπ     Beginπ       If (YPos>80) and (YPos<200) thenπ        Inc(YPos,YSpeed)π       elseπ        Beginπ         YSpeed:=-YSpeed;π         YPos:=YPos+YSpeed;π        End;π      Counter:=1-Counter;π       If Odd(Counter) thenπ        Beginπ         If (XPos<40*8) or (XPos>40*8+150) then XSpeed:=-XSpeed;π         Inc(XPos,XSpeed);π        End;π     End;ππ    With MoveSplit doπ     Beginπ       If (YPos>290) and (YPos<325) thenπ        Inc(YPos,YSpeed)π       elseπ        Beginπ         YSpeed:=-YSpeed;π         YPos:=YPos+YSpeed;π        End;π     End;ππ   UpdateBars;π   ScrollText(MoveMes.YPos);π   UpDateScroller;π   Split(MoveSplit.YPos);π   ColorBars;π  Until KeyPressed;ππ  While KeyPressed do Readkey;π Split(400);π SetView(0,0);π ScrollText(0);π  Asmπ   Mov Ax,3π   Int 10hπ  End;π FastWrite(1,1,15,'Bye from World of Wonders!');π Writeln;π CursorOn;πEnd.π                                                                                                         84     05-25-9408:02ALL                      WIM VAN DER VEGT         7 Segment clock          SWAG9405            94     ╓   {πHere's the source of a seven segment display useful to place at the endπof your autoexec if you also have the habit of turning your computer onπlong before using it or want an expensive clock (works then best on aπ66Mhz DX2 or Pentium).πππThe BGI_01 unit just links in the BGI driver. If removed you'll have toπsupply EGAVGA.BGI in the current directory (Or get the source of theπunit from a previous message).πππStart it with SEGMENT 15 and a bright yellow clock will appear.πππ-------------------------<cut hereππ{---------------------------------------------------------}π{  Project : Seven Segment Display                        }π{  Auteur  : Ir. G.W. van der Vegt                        }π{---------------------------------------------------------}π{  Datum .tijd  Revisie                                   }π{  901025.2000  Creatie.                                  }π{---------------------------------------------------------}ππPROGRAM Segment(INPUT,OUTPUT);ππUSESπ  CRT,π  DOS,π  GRAPH,π  BGI_01;ππVARπ  cl : INTEGER;ππ{---------------------------------------------------------}π{----Routine to display ASCII as seven segment LED display}π{---------------------------------------------------------}ππPROCEDURE Segments(nch,och : CHAR;xc,yc : INTEGER;scale : REAL);ππ{---------------------------------------------------------}π{----Types & const for graphical LED segment definition   }π{---------------------------------------------------------}ππTYPEπ  seg = ARRAY[1..7] OF Pointtype;ππCONSTπ  Ver   : seg = ((x :   1; y :   0),(x :   0; y :   1),π                 (x :   0; y :   9),(x :   1; y :  10),π                 (x :   2; y :   9),(x :   2; y :   1),π                 (x :   1; y :   0)                  );ππ  Hor   : seg = ((x :   0; y :   1),(x :   1; y :   0),π                 (x :   9; y :   0),(x :  10; y :   1),π                 (x :   9; y :   2),(x :   1; y :   2),π                 (x :   0; y :   1)                  );ππ  DPdot : seg = ((x :   1; y :   1),(x :   2; y :   0),π                 (x :   2; y :   1),(x :   2; y :   2),π                 (x :   1; y :   2),(x :   0; y :   2),π                 (x :   1; y :   1)                   );ππ  SCDot : seg = ((x :   4; y :   4),(x :   4; y :   6),π                 (x :   6; y :   6),(x :   6; y :   4),π                 (x :   4; y :   4),(x :   4; y :   4),π                 (x :   4; y :   4)                   );ππTypeπ  dir  = (vertical,horizontal,decimal,dot);ππ{---------------------------------------------------------}π{----Routine to hide/display a segment                    }π{---------------------------------------------------------}ππPROCEDURE Dispsegm(dir : dir;show : BOOLEAN; m,dx,dy : REAL);ππVARπ  segm : seg;π  i    : INTEGER;ππBEGINπ  CASE dir OFπ    vertical   : segm:=ver;π    horizontal : segm:=hor;π    decimal    : segm:=DPdot;π    dot        : segm:=SCdot;π  END;ππ  FOR i:=1 TO 7 DOπ    BEGINπ      segm[i].x:=TRUNC((segm[i].x+dx)*m)+xc;π      segm[i].y:=TRUNC((segm[i].y+dy)*m)+yc;π    END;ππ  IF showπ    THEN setfillstyle(solidfill,cl)π    ELSE setfillstyle(solidfill,black);ππ  Fillpoly(7,segm);πEND;ππ{---------------------------------------------------------}π{----Types & Const for 7 segment display codes definitions}π{---------------------------------------------------------}ππTYPEπ  leds  = (a,b,c,d,e,f,g,dp,dl,dh);π  offst = RECORDπ            dx,dy : REAL;π            d     : dir;π          END;π  disp  = SET OF leds;ππCONSTπ  rel : ARRAY[leds] OF offst =π        ((dx : 1.0;dy : 0.0; d : horizontal),π         (dx : 0.0;dy : 1.0; d : vertical  ),π         (dx : 0.0;dy :11.0; d : vertical  ),π         (dx : 1.0;dy :20.0; d : horizontal),π         (dx :10.0;dy :11.0; d : vertical  ),π         (dx :10.0;dy : 1.0; d : vertical  ),π         (dx : 1.0;dy :10.0; d : horizontal),π         (dx :11.0;dy :21.0; d : decimal   ),π         (dx : 1.0;dy : 1.0; d : dot       ),π         (dx : 1.0;dy :11.0; d : dot       ));ππ{---------------------------------------------------------}π{----Routine to convert ASCII to 7 segments               }π{---------------------------------------------------------}ππPROCEDURE Calcleds(ch : CHAR;VAR sseg : disp);ππBEGINπ  CASE ch OFπ    '0' : sseg:=[a,b,c,d,e,f];π    '1' : sseg:=[e,f];π    '2' : sseg:=[a,c,d,f,g];π    '3' : sseg:=[a,d,e,f,g];π    '4' : sseg:=[b,e,f,g];π    '5' : sseg:=[a,b,d,e,g];π    '6' : sseg:=[a,b,c,d,e,g];π    '7' : sseg:=[a,e,f];π    '8' : sseg:=[a,b,c,d,e,f,g];π    '9' : sseg:=[a,b,d,e,f,g];π    '-' : sseg:=[g];π    '-' : sseg:=[d];π    '^' : sseg:=[a];π    ':' : sseg:=[dl,dh];π    '≡' : sseg:=[a,d,g];π    '.' : sseg:=[dp];π  ELSE sseg:=[];π  END;πEND;ππVARπ  led     : leds;π  oseg,π  nseg,π  offseg,π  onseg   : disp;ππBEGINπ  Setcolor(DarkGray);ππ  IF (nch=#0) AND (och=#0)π    THENπ      BEGINπ        offseg:=[a,b,c,d,e,f,g,dp,dl,dh];π        onseg :=[];π      ENDπ    ELSEπ      BEGINπ        Calcleds(och,oseg);π        Calcleds(nch,nseg);ππ        onseg :=nseg-oseg-oseg*nseg;    {----Leds to turn on }π        offseg:=oseg-nseg-oseg*nseg;    {----Leds to turn off}π      END;ππ  FOR led:=a TO dh DOπ    WITH rel[led] DOπ      BEGINπ        IF led IN  onseg THEN Dispsegm(d, true,scale,dx,dy);π        IF led IN offseg THEN Dispsegm(d,false,scale,dx,dy);π      END;πEND;ππ{---------------------------------------------------------}π{----Prints error msg & halts program                     }π{---------------------------------------------------------}ππPROCEDURE Error(s : STRING);ππBEGINπ  CLRSCR;π  WRITELN;π  WRITELN('SYNTAX : Segment <color>');π  WRITELN;π  WRITELN('ERROR    ',s);π  WRITELN;π  HALT;πEND;ππ{---------------------------------------------------------}π{----Main Program                                         }π{---------------------------------------------------------}ππVARπ  tmp,π  h,m,s,ms : WORD;π  i,e      : INTEGER;ππ  c1,c2,c3 : STRING[2];ππ  olds,π  news     : STRING;ππ  grdriver,π  grmode,π  errcode : INTEGER;ππ  r       : REGISTERS;π  oldstate: BYTE;ππ{---------------------------------------------------------}ππBEGINππ  Grdriver:=detect;π  DetectGraph(grdriver,grmode);ππ{----Allow segment color to be chosen by user}π  IF (PARAMCOUNT=1)π    THENπ      BEGINπ        VAL(PARAMSTR(1),cl,e);π        IF (e<>0) THEN Error('Incorrcet Parameter');π      ENDπ    ELSEπ      CASE grdriver OFπ        mcga,π        egamono : cl:=1;π        ega64   : cl:=3;π        ega,π        vga     : cl:=15;π      END;ππ  CASE grdriver OFπ    mcga    : IF NOT (cl IN [1])π                THEN Error('With MCGA only color 1 is allowed');π    ega64   : IF NOT (cl IN [1..3])π                THEN Error('With 64 K EGA only colors 1..4 are allowed');π    egamono : IF NOT (cl IN [1])π                THEN Error('With EGA mono only color 1 is allowed');π    ega     : IF NOT (cl IN [1..15])π                THEN Error('With 256 K EGA only colors 1..15 are allowed');π    vga     : IF NOT (cl IN [1..15])π                THEN Error('With VGA only colors 1..15 are allowed');π  ELSE Error('Graphics Adapter NOT Supported');π  END;ππ  Initgraph(grdriver,grmode,'');π  errcode:=Graphresult;ππ  news:='        ';π  olds:='        ';ππ  FOR i:=1 TO LENGTH(news) DO Segments(#0,#0,80*(i-1),80,6.0);ππ  r.ah:=$02;π  INTR($16,r);ππ  REPEATπ    oldstate:=r.al;ππ    GETTIME(h,m,s,ms);ππ    STR(h:2,c1);π    STR(m:2,c2);π    STR(s:2,c3);ππ    IF Odd(s)π      THEN news:=c1+':'+c2+':'+c3π      ELSE news:=c1+' '+c2+' '+c3;ππ    IF (news[1]=' ') THEN news[1]:='0';π    IF (news[4]=' ') THEN news[4]:='0';π    IF (news[7]=' ') THEN news[7]:='0';ππ  {----Write only the changed segments in all displays}π    FOR i:=1 TO LENGTH(news) DO Segments(news[i],olds[i],80*(i-1),80,6.0);ππ    olds:=news;ππ    Delay(100);ππ{----Not only wait for normal keypressed but also forπ     shift/alt/ctrl or insert/numlock/scrollock keys pressed}π    r.ah:=$02;π    INTR($16,r);ππ  UNTIL (r.al<>oldstate) OR (KEYPRESSED AND (READKEY<>#255));ππ  Closegraph;ππEND. {of segment}πππ> I would like to include a clock in my current project which will beπ> updated once a minute.  Instead of constantly checking the computer's clockπ> and waiting for it to change, I would like to use an interrupt.ππThis one has even a hot key handler.  If you want to update it once perπminute, bump a counter within the interrupt 1Ch handler till it reaches theπvalue 60*18.2.  Then refresh the screen.π}ππProgram Clock;ππ{$G+,R-,S-,M 1024, 0, 0 }ππusesπ  Dos;ππConstπ  x           = 71;                   { x location on screen }π  y           = 1;                    { y location on screen }π  Keyboard    = 9;                    { Hardware keyboard interrupt }π  TimerTick   = $1C;                  { Gets called 18.2 / second }π  VideoOffset = 160 * (y - 1) + 2 * x;{ Offset in display memory }π  yellow      = 14;π  blue        = 1;π  attribute   = blue * 16 + yellow;   { Clock colours }π  VideoBase   : Word = $B800;         { Segment of display memory }π  ActiveFlag  : ShortInt = -1;        { 0: on, -1: off }ππVarπ  OrgInt9,                             { Saved interrupt 9 vector }π  OrgInt1Ch : Pointer;              { Saved interrupt 1Ch vector }π  VideoMode : Byte absolute $0000:$0449;ππ{ Display a string using Dos services (avoid WriteLn, save memory) }ππProcedure DisplayString(s : String); Assembler;ππASMπ  PUSH   DSπ  XOR    CX, CXπ  LDS    SI, sπ  LODSBπ  MOV    CL, ALπ  JCXZ   @EmptyStringπ  CLDπ @NextChar:π  LODSBπ  XCHG   AX, DXπ  MOV    AH, 2π  INT    21hπ  LOOP   @NextCharπ @EmptyString:π  POP    DSπend;ππ{ Returns True if a real time clock could be found }πFunction HasRTClock : Boolean; Assembler;ππASMπ  XOR    AL, ALπ  MOV    AH, 2π  INT    1Ahπ  JC     @NoRTClockπ  INC    AXπ @NoRTCLock:πend;ππ{ Release Dos environment }πProcedure ReleaseEnvironment; Assembler;πASMπ  MOV    ES, [PrefixSeg]π  MOV    ES, ES:[002Ch]π  MOV    AH, 49hπ  INT    21hπend;ππ{ INT 9 handler intercepting Alt-F11 }πProcedure ToggleClock; Interrupt; Assembler;πConstπ  F11      = $57;                  { 'F11' make code }π  BiosSeg  = $40;                  { Segment of BIOS data area }π  AltMask  = $08;                  { Bitmask of Alt key }π  KbdFlags = $17;                  { Byte showing keyboard status }ππASMπ  STIπ  IN     AL, 60hππ { F11 pressed? }π  CMP    AL, F11π  JNE    @PassThruππ { Alt-key pressed? }π  PUSH   BiosSegπ  POP    ESπ  MOV    AL, ES:[KbdFlags]π  AND    AL, AltMaskπ  CMP    AL, AltMaskπ  JNE    @PassThruππ { Flip status flag, force EOI and leave routine }π  NOT    [ActiveFlag]π  IN     AL, 61hπ  MOV    AH, ALπ  OR     AL, 80hπ  OUT    61h, ALπ  MOV    AL, AHπ  OUT    61h, ALπ  CLIπ  MOV    AL, 20hπ  OUT    20h, ALπ  STIπ  JMP    @Exitππ @PassThru:π  CLIπ  PUSHFπ  CALL   DWord Ptr [OrgInt9]π @Exit:πend;  { ToggleClock }ππ{ Convert a packed BCD byte to ASCII character }πProcedure Digit; Assembler;πASMπ  PUSH   AXπ  CALL   @HiNibbleπ  POP    AXπ  CALL   @LoNibbleπ  RETNππ @HiNibble:π  SHR    AL, 4π  JMP    @MakeAsciiπ @LoNibble:π  AND    AL, 0Fhπ @MakeAscii:π  OR     AL, '0'π  STOSWπend;ππ{ INT 1Ch handler that displays a clock on the right hand side of the screen }πProcedure DisplayClock; Interrupt; Assembler;πASMπ  CMP    [ActiveFlag], 0π  JNE    @Exitπ  CLDπ  MOV    AH, 2π  INT    1Ahπ  MOV    ES, [VideoBase]π  MOV    DI, VideoOffsetπ  MOV    AH, attributeπ  MOV    AL, CHπ  CALL   Digitπ  MOV    AL, ':'π  STOSWπ  MOV    AL, CLπ  CALL   Digitπ  MOV    AL, ':'π  STOSWπ  MOV    AL, DHπ  CALL   Digitπ  PUSHFπ  CALL   DWord Ptr [OrgInt1Ch]π @Exit:πend;ππBeginπ  If VideoMode = 7 Thenπ    VideoBase := $B000;π  GetIntVec(TimerTick, OrgInt1Ch);π  SetIntVec(TimerTick, @DisplayClock);π  GetIntVec(Keyboard, OrgInt9);π  SetIntVec(Keyboard, @ToggleClock);π  SwapVectors;π  ReleaseEnvironment;π  DisplayString('CLOCK installed.  <Alt-F11> toggles on/off');π  Keep(0);πend.π                                                                                                                   85     05-25-9408:02ALL                      RYAN PETRIE              Virtual Screens          SWAG9405            10     ╓   {ππWS>Hello! I've thought about writing my own 3D games or just any high graphicsπWS>program and am in the process of writing a unit that handles virtual screensπWS>have 6 virtual screens (0..5, where 0 will be MOVEd to $A000:0000) that areπWS>type pointer with 64000 bytes each. They are designed for Mode 13h, of coursπWS>I have a procedure called CopyScreen. Basically,ππJust FYI:  You might want to consider using Mode-X.  Matt Pritchard hasπwritten a great freeware library for such (MODEX10?.ZIP) with a Pascalπexample.  With Mode-X, you can use the VGA's memory instead of preciousπconventional (if in real mode) memory, and the page switching is a lotπfaster than copying 64k from memory.π}ππprocedure copyscreen(source,dest : pointer; mask : byte); assembler;ππasmπ  push  dsπ  lds   si,sourceπ  les   di,destπ  mov   cx,64000π  cldπ@loop:π  lodsbπ  cmp   mask,alπ  je    @nodrawπ  mov   es:[di],alπ@nodraw:π  inc   diπ  loop  @loopπ  pop   dsπend;ππYou need to call it like this (note the '@'):ππ  copyscreen(@virtualscreen[first],@virtualscreen[second],mask);π                                                                                 86     05-25-9408:13ALL                      FLORIAN ANSORGE          Fading UNIT              SWAG9405            18     ╓   UNIT FadeUnit;        { This unit does some fading (I hope!) }π                      { The SetCol procedure lets you change individual}π                      { palette entries , for an easier way, try }π                      { the TP setrgbpalette procedure...}π                      { Regards Florian Ansorge :-) }πINTERFACEππProcedure InitCol; {gets the current palette and saves it}ππProcedure FadeOUT(Duration:Byte);   { lowers/increases the brightness,}πProcedure FadeIN(Duration:Byte);    { duration determines the time it takes}ππProcedure SetBrightness(Brightness :Byte);π                                    {sets the brightness to brightness / 63 }πIMPLEMENTATIONππUSES Crt, Dos;ππCONST     PelIdxR  = $3c7; {Port to read}π          PelIdxW  = $3c8; {Port to write}π          PelData  = $3c9; {Dataport}π          Maxreg   = 255;  {Set to 63 for textmode}π          MaxInten = 63;ππVAR col : ARRAY[0..MaxReg] of RECORDπ                                r, g, b : Byteπ                              END;ππPROCEDURE GetCol(ColNr :Byte; var r, g, b :Byte);πBEGINπ  Port[PelIdxR] := ColNr;π  r := Port[PelData];π  g := Port[PelData];π  b := Port[PelData];;πEND;ππPROCEDURE SetCol(ColNr, r, g, b :Byte); {Change just one colour}πBEGINπ  Port[PelIdxW] := ColNr;π  Port[PelData] := r;π  Port[PelData] := g;π  Port[PelData] := b;πEND;ππPROCEDURE InitCol; {save initial palette}ππVAR i :Byte;ππBEGINπ  FOR i := 0 to MaxReg DOπ    GetCol(i,col[i].r,col[i].g,col[i].b);πEND;ππPROCEDURE SetBrightness(Brightness :Byte);ππVAR i          :Byte;π    fr, fg, fb :Byte;ππBEGINπ  FOR i := 0 to MaxReg DOπ  BEGINπ    fr := col[i].r * Brightness DIV MaxInten;π    fg := col[i].g * Brightness DIV MaxInten;π    fb := col[i].b * Brightness DIV MaxInten;π    SetCol(i,fr,fg,fb);π  END;πEND;ππPROCEDURE FadeOUT(Duration :Byte);ππVAR i :Byte;ππBEGINπ  FOR i := MaxInten downto 0 DOπ  BEGINπ    SetBrightness(i);π    Delay(Duration);π  END;πEND;ππPROCEDURE FadeIN(Duration :Byte);ππVAR i :Byte;ππBEGINπ  FOR i := 0 to MaxInten DOπ  BEGINπ    SetBrightness(i);π    Delay(Duration);π  END;πEND;ππBEGINπEND.π                                                                                          87     05-25-9408:20ALL                      WIM VAN DER VEGT         Delux Paint II LBM decodeSWAG9405            90     ╓   {πHere a program to display files from deLux Paint II (*.LBM files)πdrawings. It uses a PD BGI driver for 320x200x256 color mode. Otherπdrivers can also be used. Otherwise look in the SWAG lib for routines toπenter this graphics mode and set a pixel in a certain color.ππCode isn't optimal and can be made much faster but works. It doesn'tπdisplay some brushes because of some undocumented sections in the LBMπfile. If the defines are made active the file is decoded and dumpedπtextual to the screen. After the program a part of a small PD text fileπI found and used as base for this program. It contained some bugs butπone evening works does a lot.ππBtw. Does anybody know how to distinguish deLux Paint II and deLux PaintπII Enhanced files?π}ππ{---------------------------------------------------------}π{ Written by : Ir. G.W. van der Vegt                      }π{ Purpose    : a Delux Paint II LBM file displayer/decoder}π{              displays 16 and 256 color bitmaps but no   }π{              brushes and Delux Paint IIe files yet      }π{                                                         }π{              Displays at the moment only                }π{              320x200 or smaller pictures.               }π{                                                         }π{              Uses a PD SVGA driver to access MCGA mode. }π{              Substitute your own if you havn't got it.  }π{                                                         }π{ File format info by Bob Montgomery 9-21-90, although    }π{ it wasn't very accurate (he forgot Motorola swaps       }π{ lo & hi byes of words) and didn't cover the             }π{ DPPV, CRNG & GRAB sections.                             }π{                                                         }π{ Use the verbose (and rle) defines to get a dump of the  }π{ lbm file.                                               }π{---------------------------------------------------------}ππPROGRAM lbm(INPUT,OUTPUT);ππUSESπ  crt,π  dos,π  graph;π  routines;ππ{ DEFINE verbose}π{ DEFINE rle    }π{$I SVGA256.INC}ππTYPEπ  rgb  = (r,g,b);π  dp2l = ARRAY[0..3] OF BYTE; {read left to right}π  dp2m = ARRAY[1..4] OF CHAR;π  dp2t = ARRAY[rgb] OF BYTE;π  dp2h = RECORDπ           msg1         : dp2m; { "FORM" }π           flen         : dp2l;                 { File length - 8 }π           msg2,                { "ILBM" }π           msg3         : dp2m; { "BMHD" }π           hlen         : dp2l;                 { Length of header }π           width,π           Length,π           xoff,π           yoff         : WORD;π           planes,π           masking,π           compression,π           pad          : BYTE;π           tansparent   : INTEGER;π           x_aspect,π           y_aspect     : BYTE;π           screenwidth,π           screenheight : WORD;π         END;ππCONSTπ  max  = 1023;ππVARπ   f   : FILE;π   dp2 : dp2h;π   msg : dp2m;π   len : dp2l;π   col : dp2t;ππ   i,π   j,π   k,π   y   : INTEGER;π   c   : BYTE;π   bl,π   h,π   l   : LONGINT;π   w   : WORD;π   grmode,π   grdriver : INTEGER;π   lin      : ARRAY[0..max] OF BYTE;ππCONSTπ  form  : dp2m = ('F','O','R','M');π  ilbm  : dp2m = ('I','L','B','M');π  bmhd  : dp2m = ('B','M','H','D');π  cmap  : dp2m = ('C','M','A','P');π  body  : dp2m = ('B','O','D','Y');ππ{$F+}πFUNCTION Detectvga256 : INTEGER;ππBEGINπ  Detectvga256 := svga320x200x256;πEND;π{$F-}πFUNCTION Len2long(a : dp2l) : LONGINT;ππBEGINπ  Len2long:=(((a[0]*256+a[1])*256+a[2])*256+a[3]);πEND;ππFUNCTION Msg2str(a : dp2m) : STRING;ππBEGINπ  Msg2str:=a[1]+a[2]+a[3]+a[4];πEND;ππFUNCTION Readnext : BYTE;ππVARπ w : WORD;π c : BYTE;ππBEGINπ  Blockread(f,c,1,w);π  IF (w<>1)π    THENπ      BEGINπ        Closegraph;π        Writeln('Unexpected EOF encountered');π        Halt(3);π      ENDπ    ELSE Readnext:=c;πEND;ππCONSTπ  cnt : BYTE    = 0;π  rle : BOOLEAN = false;π  dat : BYTE    = 0;π  vir : LONGINT = 0;π  rel : LONGINT = 0;ππFUNCTION Getnext : BYTE;ππVARπ  c : BYTE;π  w : WORD;ππBEGINπ(*πget a code BYTE from the data stream.πIF the msb is 1, the 'count' is (1 - code), max = 127. get the nextπ   BYTE from the data stream, AND REPEAT it 'count' times.πIF the msb is 0, the 'count' is (1 + code), max = 128. get the nextπ   'count' bytes from the data stream.π*)π  IF (dp2.compression=0)π    THEN Getnext:=Readnextπ    ELSEπ      IF (cnt=0)π        THENπ          BEGINπ            c:=Readnext;π            rle:=(c>127);π            IF rleπ              THENπ                BEGINπ                  cnt    :=SHORTINT(1-c);π                  dat    :=Readnext;π                  Getnext:=dat;π{$IFDEF rle}π  Delay(500);π  Writeln;π  Write('RLE : ',byte2hex(c),' = ',cnt:3,'x',byte2hex(dat));π{$ENDIF}π                ENDπ              ELSEπ                BEGINπ                  cnt    :=1+c;π                  dat    :=Readnext;π                  Getnext:=dat;π{$IFDEF rle}π  Delay(500);π  Writeln;π  Write('UNC : ',byte2hex(c),' : ',byte2hex(dat));π{$ENDIF}π                END;π          ENDπ        ELSEπ          BEGINπ            IF NOT(rle)π              THEN dat:=Readnext;π            Getnext:=dat;π{$IFDEF rle}π  IF NOT(rle) THEN Write(' ',byte2hex(dat));π{$ENDIF}π          END;ππ  Dec(cnt);π  rel:=Filepos(f)-h;π  Inc(vir);πEND;ππBEGINπ  Assign(f,Paramstr(1)+'.lbm');π  Reset(f,1);ππ  Blockread(f,dp2,Sizeof(dp2));ππ  WITH dp2 DOπ    BEGINπ{$IFDEF verbose}π      FOR i:=1 TO Sizeof(msg1) DO Write(msg1[i]); Writeln;π      FOR i:=1 TO Sizeof(msg2) DO Write(msg2[i]); Writeln;π{$ENDIF}π      IF (msg1<>form) OR (msg2<>ilbm) OR (msg3<>bmhd)π        THENπ          BEGINπ            Writeln('No DeLux Paint LBM file.');π            Halt(1);π          END;ππ{$IFNDEF verbose}π      grdriver:=Installuserdriver('SVGA256',@detectvga256);π      grmode  :=svga320x200x256;π      grdriver:=detect;π      Initgraph(grdriver,grmode,'');π{$ENDIF}ππ    {----Low & high words/bytes are swapped (Motorola 680x0 convention)}π{$IFDEF verbose}π      Writeln('filelength : ',Len2long(flen));π      Writeln('headlength : ',Len2long(hlen));π{$ENDIF}ππ    {----Low & high bytes are swapped (Motorola 680x0 convention)}π      width       :=Swap(width);π      Length      :=Swap(Length);π      xoff        :=Swap(xoff);π      yoff        :=Swap(yoff);π      screenwidth :=Swap(screenwidth);π      screenheight:=Swap(screenheight);ππ{$IFDEF verbose}π      Writeln('W .L  : ',width      ,'x',Length);π      Writeln('Xo.Yo : ',xoff       ,'x',yoff  );π      Writeln('Xa.Ya : ',x_aspect   ,'x',y_aspect);π      Writeln('W. H  : ',screenwidth,'x',screenheight);π      Writeln('Planes: ',planes);π      Writeln('Pad   : ',pad);π{$ENDIF}ππ      Blockread(f,msg,Sizeof(msg));π      Blockread(f,len,Sizeof(len));ππ{$IFDEF verbose}π      Writeln(Msg2str(msg));π      Delay(1000);π{$ENDIF}ππ      IF (msg=cmap)π        THENπ          BEGINπ            l:=Len2long(len);π{$IFDEF verbose}π            Writeln('CMAPlen : ',l);π{$ENDIF}π            FOR i:=1 TO l DIV 3 DOπ              BEGINπ                Blockread(f,col,Sizeof(col));π{$IFDEF verbose}π                Delay(100);π                Writeln(i-1:4,col[r]:4,col[g]:4,col[b]:4);π{$ELSE}π                Setrgbpalette(i-1,col[r] DIV 4,col[g] DIV 4,col[b] DIV 4);π{$ENDIF}π              END;π            Blockread(f,msg,Sizeof(msg));π          END;ππ{----dump unkown sections dppvπ     the 4 bytes Length is mostly 104 bytesπ}π{----dump unkown sections grabπ     the 4 bytes Length is 4, section found IN a brush only,π}π{----dump 4 unkown sections crng :π     seems each TO consist OF two entries WITH :π              00 00 0a aa,00 00 01 0eπ              00 00 0a aa,00 00 00 00π              00 00 0a aa,00 00 00 00π              00 00 0a aa,00 00 00 00π     brushes contain different values.π}π      WHILE (msg<>body) DOπ        BEGINπ          Blockread(f,len,Sizeof(len));π          l:=Len2long(len);π          Writeln(Msg2str(msg)+' : ',l);π          FOR h:=1 TO l DOπ            BEGINπ              Blockread(f,c,1);π              Write(' ',byte2hex(c));π            END;π          Blockread(f,msg,Sizeof(msg));π          Writeln;π        END;ππ      IF (msg=body)π        THENπ          BEGINπ{$IFDEF verbose}π            Writeln(Msg2str(msg));π{$ENDIF}π            Blockread(f,len,Sizeof(len));π            l:=Len2long(len);π            h :=Filepos(f);π{$IFDEF verbose}π            Writeln('BODYlen : ',l);π{$ENDIF}π            IF compression=0π              THEN bl:=l DIV Length DIV planesπ              ELSE bl:=width DIV 8;π{$IFDEF verbose}π            Writeln('Bytew   : ',bl);π{$ENDIF}π            FOR y:=1 TO Length DOπ              BEGINπ                FOR i:=0 TO max DO lin[i]:=0;π{$R-}π                FOR j:=0 TO planes-1 DOπ                  FOR i:=0 TO bl-1 DOπ                    BEGINπ                      c:=Getnext;π                      FOR k:=0 TO 7 DOπ                        IF (c AND (128 SHR k))>0π                          THEN lin[(i*8)+k]:=lin[(i*8)+k] OR 1 SHL j;π                    END;π{$R+}π{$IFNDEF verbose}π                FOR i:=1 TO width DOπ                  Putpixel(i,y,lin[i])π{$ENDIF}π              END;ππ          END;ππ{$IFNDEF verbose}π      WHILE NOT Keypressed DO;π      Closegraph;π{$ELSE}π      Writeln('image  ',LONGINT(width)*Length*planes DIV 8);π      Writeln('bodys  ',h);π      Writeln('files  ',Filesize(f));π      Writeln('filep  ',Filepos(f));π      Writeln('heads  ',Sizeof(dp2h));π      Writeln('virtu  ',vir);π{$ENDIF}π      Close(f);π    END;ππEND.ππ(*πdeluxe paint ii lbm & iff filesππthe deluxe paint lbm (AND iff) FILE header (40 bytes) has the followingπcontent:π     struct dp2π     {   CHAR msg1[4];               "form"π         BYTE a3, a2, a1, a0;        FILE Length - 8  (Read left TO right)π         CHAR msg2[8];               "ilbmbmhd"π         BYTE b3, b2, b1, b0;        Length OF header (Read left TO right)π         Int  width, Length, xoff, yoff;π         BYTE planes, masking, compression, pad;π         Int  tansparent;π         BYTE x_aspect, y_aspect;π         Int  screenwidth, screenheight;π     } ;π   there may be a color map following a STRING "cmap" IN the FILE. after cmapπ        is the Length OF the color map (4 bytes, Read left TO right). the colorπ        map is BYTE triples (r, g, b) FOR each colors. the number OF colors isπ        1 shifted left by planes (1 << planes).π   the actual picture data follows a STRING "body" AND Length OF the pictureπ        data (4 bytes Read left TO right). the picture data is organized on aπ        color plane basis FOR dp2, AND on a pixel basis FOR dp2e (enhanced).π        thus, FOR dp2:π            there are (width / 8) bytes per row.π            the data stream FOR each row consists OF all the bytes FOR plane 0,π                followed by all the bytes FOR plane 1, etc.π        AND FOR dp2e:π            there are (width) bytes/row, where each BYTE is a pixel color.π   IF the data is uncomperessed (compression flag = 0), the data stream bytesπ        are fed TO the OUTPUT unmodified. IF it is compressed, it is run Lengthπ        encoded as follows:π            get a code BYTE from the data stream.π            IF the msb is 1, the 'count' is (1 - code), max = 127. get the nextπ                BYTE from the data stream, AND REPEAT it 'count' times.π            IF the msb is 0, the 'count' is (1 + code), max = 128. get the nextπ                'count' bytes from the data stream.π*)π                       88     05-25-9408:20ALL                      RICKY BOOTH              PCX *IN* Pascal!         SWAG9405            34     ╓   ππ > Does anyone have a program (not necessarily source) that willπ > take a fullπ > screen GIF or PCX or whatever graphic format and convert it intoπ > something I can load in Pascal?  Or even a graphic editor thatππYou can load a .PCX in pascal! No conversion needed. Here is some source.ππ{ MCGA PCX decode by Bas van Gaalen, Holland, PD }π{ Modified to use virtual screen/pointers by Ricky Booth, USA, PD }πππ{$M 65520, 4096, 655360}π{$I-}ππprogram pcx_view;ππusesπ  crt;ππtypeπ  pcxheader = recordπ    manufacturer,version,encoding,bits_per_pixel : byte;π    xmin,ymin,xmax,ymax,hres,vres : word;π    palette : array[0..47] of byte;π    reserved : byte;π    color_planes : byte;π    bytes_per_line : word;π    palette_type : word;π    filler : array[0..57] of byte;π  end;ππvarπ  pcxfile : file;π  header : pcxheader;ππ{----------------------------------------------------------------------------}ππprocedure error(errstr : string);πbeginπ  writeln(errstr);π  halt;πend;ππ{----------------------------------------------------------------------------}ππfunction validpcx : boolean;πbeginπ  seek(pcxfile,0);π  blockread(pcxfile,header,sizeof(header));π  with header do validpcx := (manufacturer = 10) and (version = 5) andπ    (bits_per_pixel = 8) and (color_planes = 1);πend;ππ{----------------------------------------------------------------------------}ππfunction validpal : boolean;πvar v : byte;πbeginπ  seek(pcxfile,filesize(pcxfile)-769);π  blockread(pcxfile,v,1);π  validpal := v = $0c;πend;ππ{----------------------------------------------------------------------------}ππprocedure setvideo(md : word); assembler;πasmπ  mov ax,mdπ  int 10hπend;ππ{----------------------------------------------------------------------------}ππCONST VGA = $a000;  (* This sets the constant VGA to the segment of theπ                       VGA screen.                                      *)ππType Virtual = Array [1..64000] of byte;  { The size of our Virtual Screen }π     VirtPtr = ^Virtual;                  { Pointer to the virtual screen }ππVAR Virscr : VirtPtr;                     { Our first Virtual screen }π    Vaddr  : word;                        { The segment of our virtual screen}ππprocedure setpal;πvar pal : array[0..767] of byte;πbeginπ  seek(pcxfile,filesize(pcxfile)-768);π  blockread(pcxfile,pal,768);π  asmπ    cldπ    xor di,diπ    xor bx,bxπ   @L1:π    mov dx,03c8hπ    mov ax,bxπ    out dx,alπ    inc dxπ    mov cx,3π   @L2:π    mov al,byte ptr pal[di]π    shr al,1π    shr al,1π    out dx,alπ    inc diπ    loop @L2π    inc bxπ    cmp bx,256π    jne @L1π  end;πend;ππ{----------------------------------------------------------------------------}ππProcedure SetUpVirtual;πBEGINπ  GetMem (VirScr,64000);π  vaddr := seg (virscr^);πEND;ππprocedure unpack;πvar gofs,j : word; i,k,v,loop : byte;πbeginπ  seek(pcxfile,128);π  gofs := 0;π  for i := 0 to header.ymax-header.ymin+1 do beginπ    j := 0;π    while j < header.bytes_per_line do beginπ      blockread(pcxfile,v,1);π      if (v and 192) = 192 then beginπ        loop := v and 63;π        inc(j,loop);π        blockread(pcxfile,v,1);π        for k := 1 to loop do beginπ          Mem[Vaddr:gofs] := v;π          inc(gofs);π        end;π      endπ      else beginπ        Mem[Vaddr:gofs] := v;π        inc(gofs);π        inc(j);π      end;π    end;π  end;π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;ππ{----------------------------------------------------------------------------}ππbeginπ  SetUpVirtual; (*initilizes the pointers*)π  if paramstr(1) = '' then error('Enter filename on commandline.');π  assign(pcxfile,paramstr(1));π  reset(pcxfile,1);π  if ioresult <> 0 then error(paramstr(1)+' not found.');π  if not validpcx then error('Not a 256 color PCX file.');π  if not validpal then error('Palette corrupt.');π  Writeln('Decoding Image...');π  Unpack;π  Setvideo($13);π  Setpal;π  Move(Virscr^,MEM[VGA:0],64000); (*Stick the virtual page to the vga mem*)π  repeat until keypressed;π  While keypressed do readln;π  setvideo(3);π  close(pcxfile);π  FreeMem (VirScr,64000); (*Free up virtual memory*)πend.π                     89     05-25-9408:20ALL                      PETER GRUHN              Plasma                   SWAG9405            51     ╓   {πThis is my plasma code. Written here for windows 24bit mode. There'sπsome comments in it. It had a problem. I tried to fix it. Couldn't.πDeleted some POSITIVELY ABSOLUTELY ESSENTIAL bits of code, and theπproblem went away. Don't ask me, I just wrote it.ππYou should be able to put it to palette based code pretty easy. Itπstarted out that way and then got converted to RGB. Probably all you'dπneed to do, is kill red and green, and just use blue as the paletteπentry. Your problem to make sure your palette has nice colours.ππIt still tends to be a little ridgy on the primary axes. If anybody canπget rid of that, that would be cool. Let me know.ππIt's also a fractal terrain generator. Same alg. This is just 3 fractalπterrain altitude maps overlaid in rgb.ππ(Oh, yeah, it's not really windows code. All the real windows codeπshould be separate from the useful code, just in case you don't doπwindows, don't be scared.)ππ--8<--------------------------------------------------------π}ππprogram plasma;π{integer version of cloud.π Only works 24bit. Change resolutionπ constants width, height if you need.}π{Left button starts drawing.π CTRL-ALT-DEL to stop. Or wait for it to finish, andπ right button}πuses OWindows, ODialogs, WinTypes, WinProcs;ππconstπ{integer version of old real constant.π For calm versions, try FUZZ1/FUZZ2=0.3π For wild versions, try FUZZ1/FUZZ2=10}π  FUZZ1=1;π  FUZZ2=6;ππ  width= 800;π  height= 600;ππtypeπ     TMyApp=object (TApplication)π       procedure InitMainWindow; virtual;π       end;ππ     PMyWindow=^TPlasmaWindow;π     TPlasmaWindow=object (TWindow)π       r,g,b:byte;π       w,h:integer;π       constructor init(AParent:PWindowsObject; ATitle:PChar);π       procedure SetUpWindow; virtual;π       procedure WMLButtonDown(var Msg:TMessage); virtual wm_First+wm_LButtonDown;π       procedure WMRButtonDown(var Msg:TMessage); virtual wm_First+wm_RButtonDown;π       function getclassname:pchar; virtual;π       procedure getwindowclass(var awndclass:twndclass); virtual;π       end;ππvar maxx,maxy:integer;π    backg:TColorRef;π    i:integer;ππfunction clamp(x:integer):byte;πbeginπ{  if x<0 then x:=0π  else if x>255 then x:=255;π  clamp:=x;}π  case x ofπ   -32767..0 : clamp:=0;π   0..255    : clamp:=x;π   256..32767: clamp:=255;π   else {oops};π   end; {case}πend;ππfunction randomcolour:TColorRef;πvar r,g,b:byte;πbeginπ    randomcolour:=rgb(random(256),random(256),random(256));πend;ππprocedure TMyApp.InitMainWindow;πbeginπ   MainWindow := New(PMyWindow, Init(NIL,'Plasma'));πend;ππconstructor TPlasmaWindow.init(AParent:PWindowsObject; ATitle:PChar);πbeginπ  inherited init(AParent,ATitle);π  r:=0; g:=0; b:=0;π  w:=2;h:=2;π  attr.x:=0; attr.y:=0;π  attr.w:=width; attr.h:=height;π  attr.style:=ws_popup + ws_visible;πend;ππprocedure TPlasmaWindow.SetUpWindow;πbeginπ  inherited setupwindow;πend;ππprocedure TPlasmaWindow.WMLButtonDown(var Msg:TMessage);πvar ADC:HDC;π    AP,TempP:HPen;π    AB,TempB:HBrush;ππ    function max(a,b:integer):integer;π    beginπ      if a<b then        max:=b      else        max:=a;π    end;ππ    function mid(a,b:integer):integer;π    beginπ      mid:=(a + b) div 2;π    end;ππ    function ridge(a,b,c,d:integer):TColorref;π    {Take two endpoints, shift the mid point, based on how far apart they are.}π    var variance:integer;π        r,g,l:byte;π        m,n:TColorref;π        vd2:integer;π    beginπ      variance:=max(c-a,d-b) * FUZZ1 div FUZZ2;π      vd2:=variance div 2;π      m:=getpixel(adc,(a),(b));π      n:=getpixel(adc,(c),(d));π      r:=clamp(((getrvalue(m) + getrvalue(n)) div 2{ + (random(variance))-vd2}));π      g:=clamp(((getgvalue(m) + getgvalue(n)) div 2{ + (random(variance))-vd2}));π      l:=clamp(((getbvalue(m) + getbvalue(n)) div 2{ + (random(variance))-vd2}));π      ridge:=rgb(r,g,l);π    end;ππ    function shift(a,b,c,d:integer; col:tcolorref):tcolorref;π    var variance:integer;π        r,g,l:byte;π        vd2:integer;π    beginπ{      variance:=max(d-b,c-a) * FUZZ1 div FUZZ2;}π      variance:=(c-a) * FUZZ1 div FUZZ2;π      vd2:=variance div 2;π      r:=clamp(getrvalue(col) + (random(variance))-vd2);π      g:=clamp(getgvalue(col) + (random(variance))-vd2);π      l:=clamp(getbvalue(col) + (random(variance))-vd2);π      shift:=rgb(r,g,l);π    end;ππ    procedure quarter(l,t,r,b:integer);π    var mx,my,width,colour,variance:integer;π        mzr,mzg,mzb:byte;π        c:char;π        m,n,o,p,tc:TColorRef;π        vd2:integer;π        abrush:hbrush;π    beginπ      width:=r-l;π      if (width>1) or (b-t>1) thenπ        beginπ        variance:=width * FUZZ1 div fuzz2 ;π        vd2:=variance div 2;π        mx:=mid(l,r);π        my:=mid(t,b);π        m:=getpixel(adc,l,t);π        n:=getpixel(adc,l,b);π        o:=getpixel(adc,r,t);π        p:=getpixel(adc,r,b);π        mzr:=clamp((getrvalue(m) + getrvalue(n) + getrvalue(o) + getrvalue(p)) div 4 + random(variance)-vd2);π        mzg:=clamp((getgvalue(m) + getgvalue(n) + getgvalue(o) + getgvalue(p)) div 4 + random(variance)-vd2);π        mzb:=clamp((getbvalue(m) + getbvalue(n) + getbvalue(o) + getbvalue(p)) div 4 + random(variance)-vd2);ππ        setpixel(adc,mx,my,rgb(mzr,mzg,mzb));π        setpixel(adc,(l),(my),ridge(l,t,l,b));π        setpixel(adc,(r),(my),ridge(r,t,r,b));π        setpixel(adc,(mx),(t),ridge(l,t,r,t));π        setpixel(adc,(mx),(b),ridge(l,b,r,b));ππ        quarter(l,t,mx,my);π        quarter(l,my,mx,b);π        quarter(mx,t,r,my);π        quarter(mx,my,r,b);π        end;π    end;ππbeginπ  ADC:=getdc(HWindow);π  randomize;π  maxx:=width-1; maxy:=height-1;π  backg:=getpixel(ADC,10,10);π  setpixel(adc,0,0,randomcolour);π  setpixel(adc,0,maxy,randomcolour);π  setpixel(adc,maxx,0,randomcolour);π  setpixel(adc,maxx,maxy,randomcolour);π  setpixel(adc,mid(0,maxx),0,randomcolour);π  setpixel(adc,mid(0,maxx),maxy,randomcolour);π  setpixel(adc,0,mid(0,maxy),randomcolour);π  setpixel(adc,maxx,mid(0,maxy),randomcolour);π  quarter(0,0,maxx,maxy);π  end;ππprocedure TPlasmaWindow.WMRButtonDown(var Msg:TMessage);πbeginπ  destroy;πend;ππfunction TPlasmaWindow.getclassname:pchar;πbeginπ  getclassname:='Cloud Window';πend;ππprocedure TPlasmaWindow.getwindowclass(var awndclass:twndclass);πbeginπ  inherited getwindowclass(awndclass);π  awndclass.hbrbackground:=getstockobject(white_brush);πend;ππvar DitherApp:TMyApp;ππbeginπ  DitherApp.init('Cloud');π  DitherApp.run;π  DitherApp.done;πend.π              90     05-25-9408:20ALL                      KAARE BOEEGH             RE: PLASMA  (revisited)  SWAG9405            31     ╓   {π{TITLE: Plasma  FROM: Kaare Boeegh  DATE: Sun Apr 17 1994 08:25 pm}π{$A+,B-,D-,E-,F+,G+,I-,L-,N-,O-,R-,S-,V-,X-}πPROGRAM plasma;ππCONST ys : BYTE = 0;π      yt : BYTE = 255;ππVAR ft   : ARRAY [0..512] OF BYTE;π    sint : ARRAY [0..256] OF BYTE;π    i1,a,b,d,c,od,color,e,y : BYTE;π    x,k,i                   : WORD;ππPROCEDURE do_tables;π  VAR i : WORD;π  BEGINπ    FOR i := 0 TO 512 DO   FT [i] := ROUND(64+63*SIN(i/40.74));π    FOR i := 0 TO 256 DO SINT [i] := ROUND(128+127*SIN(i/40.74))-1;π  END;ππPROCEDURE do_palette;π  VAR i : WORD;π  BEGINπ    PORT[$3C8] := 0;π    FOR i := 0 TO 255 DOπ      BEGINπ        PORT[$3C9] := i DIV 4;π        PORT[$3C9] := i DIV 6;π        PORT[$3C9] := i DIV 8;π      END;π  END;ππBEGINπ  ASMπ    mov al,ysπ    mov y,alπ    mov ax,0013h;π    int 10h;      {Set Mode $13}ππ    mov dx,3d4h   {Go into Double Height Pixel Mode}π    mov al,9π    out dx,alπ    inc dxπ    in al,dxπ    and al,0e0hπ    add al,3π    out dx,alππ    call do_palette;π    call do_tables;ππ@3: inc i1  {Main Loop}                                          {Grid Counter}π    sub c,2π    inc odπ    mov al,odπ    mov d,alππ    mov al,ys                          {Alternate Starting Position every pass}π    mov ah,ytπ    xchg al,ahπ    mov ys,alπ    mov ah,ytπ    mov y,alππ  @2: mov al,y                 {Calculate Offset and add one every second line}π      mov bx,320π      mul bxπ      mov bx,axπ      mov al,yπ      mov ah,0π      and al,1π      add ax,bxπ      mov k,axππ      mov al,i1                   {move grid one pixel down every second frame}π      mov ah,0π      and al,1π      mov ah,0π      mov bx,320π      mul bxππ      mov bx,kπ      sub bx,axπ      mov k,bxππ      mov al,dπ      add al,2π      mov d,alππ      mov al,c           {[(c}π      add al,y           {+y)}π      and ax,255         {and 255]}π      mov di,offset sint {get sint mem location}π      add di,ax          {[c+y] and 255}π      mov al,ds:[di]     {sint[(c+y) and 255]}π      mov a,alππ      mov di,offset sintπ      mov al,dπ      and al,255π      add di,axπ      mov al,ds:[di]π      mov b,alππ      mov ax,0π      mov bx,0π      mov cx,0ππ    @1: mov di,offset ft    {get ft mem location}π        mov al,a            {a}π        add al,b            {+b}π        add di,ax           {[a+b]}π        mov al,ds:[di]      {ft[a+b]}π        mov bx,ax           {Store}π        inc bx              {+1}π        mov di,offset ft    {get ft mem location}π        mov al,y            {y}π        add al,b            {+b}π        add di,ax           {[y+b]}π        mov ax,ds:[di]      {ft[y+b]}π        add ax,bx           {+}π        mov color,al        {color:=}ππ        mov bx,0a000h       {screen memory location}π        mov es,bx           {mov it to es}π        mov di,k            {k is screen offset}πππ        mov es:[di+80],al      {plot color to screen}π                 { ^^ center}π        mov al,bπ        add al,2π        mov b,alππ        mov ax,k {Ofs of Plasma Pixel, Increased by 2 to Create the Grid}π        add ax,2π        mov k,axππ        mov ah,0                                  {INC(a,1+color SHR 7);}π        mov al,colorπ        shr al,7π        add al,1π        mov ah,0π        mov bl,alπ        mov al,aπ        add al,blπ        mov a,alππ        inc cxπ        cmp cx,80  {160}π        jnz @1     {inner loop}ππ      inc yπ      cmp y,101π      jnz @2     {outer loop, number of lines}ππ    mov ah,01hπ    int 16hπ    jz @3      {get keypress}ππ    mov ax,03h {mode 3}π    int 10hπ  END;πEND.π-----------------------------------------------------------------------------πShipleyπ--- Synchronetπ * Origin: The Brook Forest Inn [714] 951-5282 (1:103/950)π                                                                                                                                                           91     05-25-9408:21ALL                      JOHN SHIPLEY             Re: Virtual Reality.     SWAG9405            26     ╓   {πRE: Re: Virtual Reality.πBY: Bas van Gaalen to John Shipley on Fri Mar 25 1994 02:26 pmππ > John Shipley wrote in a message to Bas van Gaalen:π > π >  > I posted it recently, so you must have seen it passing by...π >  JS> You did? I read just about every post you write, I didn'tπ >  JS> see any program by that name come by here.π > π > I suppose it got lost. You're the second... Anyway, I posted it again. Checkπ > previous message... It should be there.ππHello Bas!ππYes, I got it today... basically the problem I saw with the code was lack ofπoptimization and it also looked like you were trying to do too much. Youπdidn't need all the asm. But it could be even faster if you included it. I'mπsending back my modified version of your DYCP program. The "writecharasm"πprocedure was screwed up so I removed it and I will check it out at a laterπtime. I modified the "writechar" procedure which you had commented out.ππ-------8<---------Snip---------8<---------Snip---------8<--------Snip---------ππ{$G+}πPROGRAM different_y_char_position;ππ(* Programmed by Bas van Gaalen, Holland, PD  *)π(* Modified by John Shipley, USA, PD 03/30/94 *)ππUSES CRT;ππCONST vseg : WORD   = $a000;π      txt  : STRING = '**** Well... 38 chars, let''s see. ****';π                   (*  12345678901234567890123456 78901234567890 *)π      txt1 : STRING = 'This is another Strng of 38 Characters';πVAR stab      : ARRAY[0..255] OF BYTE;π    fseg,fofs : WORD;ππPROCEDURE getfont; ASSEMBLER;π  ASMπ    mov ax,1130h;π    mov bh,1;π    int 10h;π    mov fseg,es;π    mov fofs,bp;π  END;ππPROCEDURE csin;π  VAR i : BYTE;π  BEGINπ    for i := 0 to 255 do stab[i] := round(sin(6*i*pi/255)*25)+40;(*150*)π  END;ππPROCEDURE clear(x,y: WORD); ASSEMBLER;π  ASMπ    mov es,vsegπ    mov dx,0π   @lout:π    mov cx,0π   @lin:π    mov ax,yπ    add ax,dxπ    shl ax,6π    mov di,axπ    shl ax,2π    add di,axπ    add di,xπ    add di,cxπ    xor ax,axπ    mov [es:di],axπ    add cx,2π    cmp cx,8π    jne @linπ    inc dxπ    cmp dx,2 (* Was 8 *)π    jne @loutπ  END;ππPROCEDURE writechar(ch: CHAR; x,y: WORD; col: BYTE);π  VAR j,k : BYTE;π      pre : WORD;π      opt : WORD;π  BEGINπ    pre := BYTE(ch)*8; (* Opt *)π    clear(x,y-2);      (* Key *)π    FOR j:=0 TO 7 DOπ      FOR k:=0 TO 7 DOπ        BEGINπ          opt := (y+j)*320+x+k;  (* Opt *)π          IF ((MEM[fseg:fofs+pre+j] SHL k) AND 128)=0 THENπ            MEM[$a000:opt] := 0 (* Key *)π          ELSEπ            MEM[$a000:opt] := col;π        END;π    INC(y,8);   (* Opt *)π    clear(x,y); (* Key *)π  END;ππPROCEDURE dodycp;π  VAR sctr,i,l: BYTE;π      a,b,c : WORD;π  BEGINπ    sctr := 0;π    l := LENGTH(txt); (* Opt *)π    REPEATπ      WHILE (PORT[$3da] AND 8)<>0 DO;π      WHILE (PORT[$3da] AND 8)=0 DO;π      FOR i := 1 TO l DOπ        BEGINπ          a := i*8;π          b := stab[(sctr+2*i) MOD 255];π          c := stab[sctr+i] MOD 64;π          INC(c,32);π          writechar(txt[i],a,b,c);π          INC(b,110);π          writechar(txt1[i],a,b,c);π        END;π      INC(sctr);π    UNTIL KEYPRESSED;π  END;ππBEGINπ  getfont;π  csin;π  ASMπ    mov ax,13h;π    int 10h;π  END;π  dodycp;π  TEXTMODE(lastmode);πEND.π                                                92     05-25-9408:22ALL                      GLEN JEH                 Ribbon scroll..          SWAG9405            21     ╓   π{Ribbon scroller...programmed by Glen Jeh in Turbo Pascal 7.0, 4/24/94π Use freely}ππ{$R+}πprogram RibbonScroll;  {this is IT}πuses Crt, Dos;ππ     { I turned on range checking to slow it down :) }ππconstπ  YLocation = 100;  {position on the screen...}π  Constant = 8;     {mess with this to use different parts of the curve}π  Radius = 30;      {this is how big of a curve you want}π  Width  = 10;      {wrong name..this is actually the waviness of the curve}π  Spacing = 4;      {this is how fat the chars will be..or something}π  Height = 1.5;     {this is how tall each character will be}π  DispStr : string = 'Adjust the above constants <WRAP>...   ';ππ  Rows   = 8; {don't change this}ππ{testing}πtypeπ  CharType = array[1..8] of Byte;π  PathType = array[1..320 div Spacing] ofπ    recordπ      Pos : Word; {position in memory}π      On  : Boolean; {on or off?}π    end;π             {this keeps track of the Y-Pos of the dot at X}πvarπ  CharSet : array[0..255] of CharType absolute $F000:$FA6E;π  PathArray : array[1..Rows] of PathType;π  I,π  I2,π  DispLine : Integer;ππfunction GetNext(Row : Integer) : Boolean;πvarπ  CharNum,π  ColumnNum : Integer;πbeginπ  CharNum := DispLine div 8 + 1;π  ColumnNum := DispLine mod 8 + 1;π  GetNext := CharSet[Ord(DispStr[CharNum])][Row] shr (8 - ColumnNum) and 1 = 1;πend;πππfunction F(X:Real): Real;πbeginπ  F := (Sin ((X + Constant) / Width) * Radius + YLocation)πend;πππprocedure Mode(B : Byte);πvarπ  Regs : Registers;πbeginπ  Regs.ah := 0;π  Regs.al := B;π  Intr($10,Regs);πend;ππprocedure BuildPath;πbeginπ  for I := 1 to Rows doπ    for I2 := 1 to 320 div Spacing doπ      beginπ        PathArray[I][I2].Pos := Round(F(I2+Height*I));π          {compute Y location first}ππ        PathArray[I][I2].Pos :=π          (PathArray[I][I2].Pos - 1) * 320 + (I2 * Spacing) - 1;π          {compute memory location}π      endπend;πππbeginπ  Mode($13);π  BuildPath;π  DispLine := 1;π  repeatπ    repeat until (Port[$3DA] and $08) <> 0;π    for I := 1 to 8 doπ      beginπ        for I2 := 1 to (320 div Spacing) - 1 doπ          PathArray[I][I2].On := PathArray[I][I2 + 1].On;π        PathArray[I][320 div Spacing].On := GetNext(I);π        for I2 := 1 to 320 div Spacing doπ          if PathArray[I][I2].On thenπ            Mem[$A000:PathArray[I][I2].Pos] := I2 mod (100 - 50) + 50π          elseπ            Mem[$A000:PathArray[I][I2].Pos] := 0;π      end;π    Inc(DispLine);π    if DispLine = 8 * Length(DispStr) thenπ      DispLine := 1;π  until KeyPressed;π  Mode($3);πend.π                                        93     05-25-9408:22ALL                      OSCAR WAHLBERT           Multicolour Text Scroll  SWAG9405            17     ╓   πprogram multicolourtextscroll;πuses crt;πconst sseg : word = $b800; hi = 16; wideness = 1;π  txt : string = 'Multicoloured smooth text scroller!   ';π  maxcols = 17; cols : array[0..maxcols] of byte =π    (8, 8, 8, 7, 8, 7, 7, 15, 7, 15, 15, 15, 7, 15, 7, 7, 8, 7);πvar idx : word; i, cur, line, bitpos : byte;π    ccol : byte; colw : byte; ch : char;ππprocedure retrace; assembler;πasmπ  mov dx,3dah;π  @l1: in al,dx; test al,8; jnz @l1;π  @l2: in al,dx; test al,8; jz @l2;πend;ππprocedure movecharsleft(startingrow : word); assembler;πasmπ  push  ds;π  mov   ax,$b800;π  mov   ds,ax;π  mov   di,2π  @@MoveByte:π    add   di,startingrow;π    mov   al,[ds:di];π    sub   di,2π    mov   [ds:di],al;π    sub   di,startingrow;π    add   di,4π    cmp   di,160π  jl      @@MoveByte;π  pop   dsπend;ππprocedure movecolsright(startingrow : word); assembler;πasmπ  push  dsπ  mov   ax,$b800π  mov   ds,axπ  mov   di,161π  @@MoveByte:π    add   di,startingrowπ    sub   di,4π    mov   al,[ds:di]π    add   di,2π    mov   [ds:di],alπ    sub   di,startingrowπ    cmp   di,0001π  ja      @@MoveByteπ  pop   dsπend;πππbeginπ  textattr := 7; clrscr; ccol := 1; idx := 1; colw := 0;π  repeatπ    inc(colw);π    retrace;π    mem[$b800:hi*160+158] := ord(txt[idx]);π    movecharsleft(hi*160);π    if (colw > 1) then beginπ      colw := 0; inc(ccol);π      mem[$b800:hi*160+1] := cols[ccol mod (maxcols+1)];π      movecolsright(hi*160);π    end;π    if not keypressed then idx := 1 + idx mod length(txt);π  until keypressed;π  while keypressed do ch := readkey; textattr := 7; clrscr;πend.ππThe push/pop ds might be superfluous... I don't know if you need them or not...πI'm just starting assembly, you know.  :^)πIt's kinda like the one you made, but it doesn't lock up on my computer -- youπcan't check port[$60] on XTs.  :^)πAnd in this, the colours move one way, and the text, the other.  It's kindaπdistracting when you're trying to read the scroll, but oh well...πC-YA.ππ                                                                                        94     05-25-9408:23ALL                      PIETER KIRKHAM           Faster Sprites           SWAG9405            32     ╓   {π  For the people who requested a faster sprite drawing program, here it is.πThis program is just Bas van Gaalen's sprite program with a few modificationsπto make it run quicker.  I am currently working on this program, so that itπwill be able to handle more sprites than one..ππ------------------- CUT HERE ----------------------π}ππPROGRAM Game_sprites;π{ By Bas van Gaalen, Holland, PD }π{$G+}ππUSES crt;ππCONST w=16; h=16; sega000= $0A000;ππTYPEπ  SPRBUF = Array[1..256] of Byte;ππVARπ  Bckbuf,Sprite : SPRBUF;π  px,py : Word;π  CCOS,CSIN : Array [0..360] of WORD;ππCONSTπ  SegS : Word = SEG(Sprite);π  OfsS : Word = OFS(Sprite);π  SegB : Word = SEG(BckBuf);π  OfsB : Word = OFS(BckBuf);πππPROCEDURE setpal(col,r,g,b : byte); assembler;πASMπ  mov dx,03c8hπ  mov al,colπ  out dx,alπ  inc dxπ  mov al,rπ  out dx,alπ  mov al,gπ  out dx,alπ  mov al,bπ  out dx,alπEND;ππPROCEDURE retrace; assembler;πASMπ  mov  dx,03dahπ@l2:π  in   al,dxπ  test al,8π  jz   @l2πEND;ππPROCEDURE putsprite(x,y:word);πBEGINπ  ASMπ    CLIπ    PUSH DSπ    MOV  AX,0A000hπ    MOV  ES,AXπ    MOV  DS,SegBπ    MOV  AX,PYπ    SHL  AX,6π    MOV  DI,AXπ    SHL  AX,2π    ADD  DI,AXπ    ADD  DI,PXπ    MOV  DX,1010hπ    MOV  AX,OfsBπ    MOV  SI,AXπ    XOR  AX,AXπ@1:π    MOV  AL,[DS:SI]     { Display the sprite buffer over the old sprite }π    MOV  [ES:DI],ALπ    INC  DIπ    INC  SIπ    DEC  DLπ    JNZ  @1π    ADD  DI,304π    MOV  DL,16π    DEC  DHπ    JNZ  @1π    MOV  AX,Yπ    SHL  AX,6π    MOV  DI,AXπ    SHL  AX,2π    ADD  DI,AXπ    ADD  DI,Xπ    MOV  DX,1010hπ    MOV  AX,OfsBπ    MOV  SI,AXπ    XOR  AX,AXπ@2:                           { Store the background into the Sprite Buffer }π    MOV  AL,[ES:DI]π    MOV  [DS:SI],ALπ    INC  DIπ    INC  SIπ    DEC  DLπ    JNZ  @2π    ADD  DI,304π    MOV  DL,16π    DEC  DHπ    JNZ  @2π    MOV  AX,Yπ    SHL  AX,6π    MOV  DI,AXπ    SHL  AX,2π    ADD  DI,AXπ    ADD  DI,Xπ    MOV  DX,1010hπ    MOV  AX,OfsSπ    MOV  SI,AXπ    XOR  AX,AXπ@3:π    CMP  [DS:SI],AH      { Display the Sprite at it's new location }π    JZ   @4π    MOV  AL,[DS:SI]π    MOV  [ES:DI],ALπ@4:π    INC  DIπ    INC  SIπ    DEC  DLπ    JNZ  @3π    ADD  DI,304π    MOV  DL,16π    DEC  DHπ    JNZ  @3π    POP  DSπ    STIπ  END;π  px:=x; py:=y;πEND;ππ(* This procedure I added to speed up the rotation used when displaying theπsprite.  This is not nessary, but usefull *)ππPROCEDURE Calc_Cos_Sin;πVAR I : word;πBEGINπ  FOR I := 0 to 360 DOπ  BEGINπ    CCOS[I] := ROUND(COS(PI*I/180)*150);π    CSIN[I] := ROUND(SIN(PI*I/180)*75);π  END;πEND;ππvar i,j:word;ππBEGINπ  ASMπ    mov ax,13hπ    int 10hπ  END;π  Calc_Cos_Sin;π  for i:=1 to 255 do setpal(i,255-i div 6,255-i div 4,20);π  fillchar(bckbuf,sizeof(bckbuf),0);π  { create background }π  for i:=0 to 319 doπ    for j:=0 to 199 doπ      mem[sega000:j*320+i]:=round(5+0.4*i+0.4*j)+random(10);π  { create random sprite }π  randomize;π  for i:=1 to 256 doπ    sprite[i]:=random(255);π  { clear middle part }π  for i:=6 to 10 doπ    for j:=6 to 10 doπ      sprite[j*w+i]:=0;π  i:=0;π  { save first old backup screen }π  px:=0; py:=0;ππ(*  The following assembly code is required to save the sprites background whenπit is first displayed.  I am still trying to figure how to incorperate thisπinto the main assembly code for displaying the sprite *)ππ  ASMπ    CLIπ    PUSH BPπ    PUSH DSππ    MOV  AX,SegA000π    MOV  ES,AXπ    MOV  DS,SegBππ    MOV  AX,0π    SHL  AX,6π    MOV  DI,AXπ    SHL  AX,2π    ADD  DI,AXπ    ADD  DI,0ππ    MOV  DX,1010hπ    MOV  AX,OfsBπ    MOV  BP,AXπ    XOR  AX,AXπ@2:π    MOV  AL,[ES:DI]π    MOV  [DS:BP],ALπ    INC  DIπ    INC  BPπ    DEC  DLπ    JNZ  @2π    ADD  DI,304π    MOV  DL,16π    DEC  DHπ    JNZ  @2ππ    POP  DSπ    POP  BPπ    STIπ  END;π  { move sprite over background }π  repeatπ    retrace;π    putsprite(150+CCOS[I],100+CSIN[I]);π    i:=1+i mod 360;π  until keypressed;π  ASMπ    mov ax,3hπ    int 10hπ  END;πEND.ππ                                                                       95     05-25-9408:23ALL                      ANDREW GOLOVIN           Starry night simulation  SWAG9405            43     ╓   πProgram StarryNight;ππ{ Looks like some late evening in the summer before starry night }π{ But i guess that stars goes brighter much faster than dimmer   }π{ Can you advise me on that fenomenon?                           }ππConstπ  NumberOfStars = 55; { Number of Stars. Can't be greater than 55 }πtypeπ  StarMapArray = Array [0..6,0..4] of Word;π  { Each star allocate rectangle 4 pixels width and 6 pixels height }πconstπ   StarMap : StarMapArray =π         ((0,0,1,0,0),π          (0,0,2,0,0),π          (0,0,3,0,0),π          (1,3,4,3,1),π          (0,0,3,0,0),π          (0,0,2,0,0),π          (0,0,1,0,0));π  { This is picture of one star }πTypeππ  RGBRec = Recordπ    r,g,b: byte;π  end;π  { Palette record }ππ  PStar = ^TStar;   { Star itself }π  TStar = objectπ    Delta: byte;       { Step for brightness change }π    Brightest: RGBRec; { The very brightest color of the star }π    Brighten: Boolean; { Do star go brighter? }π    Number: byte;      { Personal star number }π    Xloc,Yloc: word;   { X,Y location }π    Colors: Array [1..4] of RGBRec;  { Star colors }π    constructor Init(ANumber: Byte);π    procedure Relocate;              { Move star to new position }π    procedure Rotate;                { Change colors step by step }π  end;ππ{..$DEFINE Mono}π{ Define MONO if you whant to see gray-scaled stars }ππfunction keypressed : boolean; assembler;π  asmπ    Mov AH,01hπ    Int 16hπ    JNZ @0π    XOR AX,AXπ    Jmp @1π@0: Mov AL,1π@1:π  end;ππconstructor TStar.Init(ANumber: Byte);π  varπ    cx,cy: word;π  beginπ    Number:=ANumber;π    XLoc:=0;YLoc:=0;π    Relocate;π  end;ππprocedure TStar.Relocate;π  varπ    cx,cy: word;π    cc: byte;π    {$IFDEF Mono}π    mc: byte;π    {$ENDIF}π  beginπ    For cy:=0 to 6 doπ      For cx:=0 to 4 doπ        Mem[$A000:(cx+XLoc)+(cy+Yloc)*320]:=(224+(cy+YLoc) div 8);π    { Restore old background }π    Brighten:=True;π    {$IFDEF Mono}π    mc:=Random(64);π    With Brightest doπ      beginπ        r:=mc;π        g:=mc;π        b:=mc;π      end;π    {$ELSE}π    With Brightest doπ      beginπ        r:=Random(64);π        g:=Random(64);π        b:=Random(64);π      end;π    {$ENDIF}π    Port[968]:=Number*4;π    For cc:=1 to 4 doπ      beginπ        with Colors[cc] doπ          beginπ            r:=0; g:=0; b:=0;π          end;π        Port[969]:=0;π        Port[969]:=0;π        Port[969]:=0;π      end;π    XLoc:=Random(320-5);π    YLoc:=Random(200-7);π    Delta:=Random(5)+1;π    { Delta:=(YLoc Div 40)+1;}π    { Stars near horizont blink rapidly }π    For cx:=0 to 4 doπ      For cy:=0 to 6 doπ        if StarMap[cy,cx]<>0π           thenπ             Mem[$A000:(cx+XLoc)+(cy+Yloc)*320]:=π                 StarMap[cy,cx]+(Number ShL 2)-1;π    { Put star to screen }π  end;ππprocedure TStar.Rotate;π  varπ    cc: byte;π    cx,cy: word;π  beginπ    If Brightenπ       thenπ         beginπ           For cc:=1 to 4 doπ             beginπ               If Colors[5-cc].r+Delta<=Brightest.r div ccπ                  thenπ                    Inc(Colors[5-cc].r,Delta)π                  elseπ                    Colors[5-cc].r:=Brightest.r div cc;π               If Colors[5-cc].g+Delta<=Brightest.g div ccπ                  thenπ                    Inc(Colors[5-cc].g,Delta)π                  elseπ                    Colors[5-cc].g:=Brightest.g  div cc;π               If Colors[5-cc].b+Delta<=Brightest.b div ccπ                  thenπ                    Inc(Colors[5-cc].b,Delta)π                  elseπ                    Colors[5-cc].b:=Brightest.b div cc;π             end;π           if (Colors[4].r=Brightest.r) andπ              (Colors[4].g=Brightest.g) andπ              (Colors[4].b=Brightest.b)π              thenπ                Brighten:=Falseπ         endπ       elseπ         beginπ           For cc:=1 to 4 doπ             beginπ               If Colors[cc].r>=Deltaπ                  thenπ                    Dec(Colors[cc].r,Delta)π                  elseπ                    Colors[cc].r:=0;π               If Colors[cc].g>=Deltaπ                  thenπ                    Dec(Colors[cc].g,Delta)π                  elseπ                    Colors[cc].g:=0;π               If Colors[cc].b>=Deltaπ                  thenπ                    Dec(Colors[cc].b,Delta)π                  elseπ                    Colors[cc].b:=0;π             end;π           if (Colors[4].r=0) and (Colors[4].g=0) and (Colors[4].b=0)π              thenπ                Relocate;π         end;π      Port[968]:=Number*4;π      For cc:=1 to 4 doπ        beginπ          Port[969]:=Colors[cc].r;π          Port[969]:=Colors[cc].g;π          Port[969]:=Colors[cc].b;π        end;π  end;ππvarπ  StarArray: Array [1..NumberOfStars] of PStar;π  sc: byte;π  c: char;π  ccx,ccy: word;ππbeginπ  asm mov ax,13h; int 10h end;π  port[968]:=224;π  for ccx:=1 to 255-224 doπ    beginπ      port[969]:=ccx div 2;π      port[969]:=0;π      port[969]:=ccx;π    end;π  For ccx:=0 to 319 doπ    For ccy:=0 to 199 doπ      Mem[$A000:(ccx+ccy*320)]:=(224+ccy div 8);π  { This make a background or backsky as you like }ππ  for sc:=1 to NumberOfStars doπ    beginπ      StarArray[sc]:=New(PStar,Init(sc));π    end;π  sc:=1;π  repeatπ    StarArray[sc]^.Rotate;π    If sc=NumberOfStarsπ       thenπ         sc:=1π       elseπ         Inc(sc);π  until keypressed;πend.π                                                                          96     05-25-9408:25ALL                      ALEX CHALFIN             Wormhole                 SWAG9405            14     ╓   {πMSGID: 1:108/180 868965DBπWell, here is the cool wormhole program that everybody has been awaiting.ππIt consists of three programs, WGEN, PGEN, and WORMHOLE. The WGen programπgenerates the data file for the wormhole. PGen generates a palette fileπfor the wormhole. WORMHOLE actually runs the program once everything is done.ππ************  Listing of WGEN.PASπ}ππ{$N+,E+,G+}πProgram WGen;π{actually generates the Wormhole, SLOW}π{ math co-processor HIGHLY recommended }ππUses Crt;ππConstπ  Stretch = 25;     XCenter = 160;π  YCenter = 50;     DIVS = 1200;π  SPOKES = 2400;ππProcedure TransArray;ππVarπ  x, y, z : Real;π  i, j, color : Integer;ππBeginπ  For j := 1 to DIVS doπ    Beginπ      For i := 0 to (Spokes-1) doπ        Beginπ          z := (-1.0)+(Ln(2.0*j/DIVS));π          x := (320.0*j/DIVS*cos(2*Pi*i/SPOKES));π          y := (240.0*j/DIVS*sin(2*Pi*i/Spokes));π          y := y-STRETCH*z;π          x := x + XCenter;π          y := y + YCenter;π          Color := (Round(i/8) Mod 15)+15*(Round(j/6) MOD 15)+1;π          if ((X>=0)and(x<320)and(Y>=0)and(y<200))π            Then Mem[$A000:Round(x) + (Round(y) * 320)] := Color;π        End;π    End;πEnd;ππProcedure SaveImage;ππVarπ  i, j : Integer;π  Diskfile : File of Byte;ππBeginπ  Assign(Diskfile, 'Ln.DAT');π  Rewrite(Diskfile);π  For i := 0 to 199 doπ    For j := 0 to 319 doπ      Write(Diskfile, Mem[$A000:j + (320 * i)]);π  Close(Diskfile);πEnd;ππBeginπ  Asm  MOV  AX,$13; INT $10; End;π  FillChar(Mem[$A000:$0000], 64000, 0);π  transarray;π  SaveImage;π  Asm MOV  AX,3; INT $10; End;πEnd.π                                                                                                     97     05-26-9406:18ALL                      PAUL BROMAN              Image to File            IMPORT              11     ╓   {πS> Hi all.. I need some help.. I'm using GetImage to grab a portionπAS> of the graphics screen - so I can use PutImaget to "Paste" it onπAS> the screen later.  My question is : Can this GetImage be saved toπAS> a file & loaded later.. If so how do I save and load it?  I wouldπAS> appreciate any help you can give me ... Angel Sanchez.ππIt sure can.  Take a look at this code:ππTo Save: }ππprogram SaveImage;ππvarπ  upx, lefty, downx, righty: word;π  ScreenCapSize : longint;π  ScreenLoc : pointer;π  CapFile : file;ππScreenCapSize := ImageSize(upx, lefty, downx, righty);πGetMem(ScreenLoc, ScreenCapSize);πGetImage(upx, lefty, downX, rightY, ScreenLoc^);πAssign(CapFile, 'FILENAME.FIL');πRewrite(CapFile, ImageSize(0,0,60,60));πBlockWrite(CapFile, ScreenLoc^, ScreenCapSize);πClose(CapFile);πend.ππprogram LoadImage;ππvarπ  X, Y: word;π  ScreenCapSize : longint;π  ScreenLoc : pointer;π  CapFile : file;ππbeginπScreenCapSize := {Original Size of capture pic}πGetMem(ScreenLoc, ScreenCapSize);πAssign(CapFile, 'FILENAME.FIL');πReset(CapFile, ScreenCapSize);πSeek(CapFile, 1 {Or whichever image to read});πBlockRead(CapFile, ScreenLoc^, ScreenCapSize);πClose(CapFile);πPutImage(X, Y, ScreenLoc^);πend.ππ                                                                            98     05-26-9406:18ALL                      MARTIN RICHARDSON        Screen Dump To File      IMPORT              9      ╓    {π   DUMPSCR.PASπ   Demo to dump a 25 line screen to disk and then restore itπ   By Martin Richardsonπ   (This code is Public Domain... Enjoy!)π }π USES CRT;ππ TYPEπ    ScreenArray = ARRAY[1..25 * 80] OF WORD;π    ScreenPtr = ^ScreenArray;ππ VARπ   _Screen: ScreenPtr;π   fHandle: FILE;π   ScreenRows: BYTE;ππ BEGINπ     IF (LastMode = Mono) THENπ        _Screen := PTR( $B000, 0 )π     ELSEπ        _Screen := PTR( $B800, 0 );ππ     ASSIGN( fHandle, 'DUMP.SCR' );ππ { First we save the screen to the file DUMP.SCR }π     REWRITE( fHandle, 1 );π     BLOCKWRITE( fHandle, _Screen^, SIZEOF( _Screen^ ) );π     CLOSE( fHandle );ππ { Now a little pause as we catch our breath }π     CLRSCR;π     WRITELN( 'Press any key...' );π     WHILE READKEY = #0 DO;ππ { And finally we restore the screen from the file DUMP.SCR }π     RESET( fHandle, 1 );π     BLOCKREAD( fHandle, _Screen^, SIZEOF( _Screen^ ) );π     CLOSE( fHandle );ππ { Another pause to view our handiwork }π     WHILE READKEY = #0 DO;π END.ππ                          99     05-26-9406:20ALL                      SEAN MARTENS             Pascal Image             IMPORT              18     ╓   {π BK> Could someone tell me how to view this image in Turbo Pascal 7.0 ??ππ  Take your data and put it above the following code.π  compile and see your image.π  Please note graphics functions kept a simple as possible. Crux of matterπ  image not programing.ππ  Your data was 1028 bytes long.π  The first four bytes lead to two integer with value 31. ( dimensions)ππ  31*31 = 961.π  1028 - 961 - 4(for dimensions) = 64.ππ  64 = ?ππ  Your image says "Thanks in advance" . Its a pleasure.πππ_________o/_________π         o\π}ππprogram demo;ππUses dos;ππ{cut and paste your data here }ππtypeππ  rgbx_type  = recordπ     red,green,blue,blank : byte;π  end;ππ  rgb_type  = recordπ     red,green,blue,blank : byte;π  end;ππ  img_type = recordπ     width,                                  { dimentions }π     height  : integer;π     data    : array [0..31,0..31] of byte;  { image data }π     pallete : array [0..15] of rgbx_type;   { no supporting evidence      }π                                             { some indexes bigger than 16 }π  end;ππ  screen_type = array [0..199,0..319] of byte;ππvarπ  screen      : screen_type absolute $a000:$0000;π  colours     : array [0..255] of rgb_type;ππprocedure SetPallete(first_colour,num_colours : word);πvarπ  regs  : registers;πbeginπ   regs.ax := $1012;π   regs.cx := num_colours;π   regs.bx := first_colour;π   regs.dx := ofs(colours);π   regs.es := seg(colours);π   intr($10,regs);πend;ππprocedure GraphicsMode;πvarπ  regs  : registers;πbeginπ  regs.ax := $13;π  intr($10,regs);πend;ππprocedure TextMode;πvarπ  regs  : registers;πbeginπ  regs.ax := $3;   { should use a saved mode }π  intr($10,regs);πend;ππprocedure SetPixel(x,y : integer; colour : byte);πbeginπ  screen[y,x] := colour;πend;ππvarπ  i,j   : integer;π  img   : img_type absolute image;π  dump  : char;πbeginπ  graphicsMode;π  for i := 0 to 15 doπ     beginπ        colours[i].red   := img.pallete[i].red;π        colours[i].green := img.pallete[i].green;π        colours[i].blue  := img.pallete[i].blue;π     end;ππ  SetPallete(0,16);π  for i := 1 to 31 doπ     for j := 1 to 31 doπ        SetPixel(i,j,img.data[j,i]);ππ  dump := readkey;π  Textmode;πend.π         100    05-26-9406:20ALL                      KAARE BOEEGH             PLASMA                   IMPORT              15     ╓   {π15 minutes ago I suddenly got a idea to a fullscreen plasma (320*200). ButπI have promised my group mates to do no more plasmas so here it is and itπis all yours. It is not 320*200, because I did not do it in assembler since Iπam not going to use the routine myself, but it should be pretty easy toπconvert.ππ -+--+--+--- CUT -+--+--+--- }ππ PROGRAM _320_100_PLASMA;ππ VARπ  FT :ARRAY [0..511] OF BYTE;π  SINT :ARRAY [0..255] OF BYTE;π  I1,A,B,D,C,OD,COLOR :BYTE;π  X,Y,K,I :WORD;ππ BEGINπ {SET 320*200*256}π  ASMπ    MOV AX,0013H; INT 10H;π   {THIS THINGGY DOUBLES THE HEIGT OF THE PIXELS}π    mov dx,3d4hπ    mov al,9π    out dx,alπ    inc dxπ    in al,dxπ    and al,0e0hπ    add al,3π    out dx,alπ  END;ππ  {DO PALETTE}π  PORT [$3C8]:=0;π  FOR I:=0 TO 255 DOπ    BEGINπ      PORT [$3C9]:=I DIV 4;π      PORT [$3C9]:=I DIV 5;π      PORT [$3C9]:=I DIV 6π    END;ππ  {DO TABLES}π  FOR I:=0 TO 511 DO FT [I]:=ROUND (64+63*SIN (I/40.74));π  FOR I:=0 TO 255 DO SINT [I]:=ROUND (128+127*SIN (I/40.74));ππ  {MAIN LOOP}π  REPEATπ  INC (I1);                    {GRID COUNTER}π  DEC (C,2);π  INC (OD,1);π  D:=OD;π  FOR Y:=0 TO 100 DOπ    BEGINπ       K:=Y*320+Y AND 1;     {CALCULATE OFFSET AND ADD ONE EVERY SECOND LINE}πK:=K-(I1 AND 1)*320;  {MOVE GRID ONE PIXEL DOWN EVERY SECOND FRAME}π       INC (D,2);π       A:=SINT [(C+Y) AND 255];π       B:=SINT [(D) AND 255];π         FOR X:=0 TO 159 DOπ           BEGINπ             COLOR:=FT [A+B]+FT [Y+B];π             MEM [$A000:K]:=COLOR;π             INC (A,1+COLOR SHR 7);π             INC (B,2); INC (K,2);π             {OFFSET OF PLASMA PIXEL, INCREASED BY TWO TO CREATE THE GRID}π           END;π    END;π UNTIL PORT [$60]<128; {EXIT IF KEY PRESSED} END.ππ                                                                                      101    05-26-9410:58ALL                      SEAN WENZEL              GIF Viewing              IMPORT              176    ╓   unit GifUtil;π{ GifUtl.pas - (c)Copyright 1993 Sean Wenzelπ    Users are given the right to use/modify and distribute this source code asπ    long as credit is given where due.  I would also ask that anyone who makesπ    use of this source/program drop me a line at my CompuServe address ofπ    71736,1245.  Just curious...ππ    The unit was written using Borland Pascal v7.0 but I think it should workπ    with Turbo Pascal down to 5.5 at the most (or least?).π    This unit has only been tested on my system - an Everex Tempo 386DXπ    with its built in SVGA adapter.  If anyone finds/fixes any bugs pleaseπ    let me know. (Feel free to send a copy of any code too)π    I have also only tested 3 or 4 256,16, and 2 color interlaced and non-π    interlaced images. (was enough for my needs)πππ    Some of the code is very loosely based on DECODER.C (availble online)π    so credit should be given to Steven A. Bennett and Steve Wilhiteππ    The unit is set up to use BGI256.BGI (inlcuded) which is available on CISπ    in the BPASCAL forum library.  The graphics initialization tries to startπ    up in 640 by 480 mode.  If an error occurs it'll go down to 320x200π    automatically (well - it should).  For higher res modes change the variableπ    GraphMode in the InitGraphics procedure to 3 for 800x600 and 4 for 1024x768.ππ    A sample program (GIF.PAS) is provided to demostrate the use of this unit.π    Basically declare a pointer to the TGIF object then initialize it using aπ    line such as TheGif := New(PGif, Init('agif'));  You can then checkπ    TheGif^.Status for any errors and/or view the GIF headers and ColorTables.π    To switch to Graphics mode and show the GIF image use TheGif^.Decode(True)π    True tells it to beep when done(or boop if some sort of error occured).  π    When finished use Dispose(TheGif, Done) to switch back to textmode and get π    rid of the object.πππ    If anyone cares to speed up the image decoding I'd suggest writingπ    TGIF.NextCode in assembler.  The routine is the most heavily called in theπ    unit while decoding and on my sytem took up about 5 seconds out of 12 whenπ    I profiled it. (send me a copy if you can)ππ    I have practically commented every line so that the source should be veryπ    readable and easy to follow.  Great for learning about GIF's and LZW π    decompression.πππ    Any problems or suggestions drop me a lineππ    Good luck...π                            -Seanππ    (almost forgot)π    "The Graphics Interchange Format(c) is the Copyright property ofπ     CompuServe Incorporated. GIF(sm) is a Service Mark property ofπ     CompuServe Incorporated."ππ}πππ{$R-}   {       range checking off }  { Put them on if you like but it slows down the}π{$S-} { stack checking off }  { decoding  (almost doubles it!) }π{$I-} { i/o checking off }ππinterfaceππuses Objects;ππtypeπ    TDataSubBlock = recordπ        Size: byte;     { size of the block -- 0 to 255 }π        Data: array[1..255] of byte; { the data }π    end;ππconstπ    BlockTerminator: byte = 0; { terminates stream of data blocks }ππtypeπ    THeader = recordπ        Signature: array[0..2] of char; { contains 'GIF' }π        Version: array[0..2] of char;   { '87a' or '89a' }π    end;ππ    TLogicalScreenDescriptor = recordπ        ScreenWidth: word;              { logical screen width }π        ScreenHeight: word;  { logical screen height }π        PackedFields: byte;     { packed fields - see below }π        BackGroundColorIndex: byte;     { index to global color table }π        AspectRatio: byte;      { actual ratio = (AspectRatio + 15) / 64 }π    end;ππconstπ{ logical screen descriptor packed field masks }π    lsdGlobalColorTable = $80;  { set if global color table follows L.S.D. }π    lsdColorResolution = $70;               { Color resolution - 3 bits }π    lsdSort = $08;                                                  { set if global color table is sorted - 1 bit }π    lsdColorTableSize = $07;                { size of global color table - 3 bits }π                                                            { Actual size = 2^value+1    - value is 3 bits }ππtypeπ    TColorItem = record     { one item a a color table }π        Red: byte;π        Green: byte;π        Blue: byte;π    end;ππ    TColorTable = array[0..255] of TColorItem;      { the color table }ππconstπ    ImageSeperator: byte = $2C;ππtypeπ    TImageDescriptor = recordπ        Seperator: byte;                         { fixed value of ImageSeperator }π        ImageLeftPos: word; {Column in pixels in respect to left edge of logical screen }π        ImageTopPos: word;{row in pixels in respect to top of logical screen }π        ImageWidth: word;       { width of image in pixels }π        ImageHeight: word;      { height of image in pixels }π        PackedFields: byte; { see below }π    end;πconstπ    { image descriptor bit masks }π        idLocalColorTable = $80; { set if a local color table follows }π        idInterlaced = $40;                      { set if image is interlaced }π        idSort = $20;                                            { set if color table is sorted }π        idReserved = $0C;                                { reserved - must be set to $00 }π        idColorTableSize = $07;  { size of color table as above }ππ    Trailer: byte = $3B;    { indicates the end of the GIF data stream }ππ{ other extension blocks not currently supported by this unitπ    - Graphic Control extensionπ    - Comment extension           I'm not sure what will happen if these blocksπ    - Plain text extension        are encountered but it'll be interestingπ    - application extension }ππconstπ    ExtensionIntroducer: byte = $21;π    MAXSCREENWIDTH = 800;ππtypeπ    TExtensionBlock = recordπ        Introducer: byte;                               { fixed value of ExtensionIntroducer }π        ExtensionLabel: byte;π        BlockSize: byte;π    end;ππ    PCodeItem = ^TCodeItem;π    TCodeItem = recordπ        Code1, Code2: byte;π    end;ππconstπ    MAXCODES = 4095;        { the maximum number of different codes 0 inclusive }ππππtypeπ    { This is the actual gif object }π    PGif = ^TGif;π    TGif = object(TObject)π        Stream: PBufStream;                                                                     { the file stream for the gif file }π        Header: THeader;                                                                                { gif file header }π        LogicalScreen: TLogicalScreenDescriptor;  { gif screen descriptor }π        GlobalColorTable: TColorTable;            { global color table }π        LocalColorTable: TColorTable;             { local color table }π        ImageDescriptor: TImageDescriptor;        { image descriptor }π        UseLocalColors: boolean;                  { true if local colors in use }π        Interlaced: boolean;                      { true if image is interlaced }π        LZWCodeSize: byte;                       { minimum size of the LZW codes in bits }π        ImageData: TDataSubBlock;                { variable to store incoming gif data }π        TableSize: word;                                                 { number of entrys in the color table }π        BitsLeft, BytesLeft: integer;{ bits left in byte - bytes left in block }π        BadCodeCount: word;          { bad code counter }π        CurrCodeSize: integer;       { Current size of code in bits }π        ClearCode: integer;          { Clear code value }π        EndingCode: integer;         { ending code value }π        Slot: word;                                     { position that the next new code is to be added }π        TopSlot: word;      { highest slot position for the current code size }π        HighCode: word;     { highest code that does not require decoding }π        NextByte: integer;      { the index to the next byte in the datablock array }π        CurrByte: byte;                 { the current byte }π        DecodeStack: array[0..MAXCODES] of byte; { stack for the decoded codes }π        Prefix: array[0..MAXCODES] of word;                     { array for code prefixes }π        Suffix: array[0..MAXCODES] of byte;             { array for code suffixes }π        LineBuffer: array[0..MAXSCREENWIDTH] of byte; { array for buffer line output }π        CurrentX, CurrentY: integer;                                            { current screen locations }π        Status: word;                                                         { status of the decode }π        InterlacePass: byte;    { interlace pass number }π        constructor Init(AGIFName: string);π        destructor Done; virtual;π        procedure Error(What: integer);π        procedure InitCompressionStream;        { initializes info for decode }π        procedure ReadSubBlock;                          { reads a data subblock from the stream }π        function NextCode: word;                                        { returns the next available code }π        procedure Decode(Beep: boolean);        { the actual LZW decoding routine }π        procedure DrawLine;                     { writes the drawline buffer to screen }π        procedure InitGraphics;                 { Initializes Graphics mode }π    end;ππconstπ{ error constants }π    geNoError = 0;                          { no errors found }π    geNoFile = 1;         { gif file not found }π    geNotGIF = 2;         { file is not a gif file }π    geNoGlobalColor = 3;  { no Global Color table found }π    geImagePreceded = 4;  { image descriptor preceeded by other unknown data }π    geEmptyBlock = 5;                       { Block has no data }π    geUnExpectedEOF = 6;  { unexpected EOF }π    geBadCodeSize = 7;    { bad code size }π    geBadCode = 8;                          { Bad code was found }π    geBitSizeOverflow = 9; { bit size went beyond 12 bits }ππimplementationππuses Graph, Crt;ππfunction Power(A, N: real): real;       { returns A raised to the power of N }πbeginπ    Power := exp(N * ln(A));πend;πππ{ TGif }πconstructor TGif.Init(AGIFName: string);πbeginπ    inherited Init;π    if Pos('.',AGifName) = 0 then     { if the filename has no extension add one }π        AGifName := AGifName + '.gif';π    Stream := New(PBufStream, Init(AGifName, stOpen, 2048));π    Stream^.Read(Header, sizeof(Header));                                           { read the header }π    if Header.Signature <> 'GIF' then Error(geNotGIF);                              { is vaild signature }π    Stream^.Read(LogicalScreen, sizeof(LogicalScreen));π    if LogicalScreen.PackedFields and lsdGlobalColorTable = lsdGlobalColorTable thenπ    beginπ        TableSize := trunc(Power(2,(LogicalScreen.PackedFields and lsdColorTableSize)+1));π        Stream^.Read(GlobalColorTable, TableSize*sizeof(TColorItem)); { read Global Color Table }π    endπ    elseπ        Error(geNoGlobalColor);π    Stream^.Read(ImageDescriptor, sizeof(ImageDescriptor)); { read image descriptor }π    if ImageDescriptor.Seperator <> ImageSeperator then                     { verify that it is the descriptor }π        Error(geImagePreceded);π    if ImageDescriptor.PackedFields and idLocalColorTable = idLocalColorTable thenπ    begin                                                               { if local color table }π        TableSize := trunc(Power(2,(ImageDescriptor.PackedFields and idColorTableSize)+1));π        Stream^.Read(LocalColorTable, TableSize*sizeof(TColorItem)); { read Local Color Table }π        UseLocalColors := True;π    endπ    elseπ        UseLocalColors := false;π    if ImageDescriptor.PackedFields and idInterlaced = idInterlaced thenπ    beginπ        Interlaced := true;π        InterlacePass := 0;π    end;π    if (Stream = nil) or (Stream^.Status <> stOk) then{ check for stream error }π        Error(geNoFile);π    Status := 0;πend;ππdestructor TGif.Done;πbeginπ    CloseGraph;π    TextMode(LastMode);π    if Stream <> nil thenπ        Dispose(Stream, Done);π    inherited Done;πend;ππprocedure TGif.Error(What: integer);πbeginπ    Status := What;πend;ππprocedure TGif.InitCompressionStream;πvarπ    I: integer;πbeginπ    InitGraphics;                           { Initialize the graphics display }π    Stream^.Read(LZWCodeSize, sizeof(byte));{ get minimum code size }π    if not (LZWCodeSize in [2..9]) then     { valid code sizes 2-9 bits }π        Error(geBadCodeSize);ππ    CurrCodeSize := succ(LZWCodeSize); { set the initial code size }π    ClearCode := 1 shl LZWCodeSize;    { set the clear code }π    EndingCode := succ(ClearCode);     { set the ending code }π    HighCode := pred(ClearCode);                     { set the highest code not needing decoding }π    BytesLeft := 0;                    { clear other variables }π    BitsLeft := 0;π    CurrentX := 0;π    CurrentY := 0;πend;ππprocedure TGif.ReadSubBlock;πbeginπ    Stream^.Read(ImageData.Size, sizeof(ImageData.Size)); { get the data block size }π    if ImageData.Size = 0 then Error(geEmptyBlock); { check for empty block }π    Stream^.Read(ImageData.Data, ImageData.Size);   { read in the block }π    NextByte := 1;                                  { reset next byte }π    BytesLeft := ImageData.Size;                                                                            { reset bytes left }πend;ππconstπ    CodeMask: array[0..12] of longint = (  { bit masks for use with Next code }π        0,π        $0001, $0003,π        $0007, $000F,π        $001F, $003F,π        $007F, $00FF,π        $01FF, $03FF,π        $07FF, $0FFF);ππfunction TGif.NextCode: word; { returns a code of the proper bit size }πvarπ    Ret: longint;                          { temporary return value }πbeginπ    if BitsLeft = 0 then                                                                            { any bits left in byte ? }π    begin                                   { any bytes left }π        if BytesLeft <= 0 then                                                          { if not get another block }π            ReadSubBlock;π                        CurrByte := ImageData.Data[NextByte]; { get a byte }π        inc(NextByte);                        { set the next byte index }π        BitsLeft := 8;                        { set bits left in the byte }π        dec(BytesLeft);                       { decrement the bytes left counter }π    end;π    ret := CurrByte shr (8 - BitsLeft);                     { shift off any previosly used bits}π    while CurrCodeSize > BitsLeft do        { need more bits ? }π    beginπ        if BytesLeft <= 0 then                                                          { any bytes left in block ? }π            ReadSubBlock;                       { if not read in another block }π        CurrByte := ImageData.Data[NextByte]; { get another byte }π        inc(NextByte);                        { increment NextByte counter }π        ret := ret or (CurrByte shl BitsLeft);{ add the remaining bits to the return value }π        BitsLeft := BitsLeft + 8;                                               { set bit counter }π        dec(BytesLeft);                     { decrement bytesleft counter }π    end;π    BitsLeft := BitsLeft - CurrCodeSize;  { subtract the code size from bitsleft }π    ret := ret and CodeMask[CurrCodeSize];{ mask off the right number of bits }π    NextCode := ret;πend;ππ{ this procedure initializes the graphics mode and actually decodes theπ    GIF image }πprocedure TGif.Decode(Beep: boolean);πvarπ    SP: integer; { index to the decode stack }ππ{ local procedure that decodes a code and puts it on the decode stack }πprocedure DecodeCode(var Code: word);πbeginπ    while Code > HighCode do { rip thru the prefix list placing suffixes }π    begin                    { onto the decode stack }π        DecodeStack[SP] := Suffix[Code]; { put the suffix on the decode stack }π        inc(SP);                         { increment decode stack index }π        Code := Prefix[Code];            { get the new prefix }π    end;π    DecodeStack[SP] := Code;        { put the last code onto the decode stack }π    inc(SP);                                                                        { increment the decode stack index }πend;ππvarπ    TempOldCode, OldCode: word;π    BufCnt: word;           { line buffer counter }π    Code, C: word;π    CurrBuf: word;  { line buffer index }πbeginπ    InitGraphics;                                                   { Initialize the graphics mode and RGB palette }π    InitCompressionStream;    { Initialize decoding paramaters }π    OldCode := 0;π    SP := 0;π    BufCnt := ImageDescriptor.ImageWidth; { set the Image Width }π    CurrBuf := 0;ππ    C := NextCode;                                          { get the initial code - should be a clear code }π    while C <> EndingCode do  { main loop until ending code is found }π    beginπ        if C = ClearCode then   { code is a clear code - so clear }π        beginπ            CurrCodeSize := LZWCodeSize + 1;{ reset the code size }π            Slot := EndingCode + 1;                                 { set slot for next new code }π            TopSlot := 1 shl CurrCodeSize;  { set max slot number }π            while C = ClearCode doπ                C := NextCode;                  { read until all clear codes gone - shouldn't happen }π            if C = EndingCode thenπ            beginπ                Error(geBadCode);   { ending code after a clear code }π                break;                                                  { this also should never happen }π            end;π            if C >= Slot { if the code is beyond preset codes then set to zero }π                then c := 0;π            OldCode := C;π            DecodeStack[sp] := C;                                   { output code to decoded stack }π            inc(SP);                                                { increment decode stack index }π        endπ        else   { the code is not a clear code or an ending code so it must }π        begin  { be a code code - so decode the code }π            Code := C;π            if Code < Slot then     { is the code in the table? }π            beginπ                DecodeCode(Code);                               { decode the code }π                if Slot <= TopSlot thenπ                begin                                           { add the new code to the table }π                    Suffix[Slot] := Code;                   { make the suffix }π                    PreFix[slot] := OldCode;        { the previous code - a link to the data }π                    inc(Slot);                                                              { increment slot number }π                    OldCode := C;                                                   { set oldcode }π                end;π                if Slot >= TopSlot then { have reached the top slot for bit size }π                begin                   { increment code bit size }π                    if CurrCodeSize < 12 then { new bit size not too big? }π                    beginπ                        TopSlot := TopSlot shl 1;       { new top slot }π                        inc(CurrCodeSize)                                       { new code size }π                    endπ                    elseπ                        Error(geBitSizeOverflow); { encoder made a boo boo }π                end;π            endπ            elseπ            begin           { the code is not in the table }π                if Code <> Slot then                    { code is not the next available slot }π                    Error(geBadCode);  { so error out }ππ                { the code does not exist so make a new entry in the code tableπ                 and then translate the new code }π                TempOldCode := OldCode;  { make a copy of the old code }π                while OldCode > HighCode do { translate the old code and place it }π                begin                                   { on the decode stack }π                    DecodeStack[SP] := Suffix[OldCode]; { do the suffix }π                    OldCode := Prefix[OldCode];         { get next prefix }π                end;π                DecodeStack[SP] := OldCode;     { put the code onto the decode stack }π                                                                        { but DO NOT increment stack index }π                { the decode stack is not incremented because because we are onlyπ                    translating the oldcode to get the first character }π                if Slot <= TopSlot thenπ                begin                 { make new code entry }π                    Suffix[Slot] := OldCode;                 { first char of old code }π                    Prefix[Slot] := TempOldCode; { link to the old code prefix }π                    inc(Slot);                   { increment slot }π                end;π                if Slot >= TopSlot then { slot is too big }π                begin                   { increment code size }π                    if CurrCodeSize < 12 thenπ                    beginπ                        TopSlot := TopSlot shl 1;       { new top slot }π                        inc(CurrCodeSize)                                       { new code size }π                    endπ                    elseπ                        Error(geBitSizeOverFlow);π                end;π                DecodeCode(Code); { now that the table entry exists decode it }π                OldCode := C;     { set the new old code }π            end;π        end;π        { the decoded string is on the decode stack so pop it off and put itπ         into the line buffer }π        while SP > 0 doπ        beginπ            dec(SP);π            LineBuffer[CurrBuf] := DecodeStack[SP];π            inc(CurrBuf);π            dec(BufCnt);π            if BufCnt = 0 then  { is the line full ? }π            beginπ                DrawLine;π                CurrBuf := 0;π                BufCnt := ImageDescriptor.ImageWidth;π            end;π        end;π    C := NextCode;  { get the next code and go at is some more }π    end;            { now that wasn't all that bad was it? }π    if Beep thenπ        if Status = 0 thenπ        beginπ            Sound(660);     { Beep if status is ok }π            Delay(50);π            NoSound;π        endπ        elseπ        beginπ            Sound(110); { Boop if status is not ok }π            Delay(200);π            NoSound;π        end;πend;ππprocedure TGif.DrawLine;πvarπ    I: integer;πbeginπ    for I := 0 to ImageDescriptor.ImageWidth doπ        PutPixel(I, CurrentY, LineBuffer[I]);π    inc(CurrentY);ππ    if InterLaced then     { Interlace support }π    beginπ        case InterlacePass ofπ            0: CurrentY := CurrentY + 7;π            1: CurrentY := CurrentY + 7;π            2: CurrentY := CurrentY + 3;π            3: CurrentY := CurrentY + 1;π        end;π        if CurrentY >= ImageDescriptor.ImageHeight thenπ        beginπ            inc(InterLacePass);π            case InterLacePass ofπ                1: CurrentY := 4;π                2: CurrentY := 2;π                3: CurrentY := 1;π            end;π        end;π    end;πend;ππprocedure TGif.InitGraphics;πvarπ    GraphDriver: integer;π    GraphMode: integer;π    ErrorCode: integer;π    I: integer;πbeginπ    GraphDriver := InstallUserDriver('bgi256', nil);π    GraphMode := 2;π    InitGraph(GraphDriver, GraphMode, '\dealer\bin');π    ErrorCode := GraphResult;π    if ErrorCode <> grOk thenπ    beginπ        Writeln('Graphics Error: ', GraphErrorMsg(ErrorCode));π        Halt(99);π    end;ππ    { the following loop sets up the RGB palette }π    if not UseLocalColors thenπ        for I := 0 to TableSize - 1 doπ            SetRGBPalette(I, GlobalColorTable[I].Red div 4, GlobalColorTable[i].Greenπ                div 4, GlobalColorTable[I].Blue div 4)π    elseπ        for I := 0 to TableSize - 1 doπ            SetRGBPalette(I, LocalColorTable[I].Red div 4, LocalColorTable[i].Greenπ                div 4, LocalColorTable[I].Blue div 4);πend;πππend.ππ{ --------------------------   DEMO PROGRAM  ------------------ }ππprogram Gif;π{ GifUtil sample programπ    (c)Copyright 1993 Sean Wenzelπ    Users are given the right to freely use and distibute the source code atπ    will as long a credit is given where due }ππuses GifUtil, CRT, Dos;ππvarπ    A: string;π    TheGif: PGif;π    Hours, Minutes, Seconds, Sec100: word;π    H, M, S, S100: word;πbeginπ    Writeln('Sample program for using GIFUTIL.PAS unit');π    Writeln('(c) Copyright 1993 Sean Wenzel');π    Writeln('');ππ    if ParamCount <> 1 thenπ    beginπ        Writeln('use: C:>gif <gifname>[.gif] to run...');π        Exit;π    end;π    TheGif := New(PGif, Init(paramstr(1)));ππ    GetTime(Hours, Minutes, Seconds, Sec100);π    TheGif^.Decode(True);π    GetTime(H, M, S, S100);π    Readln(A);π    Dispose(TheGif, Done);ππ    Writeln('Start: ',Hours,':',Minutes,':',Seconds,':',Sec100);π    Writeln(' Stop: ',H,':',M,':',S,':',S100);π    while not(KeyPressed) do;ππ    writeln('"The Graphics Interchange Format(c) is the Copyright property of');π    writeln('CompuServe Incorporated. GIF(sm) is a Service Mark property of ');π    writeln('CompuServe Incorporated."');πend.                                     102    08-24-9412:55ALL                      DAVID ROZENBERG          3D Rotation Objects      SWAG9408    Ü▐j╜    61     ╓   π{ Here is a program to rotate any object in 3D. }ππ(********************************************************π * This program was written by David Rozenberg          *π *                                                      *π * The program show how to convert a 3D point into a 2D *π * plane like the computer screen. So it will give you  *π * the illusion of 3D shape.                            *π *                                                      *π * You can rotate it by the keyboard arrows, for nonstop*π * rotate press Shift+Arrow                             *π *                                                      *π * Please use the program as it is without changing it. *π *                                                      *π * Usage:                                               *π *   3D FileName.Ext                                    *π *                                                      *π * There are some files for example how to build them   *π * the header " ; 3D by David Rozenberg " must be at the*π * beging of the file.                                  *π *                                                      *π ********************************************************)ππProgram G3d;π{$E+,N+}πUsesπ Crt,Graph;ππTypeπ  Coordinate = Array[1..7] of Real;π  Point = Recordπ            X,Y,Z : Real;π          End;π  LineRec = ^LineType;π  LineType = Recordπ               FPoint,TPoint : Point;π               Color : Byte;π               Next  : LineRec;π             End;πππVarπ  FirstLine : LineRec;π  Last      : LineRec;ππProcedure Init;πVarπ  GraphDriver,GraphMode,GraphError : Integer;ππBeginπ  GraphDriver:=Detect;π  initGraph(GraphDriver,GraphMode,'\turbo\tp');  { your BGI driver address }π  GraphError:=GraphResult;π  if GraphError<>GrOk then beginπ    clrscr;π    writeln('Error while turning to graphics mode.');π    writeln;π    halt(2);π  end;πEnd;πππFunction DegTRad(Deg : Real) : real;πBeginπ  DegTRad:=Deg/180*Pi;πEnd;ππProcedure ConvertPoint (P : Point;Var X,Y : Integer);πVarπ  Dx,Dy : Real;ππBeginπ  X:=GetMaxX Div 2;π  Y:=GetMaxY Div 2;π  Dx:=(P.Y)*cos(pi/6);π  Dy:=-(P.Y)*Sin(Pi/6);π  Dx:=Dx+(P.X)*Cos(pi/3);π  Dy:=Dy+(P.X)*Sin(Pi/3);π  Dy:=Dy-P.Z;π  X:=X+Round(Dx);π  Y:=Y+Round(Dy);πEnd;ππProcedure DrawLine(Lrec : LineRec);πVarπ  Fx,Fy,Tx,Ty : Integer;ππBeginπ  SetColor(Lrec^.Color);π  ConvertPoint(LRec^.FPoint,Fx,Fy);π  ConvertPoint(LRec^.TPoint,Tx,Ty);π  Line(Fx,Fy,Tx,Ty);πEnd;ππProcedure ShowLines;πVarπ  Lp : LineRec;ππBeginπ  ClearDevice;π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    DrawLine(Lp);π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure Error(Err : Byte;S : String);πBeginπ  Clrscr;π  Writeln;π  Case Err ofπ    1 : Writeln('File : ',S,' not found!');π    2 : Writeln(S,' isn''t a 3d file!');π    3 : Writeln('Error in line :',S);π    4 : Writeln('No file was indicated');π  End;π  Writeln;π  Halt(Err);πEnd;ππProcedure AddLine(Coord : Coordinate);πVarπ  Lp : LineRec;ππBeginπ  New(Lp);π  Lp^.Color:=Round(Coord[7]);π  Lp^.FPoint.X:=Coord[1];π  Lp^.FPoint.Y:=Coord[2];π  Lp^.FPoint.Z:=Coord[3];π  Lp^.TPoint.X:=Coord[4];π  Lp^.TPoint.Y:=Coord[5];π  Lp^.TPoint.Z:=Coord[6];π  Lp^.Next:=Nil;π  If Last=Nil then FirstLine:=Lp else Last^.Next:=Lp;π  Last:=Lp;πend;ππProcedure LoadFile(Name : String);πVarπ  F : Text;π  Coord : Coordinate;π  S,S1 : String;π  I : Byte;π  LineNum : Word;π  Comma : Integer;ππBeginπ  FirstLine:=Nil;π  Last:=Nil;π  Assign(F,Name);π  {$I-}π  Reset(f);π  {$I+}π  If IoResult<>0 then Error(1,Name);π  Readln(F,S);π  If S<>'; 3D by David Rozenberg' then Error(2,Name);π  LineNum:=1;π  While Not Eof(F) do Beginπ    Inc(LineNum);π    Readln(F,S);π    while Pos(' ',S)<>0 do Delete(S,Pos(' ',S),1);π    If (S<>'') and (S[1]<>';') then beginπ      For I:=1 to 6 do Beginπ        Comma:=Pos(',',S);π        If Comma=0 then Beginπ          Close(F);π          Str(LineNum:4,S);π          Error(3,S);π        End;π        S1:=Copy(S,1,Comma-1);π        Delete(S,1,Comma);π        Val(S1,Coord[i],Comma);π        If Comma<>0 then Beginπ          Close(F);π          Str(LineNum:4,S);π          Error(3,S);π        End;π      End;π      Val(S,Coord[7],Comma);π      If Comma<>0 then Beginπ        Close(F);π        Str(LineNum:4,S);π        Error(3,S);π      End;π      AddLine(Coord);π    End;π  End;π  Close(F);πEnd;ππProcedure RotateZ(Deg : Real);πVarπ  Lp : LineRec;π  Rad : Real;π  Tx,Ty : Real;ππBeginπ  Rad:=DegTRad(Deg);π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    With Lp^.Fpoint Do Beginπ      TX:=(X*Cos(Rad)-Y*Sin(Rad));π      TY:=(X*Sin(Rad)+Y*Cos(Rad));π      X:=Tx;π      Y:=Ty;π    End;π    With Lp^.Tpoint Do Beginπ      TX:=(X*Cos(Rad)-Y*Sin(Rad));π      TY:=(X*Sin(Rad)+Y*Cos(Rad));π      X:=Tx;π      Y:=Ty;π    End;π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure RotateY(Deg : Real);πVarπ  Lp : LineRec;π  Rad : Real;π  Tx,Tz : Real;ππBeginπ  Rad:=DegTRad(Deg);π  Lp:=FirstLine;π  While Lp<>Nil do Beginπ    With Lp^.Fpoint Do Beginπ      TX:=(X*Cos(Rad)-Z*Sin(Rad));π      TZ:=(X*Sin(Rad)+Z*Cos(Rad));π      X:=Tx;π      Z:=Tz;π    End;π    With Lp^.Tpoint Do Beginπ      TX:=(X*Cos(Rad)-Z*Sin(Rad));π      TZ:=(X*Sin(Rad)+Z*Cos(Rad));π      X:=Tx;π      Z:=Tz;π    End;π    Lp:=Lp^.Next;π  end;πEnd;ππProcedure Rotate;πVarπ  Ch : Char;ππBeginπ  Repeatπ    Repeatπ      Ch:=Readkey;π      If ch=#0 then Ch:=Readkey;π    Until Ch in [#27,#72,#75,#77,#80,#50,#52,#54,#56];π    Case ch ofπ      #54 :Beginπ              While Not keypressed do beginπ                RotateZ(10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #52:Beginπ              While Not keypressed do beginπ                RotateZ(-10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #56:Beginπ              While Not keypressed do beginπ                RotateY(10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #50:Beginπ              While Not keypressed do beginπ                RotateY(-10);π                ShowLines;π                Delay(100);π              End;π              Ch:=Readkey;π              If Ch=#0 then Ch:=ReadKey;π            End;π      #72 : Beginπ              RotateY(10);π              ShowLines;π            End;π      #75 : Beginπ              RotateZ(-10);π              ShowLines;π            End;π      #77 : Beginπ              RotateZ(10);π              ShowLines;π            End;π      #80 : Beginπ              RotateY(-10);π              ShowLines;π            End;π    End;π  Until Ch=#27;πEnd;ππBeginπ  If ParamCount<1 then Error(4,'');π  LoadFile(ParamStr(1));π  Init;π  ShowLines;π  Rotate;π  CloseGraph;π  ClrScr;π  Writeln;π  Writeln('Thanks for using 3D');π  Writeln;πEnd.ππThere is sample of some files that can be rotated:πcut out and save in specified file nameπCube.3D:ππ; 3D by David Rozenbergπ; Base of cubeπ-70,70,-70,70,70,-70,15π70,70,-70,70,-70,-70,15π70,-70,-70,-70,-70,-70,15π-70,-70,-70,-70,70,-70,15π; Top of cubeπ-70,70,70,70,70,70,15π70,70,70,70,-70,70,15π70,-70,70,-70,-70,70,15π-70,-70,70,-70,70,70,15π; Side of cubeπ-70,70,-70,-70,70,70,13π70,70,-70,70,70,70,13π70,-70,-70,70,-70,70,13π-70,-70,-70,-70,-70,70,13ππDavid.3D:ππ; 3D by David Rozenbergπ0,-120,45,0,-30,45,15π0,-60,45,0,-60,-45,15π; π0,-15,45,0,15,45,12π0,15,45,0,15,-45,12π;π0,30,45,0,120,45,11π0,90,45,0,90,-45,11π;π50,-45,-75,50,45,-75,10π50,45,-75,50,45,-165,10ππ                                                     103    08-24-9413:26ALL                      JOHN HOWARD              Bounce v1.1              SWAG9408    ░Dp    61     ╓   (*π  From: Christian Ramsvikπ  Subj: bounce    v1.0πOrigin: Hatlane Point #9 (2:211/10.9)ππHI!  Got a bouncing procedure a while ago.  It bounces a ball, and you canπincrease speed in X- and Y-axis by pressing the arrow keys.  I'm sure you canπextract what you need from this one:πππ  From: John Howard  jhπ  Subj: bounce    v1.1πOrigin: Synergy (1:280/66)πUpgraded to vary the ball size with / and *.  Compass directions use keypad inπnumlock mode or UIOJKNM, keys.  The speed can be changed in each direction.πThe gravity effect can vary with + and - keys.  Status report dialog box whenπeither space or 0 key pressed.  Press 0 again will stop all motion.  Pressπkeypad_5 will halt display and requires pressing ESCape key to continue.  Aπperiod will reset the ball to default size.π*)ππprogram Bounce;πuses Crt, Graph;π{-$DEFINE solid}π{-$DEFINE bubble}π{ jhπconstπ     MinBalls = 1;π     MaxBalls = 2;π}πtypeπ    TImage = recordπ               XPos,                   {x}       {horizontal position}π               YPos    : Integer;      {y}       {vertical position}π               XSpeed,                 {dx}      {actually a velocity}π               YSpeed  : Integer;      {dy}      {actually a velocity}π               XAccel,                 {ddx}     {jh unused acceleration}π               YAccel  : Integer;      {ddy}     {jh unused acceleration}ππ               Radius  : Byte;         {Ball}π             end;ππvarπ   Ch     : Char;π   Gd, Gm : Integer;π   Image  : {array [MinBalls..MaxBalls] of} TImage;   {jh}π   FullSpeed,                                         {jh}π   HalfSpeed : Integer;           { = FullSpeed div 2}π   {BallNumber : byte;}                               {jh}ππ{ ******************* DRAW IMAGE ********************* }πprocedure DrawImage;πbeginπ   SetColor( White );π{$IFDEF solid}π   SetFillStyle( SolidFill, White );π{$ELSE}π   SetFillStyle( HatchFill, White );π{$ENDIF}ππ   with Image doπ   beginπ{$IFDEF bubble}π      Circle( XPos, YPos, Radius );              {jh Soap bubble}π{$ELSE}π      PieSlice( XPos, YPos, 0, 360, Radius );    {jh Pattern ball}π{$ENDIF}π   end;πend;ππ{ ******************* REMOVE IMAGE ******************** }πprocedure RemoveImage;πbeginπ   SetColor( Black );π{$IFDEF solid}π   SetFillStyle( SolidFill, Black );π{$ELSE}π   SetFillStyle( HatchFill, Black );π{$ENDIF}ππ   with Image doπ   beginπ{$IFDEF bubble}π      Circle( XPos, YPos, Radius );              {jh Soap bubble}π{$ELSE}π      PieSlice( XPos, YPos, 0, 360, Radius );    {jh Pattern ball}π{$ENDIF}π   end;πend;ππ{ ******************* UPDATE SPEED ******************** }πprocedure UpdateSpeed;ππ         function IntToStr(I: Longint): String;π         { convert any integer to a string }π         var  S: string[11];π         beginπ           Str(I,S);π           IntToStr := S;π         end;πbeginπ   while KeyPressed doπ   beginπ     Ch := ReadKey;π     Ch := Upcase(Ch);π     case Ch of  { Change speed with keypad numbers }π{jh Note: Keypad_5 causes a halt until escape key pressed}ππ         '.': Image.Radius := 16;                   {Default}π         '/': Image.Radius := Image.Radius shr 1;   {Reduce}π         '*': Image.Radius := Image.Radius shl 1;   {Enlarge}π         '+': beginπ                Inc(FullSpeed);π                HalfSpeed := FullSpeed div 2;π              end;π         '-': beginπ                Dec(FullSpeed);π                HalfSpeed := FullSpeed div 2;π              end;π         '8','I': Dec( Image.YSpeed, FullSpeed );   {N upwards}π         '2','M': Inc( Image.YSpeed, FullSpeed );   {S downwards}π         '4','J': Dec( Image.XSpeed, FullSpeed );   {W leftwards}π         '6','K': Inc( Image.XSpeed, FullSpeed );   {E rightwards}π         '0',' ': begin                             {Report statistics}π                    SetColor( White );π                    SetFillStyle( SolidFill, White );π                    Rectangle(8,8,8+160,8+56);                      {box}π                    SetViewPort(8,8,8+160,8+56, ClipOff);           {dialog}π                    OutTextXY(2,2, '<ENTER> resumes');π                    OutTextXY(2,2+8,  'x = ' + IntToStr(Image.XPos));π                    OutTextXY(2,2+16, 'y = ' + IntToStr(Image.YPos));π                    OutTextXY(2,2+24, 'dx = '+ IntToStr(Image.XSpeed));π                    OutTextXY(2,2+32, 'dy = '+ IntToStr(Image.YSpeed));π                    OutTextXY(2,2+40, 'Full Speed = '+ IntToStr(FullSpeed));ππ                    Ch := ReadKey;                 {repeat until keypressed}π                    ClearViewPort;π                    SetViewPort(0,0,GetMaxX,GetMaxY, ClipOn);       {window}π                    Rectangle(0,0,GetMaxX,GetMaxY);                 {border}π                    if (Ch = '0') then              {Stop motion}π                     beginπ                       Image.XSpeed := 0;π                       Image.YSpeed := 0;π                     end;π                  end;π         '7','U': begin                      {NW}π                    Dec(Image.XSpeed, HalfSpeed);π                    Dec(Image.YSpeed, HalfSpeed);π                  end;π         '9','O': begin                      {NE}π                    Inc(Image.XSpeed, HalfSpeed);π                    Dec(Image.YSpeed, HalfSpeed);π                  end;π         '1','N': begin                      {SW}π                    Dec(Image.XSpeed, HalfSpeed);π                    Inc(Image.YSpeed, HalfSpeed);π                  end;π         '3',',': begin                      {SE}π                    Inc(Image.XSpeed, HalfSpeed);π                    Inc(Image.YSpeed, HalfSpeed);π                  end;ππ     end;  {case}π   end;π   Inc( Image.YSpeed, HalfSpeed );  { Gravitation }  {jh Just so it can vary}πend;ππ{ ****************** UPDATE POSITIONS ****************** }πprocedure UpdatePositions;πbeginπ   Inc( Image.XPos, Image.XSpeed );π   Inc( Image.YPos, Image.YSpeed );πend;ππ{ ****************** CHECK COLLISION ******************* }πprocedure CheckCollision;πbeginπ   with Image doπ   beginπ      if ( XPos - Radius ) <= 0 then  { Hit left wall }π         beginπ         XPos   := Radius +1;π         XSpeed := -Trunc( XSpeed *0.9 );π         end;ππ      if ( XPos + Radius ) >= GetMaxX then { Hit right wall }π         beginπ         XPos   := GetMaxX -Radius -1;π         XSpeed := -Trunc( XSpeed *0.9 );π         end;ππ      if ( YPos -Radius ) <= 0 then  { Hit roof }π         beginπ         YPos   := Radius +1;π         YSpeed := -Trunc( YSpeed *0.9 );π         end;ππ      if ( YPos +Radius ) >= GetMaxY then { Hit floor }π         beginπ         YPos   := GetMaxY -Radius -1;π         YSpeed := -Trunc( YSpeed *0.9 );π         end;π   end;πend;ππ{ ********************* PROGRAM ************************ }ππBEGINπ   FullSpeed := 10;π   HalfSpeed := FullSpeed div 2;π   with Image doπ   beginπ      XPos   := 30;π      YPos   := 30;π      XSpeed := FullSpeed;π      YSpeed :=  0;π      XAccel :=  0;             {jh unused}π      YAccel := 10;             {jh unused}ππ      Radius := 16;             {arbitrary}π   end;ππ   Gd := Detect;π   InitGraph( Gd, Gm, '');            {BGI drivers in Current Work Dir (CWD)}π   Gd := GraphResult;π   if (Gd <> grOK) thenπ     beginπ       Gd := Detect;π       InitGraph( Gd, Gm, '\TURBO\TP\');     {BGI drivers in default directory}π     end;π   Rectangle( 0, 0, GetMaxX, GetMaxY );                 {border}π   SetViewPort( 0, 0, GetMaxX, GetMaxY, ClipOn );       {window}ππ   repeatπ      DrawImage;π      Delay( 30 );    {milliseconds Frame delay}π      RemoveImage;ππ      UpdateSpeed;π      UpdatePositions;π      CheckCollision;π   until Ch = Chr( 27 );ππ   CloseGraph;πEND.π                         104    08-24-9413:27ALL                      LUIS MEZQUITA RAYA       Cannon Ball Animation    SWAG9408    ^¬fτ    20     ╓   {π JG> This coding works fine, I would like to make the ball travelπ JG> smoother.  When it travels in the air, its kinda "Chunky"ππ JG> How could you make it so that the computer calculates the nextπ JG> point and make it travel the ball to that point one pixel at aπ JG> time?  Cause with this structure, it kinda "Jumps there"ππ        Try next code and tell me ...π}ππProgram FallingBall;ππ{ Written by Luis Mezquita Raya }ππ{$x+}ππuses  Crt,π      Graph;ππProcedure Init;πvar cg,mg:integer;πbeginπ cg:=Detect;π InitGraph(cg,mg,'\turbo\tp');πend;ππProcedure Wait(msk:byte); assembler;πasmπ        mov dx,3dahπ@Loop1: in al,dxπ        test al,mskπ        jz @Loop1π@Loop2: in al,dxπ        test al,mskπ        jnz @Loop2πend;ππProcedure Calc;πvar angle,power,gravity,a1,a2,a3,y0,n:real;π    size:word;π    ball,mask,bkg:pointer;π    x,y,ox,oy,pause:integer;πbeginππ ClearViewPort;ππ size:=ImageSize(0,0,20,20);π GetMem(ball,size);π GetMem(mask,size);π GetMem(bkg,size);ππ SetFillStyle(SolidFill,Yellow);        { Draw a ball }π Circle(10,10,8);π FloodFill(10,10,White);π GetImage(0,0,20,20,ball^);             { Get the ball }ππ SetFillStyle(SolidFill,White);         { Draw ball's mask }π Bar(0,0,20,20);π SetFillStyle(SolidFill,Black);π SetColor(Black);π Circle(10,10,10);π FloodFill(10,10,Black);π GetImage(0,0,20,20,mask^);             { Get the mask }ππ ClearViewPort;                         { Draw a background }π SetFillStyle(CloseDotFill,LightBlue);π Bar(0,0,GetMaxX,GetMaxY);ππ angle:=35;                             { Init vars }π power:=10;π gravity:=0.1;π y0:=200;π ox:=-1;π n:=0;ππ while n<80 do                          { Main loop }π  beginπ   a1:=cos(angle*pi/180)*power*n;π   a2:=y0-sin(angle*pi/180)*power*n;π   a3:=gravity*n*n;π   x:=Round(a1);π   y:=Round(a2+a3);π   Wait(8);                             { Wait retrace }π   for pause:=0 to 399 do Wait(1);      { Wait scan line }π   if ox<>-1                            { Restore old background }π   then PutImage(ox,oy,bkg^,CopyPut);π   GetImage(x,y,x+20,y+20,bkg^);        { Save background }π   PutImage(x,y,mask^,AndPut);          { Put mask }π   PutImage(x,y,ball^,OrPut);           { Put ball }π   ox:=x;π   oy:=y;π   n:=n+0.2;π  end;ππ FreeMem(ball,size);π FreeMem(mask,size);πend;πππbeginπ Init;π Calc;π ReadKey;π CloseGraph;πend.π                                                                                                                       105    08-24-9413:28ALL                      JOHN HOWARD              Coordinate Systems       SWAG9408    Å∞┼W    70     ╓   {π -=> Quoting Sean Graham to All on 22 Jun 94 <=-π SG> some  (efficient, I would hope) code in pascal that will allow me toπ SG> move in a 2D or  3D 'universe' (or more correctly, grid-system). Let meππ SG> Let's start out easy.  For example, how would I write code to draw aπ SG> line on  a 50x80 (yes, ascii chars) screen from pos A(10,5) to posπ SG> B(47,56)?π SG> Now imagine that my screen has magically grown a third dimention.  Soπ SG> I now  want to draw a line from pos A(47,34,7) to pos B(21,11,33).  Howπ SG> would I write  code to do that?ππ SG> Now picture this, I no longer have a screen, but a grid that worksπ SG> along the same principles as the screen did, except the points rangeπ SG> from -20 to +20 on (x,y,z).  (That gives me a total of 68,921 (41^3)π SG> possible co-ordinates.)π SG> Pretend that Is a universe in space.  I'm in a tiny escape pod andπ SG> must get from co-ordinate (-10,+05,+12) to co-ordinate (+07,+02,-11)ππIf you want to create an actual space, try :π}ππUNIT space;π{ Author: John Howard }π{πDefine a two-dimensional space representation which is used for Cartesian andπPolar coordinate systems.  A three-dimensional space is for Spherical andπAzimuth-Elevation coordinate systems.π}π{ A vector is a one-dimensional array of real numbers.  A matrix has twoπ  dimensions m by n with m rows and n columns.  Notice the row number alwaysπ  comes first in the dimensions and the indices.  Example square matrix A33 =π             [ a11  a12  a13 ]    or generally  A[i, j]; i=rows, j=columns.π             [ a21  a22  a23 ]π             [ a31  a32  a33 ]π  A matrix can be operated upon with appropriate column or row vectors.π}πINTERFACEπ{.$DEFINE D2}                            {remove period to use 2D}π{$IFNDEF D2}πconst N = 3;                             { Cardinality for Three_Vector}π      M = 3;                             { Square matrix for invert routine}π{$ELSE}πconst N = 2;                             { Cardinality for Two_Vector}π      M = 2;                             { Square matrix for invert routine}π{$ENDIF}π   Size = M;πtypeπ   Vector = array [1..N] of real;        { 3D vector is the most common! }π   Matrix = array [1..M, 1..N] of real;  { 3x3 matrix is the most common! }ππ{Store all the components into a vector}π{$IFNDEF D2}π   procedure Set_Value( var a: Vector; x_value, y_value, z_value: real);π{$ELSE}π   procedure Set_Value( var a: Vector; x_value, y_value: real);π{$ENDIF}ππ{Retrieve the value of s from the ith element of a vector}π   function Element( var a: Vector; i: integer): real;ππ{Retrieve the first element from a vector}π   function  X_Component( var a: Vector): real;ππ{Retrieve the second element from a vector}π   function  Y_Component( var a: Vector): real;ππ{Retrieve the third element from a vector}π{$IFNDEF D2}π   function  Z_Component( var a: Vector): real;π{$ENDIF}ππIMPLEMENTATIONππprocedure Set_Value;          { Note: parameter list intentionally left off}πbeginπ      a[1] := x_value;π      a[2] := y_value;π{$IFNDEF D2}π      a[3] := z_value;π{$ENDIF}πend;ππfunction Element( var a: Vector; i: integer): real;πbeginπ      Element := a[i];πend;ππfunction  X_Component( var a: Vector): real;πbeginπ      X_Component := a[1];πend;ππfunction  Y_Component( var a: Vector): real;πbeginπ      Y_Component := a[2];πend;ππ{$IFNDEF D2}πfunction  Z_Component( var a: Vector): real;πbeginπ      Z_Component := a[3];πend;π{$ENDIF}πBEGINπEND.ππ(**********πIf you do not want to create an actual 3d space, just convert coordinates :ππYou could use a two dimensional X_Component and Y_Component calculation to getπyou to an approximate region based upon Z_Component.  Example:ππFrom point A(x1,y1) to B(x2,y2) you travel a distance = sqrt(sqr(x2-x1) +π  sqr(y2-y1)) at a slope of (y2-y1)/(x2-x1).  That slope is called the Tangentπof the angle of inclination of the line AB.ππNow that you know where you are heading and how far away it is you can divideπthe total distance into sections say of unit length.  That means a distance ofπ10 would have ten units.  Every time your spaceship moves one unit in the knownπdirection you can reverse the calculation to find out where you are at.  Whenπyou reach the final distance, you'd take approximations using the thirdπcomponent.  This idea is simple but not very accurate in the interum space.ππYou can use the same idea but implement it with a proper coordinate conversion.π**********)ππUNIT coord;π{ Author: John Howard }π{ Original source: Jack Crenshaw, 1992 Embedded Systems Programming }π{ Space Conversion -- Angles are capitalized }π{ All axes are perpendicular to each other }πINTERFACEπconstπ      Zero = 0.0;π      One  = 1.0;π      TwoPi               = Two * SYSTEM.Pi;π      Pi_Over_Two         = SYSTEM.Pi/Two;ππ{ 1 binary angular measure = 1 pirad = Pi radians = 180 degrees }π      Degrees_Per_Radian  = 180.0/SYSTEM.Pi;π      Radians_Per_Degree  = SYSTEM.Pi/180.0;ππ{ X-axis points east, y-axis north, and angle Theta is the heading measuredπ  north of due east.  If Theta is zero that corresponds to a line runningπ  along the x-axis a radial distance of r.π}πProcedure To_Polar ( x, y: real; Var r, Theta: real);πProcedure From_Polar ( r, Theta: real; Var x, y: real);ππ{ X-axis points toward you, y-axis right, z-axis upward, angle Phi measuresπ  directions in the horizontal (x-y plane) from the x-axis, and angle Thetaπ  measures the direction in the vertical from the z-axis downward.  If Thetaπ  is zero that corresponds to a line pointed up the z-axis.π}πProcedure To_Spherical ( x, y, z: real; Var r, Phi, Theta: real);πProcedure From_Spherical ( r, Phi, Theta: real; Var x, y, z: real);ππ{ X-axis points east, y-axis north, z-axis upward, angle Phi corresponds to anπ  azimuth measured clockwise from due north, and angle Theta is the elevationπ  measured upwards from the horizon (x-y plane).π}πProcedure To_Azimuth_Elevation ( x, y, z: real; Var r, Phi, Theta: real);πProcedure From_Azimuth_Elevation ( r, Phi, Theta: real; Var x, y, z: real);ππFunction Sign ( x, y: real): real;πFunction Degrees ( A: real): real;πFunction Radians ( A: real): real;ππFunction Atan ( x: real): real;           {ArcTangent}πFunction Atan2 ( s, c: real): real;ππIMPLEMENTATIONππ{ Convert from Cartesian to polar coordinates }πProcedure To_Polar ( x, y: real; Var r, Theta: real);πBeginπ  r := Sqrt(Sqr(x) + Sqr(y));π  Theta := Atan2(y, x);πEnd;ππ{ Convert from polar to Cartesian coordinates }πProcedure From_Polar ( r, Theta: real; Var x, y: real);πBeginπ  x := r * Cos(Theta);π  y := r * Sin(Theta);πEnd;ππ{ Convert from Cartesian to spherical polar coordinates }πProcedure To_Spherical ( x, y, z: real; Var r, Phi, Theta: real);πvar  temp: real;πBeginπ  To_Polar(x, y, temp, Phi);π  To_Polar(z, temp, r, Theta);πEnd;ππ{ Convert from spherical polar to Cartesian coordinates }πProcedure From_Spherical ( r, Phi, Theta: real; Var x, y, z: real);πvar  temp: real;πBeginπ  From_Polar(r, Theta, z, temp);π  From_Polar(temp, Phi, x, y);πEnd;ππ{ Convert from Cartesian to Az-El coordinates }πProcedure To_Azimuth_Elevation ( x, y, z: real; Var r, Phi, Theta: real);πvar  temp: real;πBeginπ  To_Polar(y, x, temp, Phi);π  To_Polar(temp, z, r, Theta);πEnd;ππ{ Convert from Az-El to Cartesian coordinates }πProcedure From_Azimuth_Elevation ( r, Phi, Theta: real; Var x, y, z: real);πvar  temp: real;πBeginπ  From_Polar(r, Theta, temp, z);π  From_Polar(temp, Phi, y, x);πEnd;ππ{ Returns Absolute value of x with Sign of y }πFunction Sign ( x, y: real): real;πBeginπ  if y >= Zero thenπ     Sign := Abs(x)π  elseπ     Sign := -Abs(x);πEnd;ππ{ Convert angle from radians to degrees }πFunction Degrees ( A: real): real;πBeginπ  Degrees := Degrees_Per_Radian * A;πEnd;ππ{ Convert angle from degrees to radians }πFunction Radians ( A: real): real;πBeginπ  Radians := Radians_Per_Degree * A;πEnd;ππ{ Inverse Trigonometric Tangent Function }πFunction Atan ( x: real): real;π{  Arctangent algorithm uses fifth-order rational fraction with optimizedπ   coefficientsπ}π   function _Atan ( x: real): real;π   constπ     a = 0.999999447;π     b = 0.259455937;π     c = 0.592716128;ππ   var  y: real;π   beginπ      y := x*x;π      _Atan := a*x*( One + b*y) / ( One + c*y);π   end;ππvar  a, y: real;πBeginπ  y := Abs(x);π  if y <= One thenπ    a := _Atan(y)π  elseπ    a := Pi_Over_Two - _Atan( One / y);π  if x <= Zero thenπ    a := -a;π  Atan := a;πEnd;ππ{ Four-Quadrant Inverse Trigonometric Tangent Function }πFunction Atan2 ( s, c: real): real;πvar  s1, c1, Theta: real;πBeginπ  s1 := Abs(s);π  c1 := Abs(c);π  if c1 + s1 = Zero thenπ    Theta := Zeroπ  else if s1 <= c1 thenπ         Theta := ArcTan(s1 / c1)π       elseπ         Theta := Pi_Over_Two - ArcTan(c1 / s1);π  if c < Zero thenπ    Theta := Pi - Theta;π  Atan2 := Sign(Theta, s);πEnd;πBEGINπEND.π(*****END*****)π                               106    08-24-9413:32ALL                      IAIN WHYTE               DOT Matrix LED Effect    SWAG9408    ╞≥I     218    ╓   unit dotmat; {written by Iain Whyte. (c) 1994 }ππ{ This unit generates a 'dot matrix' LED effect that is very effective. Ifπyou would like to use this code, all that I ask is that you mention itπin the credits somewhere, and let me know what you used it for. If you haveπany suggestions, or you want to talk to me or ask questions, I can beπcontacted at whytei@topaz.ucq.edu.au or ba022@cq-pan.cqu.edu.auπvia the Internet, or by snail-post :ππ          Iain Whyteπ          141 Racecourse Roadπ          Mt Morgan Q4714π          Australia.ππor on the Rockhampton Computer Club BBS, via the programming, IBM/DOS, orπAMIGA conferences... RCC BBS: (079) 276200ππInstructions :ππSelf explanatary, really, there is a sample prog for using this unit at theπof this file..... }ππ{displays upto 10 characters at once, max string size (ATM) is 20 chars....}πππinterfaceππuses dos,crt,graph;ππππprocedure display_dotmat_screen(xpos,ypos:integer);πprocedure create_dotmat(inputstring:string);πprocedure straight_display;πprocedure left_right;πprocedure right_left;πprocedure top_bot;πprocedure bot_top;πprocedure italics;πprocedure random_fade_out;πprocedure random_fade_in;πprocedure fall_away;ππππimplementationπππtypeππletter_set=array[0..8,0..4] of integer;πdotmattype=array[0..8,0..119] of integer;ππconstπ     pixelsize = 2; {size of each LED element i.e. 2 therfore LED is 2x2 pixels}π     a : letter_set = ((0,1,1,1,0),  {each letter is set up as a 5x9 array}π                       (1,0,0,0,1),  {1 means LED is ON, 0 means LED OFF}π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     b : letter_set = ((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0));π     c : letter_set = ((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     d : letter_set = ((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0));π     e : letter_set = ((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     f : letter_set = ((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0));π     g : letter_set = ((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     h : letter_set = ((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     i : letter_set = ((0,1,1,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,1,1,0));π     j : letter_set = ((0,0,1,1,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (0,1,1,0,0));π     k : letter_set = ((1,0,0,0,1),π                       (1,0,0,1,0),π                       (1,0,1,0,0),π                       (1,1,0,0,0),π                       (1,1,0,0,0),π                       (1,1,0,0,0),π                       (1,0,1,0,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1));π     l : letter_set = ((1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     m : letter_set = ((1,0,0,0,1),π                       (1,1,0,1,1),π                       (1,1,1,1,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     n : letter_set = ((1,0,0,0,1),π                       (1,1,0,0,1),π                       (1,1,0,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,0,1,1),π                       (1,0,0,1,1),π                       (1,0,0,0,1));π     o :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     p :  letter_set =((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0));π     q :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,0,0,1,1),π                       (0,1,1,1,1));π     r :  letter_set =((1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,1,1,1,0),π                       (1,1,0,0,0),π                       (1,0,1,0,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1));π     s :  letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (0,1,1,1,0),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     t :  letter_set =((1,1,1,1,1),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0));π     u :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     v :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (0,0,1,0,0));π     w :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,1,0,1,0));π     x :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1));π     y :  letter_set =((1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0));π     z :  letter_set =((1,1,1,1,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     exc :  letter_set =((0,0,1,0,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,1,1,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,0,0),π                       (0,0,1,0,0));π     andm :  letter_set =((0,0,1,1,0),π                       (0,1,0,0,1),π                       (0,0,1,1,0),π                       (0,1,1,1,0),π                       (1,0,0,1,0),π                       (1,0,0,0,1),π                       (1,0,0,1,1),π                       (1,0,0,1,0),π                       (0,1,1,0,1));π     hat :  letter_set =((0,1,0,1,0),π                       (0,1,0,1,0),π                       (1,1,1,1,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (1,1,1,1,1),π                       (0,1,0,1,0),π                       (0,1,0,1,0),π                       (0,1,0,1,0));π     com :  letter_set =((0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,0,0,0),π                       (0,0,1,1,0),π                       (0,0,1,1,0),π                       (0,0,1,0,0),π                       (0,1,1,0,0));π     ast : letter_set=((0,0,0,0,0),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,0,1,0,0),π                       (1,1,1,1,1),π                       (0,0,1,0,0),π                       (0,1,1,1,0),π                       (1,0,1,0,1),π                       (0,0,0,0,0));π     la : letter_set =((0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,0,1));π     ra : letter_set =((1,0,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0));π     one :letter_set =((0,0,1,0,0),π                       (0,1,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,1,1,0));π     two : letter_set=((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,1));π     thr: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,1,1,0),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     four:letter_set =((1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,0,0,1,0),π                       (1,1,1,1,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0));π     five:letter_set =((1,1,1,1,1),π                       (1,0,0,0,0),π                       (1,0,0,0,0),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     six :letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,0),π                       (1,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π     sev :letter_set =((1,1,1,1,1),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0));π    eight:letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   nine : letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,1),π                       (0,0,0,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   zer  : letter_set =((0,1,1,1,0),π                       (1,0,0,1,1),π                       (1,0,0,1,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,0,1,0,1),π                       (1,1,0,0,1),π                       (1,1,0,0,1),π                       (0,1,1,1,0));ππ   smil  :letter_set =((0,1,1,1,0),π                       (1,1,1,1,1),π                       (1,0,1,0,1),π                       (1,1,1,1,1),π                       (1,1,0,1,1),π                       (1,1,1,1,1),π                       (1,0,0,0,1),π                       (1,1,0,1,1),π                       (0,1,1,1,0));π   dol :  letter_set =((0,0,1,0,0),π                       (0,1,1,1,0),π                       (1,0,1,0,1),π                       (1,0,1,0,0),π                       (0,1,1,1,0),π                       (0,0,1,0,1),π                       (1,0,1,0,1),π                       (0,1,1,1,0),π                       (0,0,1,0,0));π   copyr: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (1,0,1,0,1),π                       (1,1,0,1,1),π                       (1,1,0,0,1),π                       (1,1,0,1,1),π                       (1,0,1,0,1),π                       (1,0,0,0,1),π                       (0,1,1,1,0));π   lb:    letter_set =((0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0),π                       (0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0));π   rb:    letter_set =((0,1,0,0,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,1,0,0,0));π   quest: letter_set =((0,1,1,1,0),π                       (1,0,0,0,1),π                       (0,0,0,0,1),π                       (0,0,0,1,0),π                       (0,0,0,1,0),π                       (0,0,1,0,0),π                       (0,0,1,0,0),π                       (0,0,0,0,0),π                       (0,0,1,0,0));πππvarπ  letters:array[' '..'z']of letter_set;π  outchars:array[0..19]of char;π  mainxpos,mainypos:integer;π  dotmatarray:dotmattype;π  dotmatarraymove,dotmatempty:dotmattype;π  counth,countv,lettercount:integer;π  count,count2,countmove,countloop:integer;ππprocedure setup_chars;ππbeginπ     letters['a']:=a;π     letters['b']:=b;π     letters['c']:=c;π     letters['d']:=d;π     letters['e']:=e;π     letters['f']:=f;π     letters['g']:=g;π     letters['h']:=h;π     letters['i']:=i;π     letters['j']:=j;π     letters['k']:=k;π     letters['l']:=l;π     letters['m']:=m;π     letters['n']:=n;π     letters['o']:=o;π     letters['p']:=p;π     letters['q']:=q;π     letters['r']:=r;π     letters['s']:=s;π     letters['t']:=t;π     letters['u']:=u;π     letters['v']:=v;π     letters['w']:=w;π     letters['x']:=x;π     letters['y']:=y;π     letters['z']:=z;π     letters['!']:=exc;π     letters['&']:=andm;π     letters['#']:=hat;π     letters[',']:=com;π     letters['*']:=ast;π     letters['<']:=la;π     letters['>']:=ra;π     letters['1']:=one;π     letters['2']:=two;π     letters['3']:=thr;π     letters['4']:=four;π     letters['5']:=five;π     letters['6']:=six;π     letters['7']:=sev;π     letters['8']:=eight;π     letters['9']:=nine;π     letters['0']:=zer;π     letters['^']:=smil;π     letters['$']:=dol;π     letters['@']:=copyr;π     letters['(']:=lb;π     letters[')']:=rb;π     letters['?']:=quest;πend;ππprocedure display_dotmat_screen(xpos,ypos:integer);ππvar countx,county:integer;ππbeginπ     mainxpos:=xpos;π     mainypos:=ypos;π     setfillstyle(1,8);π     for countx:=0 to 59 doπ     beginπ          for county:=-1 to 9 doπ          beginπ               bar((xpos+(countx*(pixelsize+1))),(ypos+(county*(pixelsize+1))),π                  ((xpos+(countx*(pixelsize+1)))+(pixelsize-1)),((ypos+(county*(pixelsize+1)))+(pixelsize-1)));ππ          end;π     end;πend;πππprocedure convertstring_to_chars(instr:string);ππvar count:integer;π    dummys:string[1];π    strcount:char;ππbeginπ     for count:=1 to 20 doπ     beginππ          dummys:=copy(instr,count,1);π          for strcount:=' ' to 'z' doπ          beginπ               if dummys = strcount then outchars[count-1]:=strcount;π          end;π     end;πend;πππprocedure create_dotmat(inputstring:string);ππbeginπ     for countv:=0 to 8 doπ     for counth:=0 to 119 doπ     dotmatempty[countv,counth]:=0;ππ     setup_chars;π     convertstring_to_chars(inputstring);ππ     for lettercount:=0 to 19 do  {make array of dots from letter data}π     beginππ     for countv:=0 to 8 doπ     beginππ          for counth :=(lettercount*6) to ((lettercount*6)+6) doπ          beginπ              if counth<120 thenπ              beginπ              dotmatarray[countv,counth]:=letters[outchars[lettercount],countv,(counth-lettercount*6)];π              if (counth-lettercount*6) > 4 then dotmatarray[countv,counth]:=0;π              end;π          end;π     end;π     end;ππππend;πππprocedure gen_display;ππbeginππ     for counth:=0 to 59 doπ     beginπ          for countv:=0 to 8 doπ          beginπ               if (counth < 2) or (counth > 57) then setfillstyle(1,2)π               else setfillstyle(1,10);π               if dotmatarraymove[countv,counth] = 1 thenπ               beginπ                  bar((mainxpos+(counth*(pixelsize+1))),(mainypos+(countv*(pixelsize+1))),π                  ((mainxpos+(counth*(pixelsize+1)))+(pixelsize-1)),((mainypos+(countv*(pixelsize+1)))+(pixelsize-1)));π               end;π               setfillstyle(1,8);π               if dotmatarraymove[countv,counth] = 0 thenπ               beginπ                   bar((mainxpos+(counth*(pixelsize+1))),(mainypos+(countv*(pixelsize+1))),π                  ((mainxpos+(counth*(pixelsize+1)))+(pixelsize-1)),((mainypos+(countv*(pixelsize+1)))+(pixelsize-1)));π               end;π          end;π     end;ππend;πππprocedure straight_display;ππbeginπ     dotmatarraymove:=dotmatarray;π     gen_display;πend;ππππprocedure left_right;πbeginππ     for count2:=0 to 119 doπ     beginπ          for count:=0 to 59 doπ          beginπ          countmove:=count+count2;π          if countmove>119 then countmove:=countmove-120;π          for countloop:=0 to 8 do dotmatarraymove[countloop,count]:=dotmatarray[countloop,countmove];ππ          end;π     gen_display;π     delay(5);π     end;πend;πππprocedure right_left;πbeginππ     for count2:=119 downto 0 doπ     beginππ          for count:=0 to 59 doπ          beginπ          countmove:=count+count2;π          if countmove>119 then countmove:=countmove-120;π          for countloop:= 0 to 8 do dotmatarraymove[countloop,count]:=dotmatarray[countloop,countmove];ππ          end;ππ     gen_display;π     delay(5);π     end;πend;πππprocedure top_bot;πbeginπ     dotmatarraymove:=dotmatempty;π     for count2:=-9 to 9 doπ     beginππ          for count:=0 to 8 doπ          beginπ            countmove:=count+count2;π          if countmove>8 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else if countmove<0 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=dotmatarray[countmove,countloop];ππ          end;ππ     gen_display;π     delay(50);π     end;πend;πππprocedure bot_top;πbeginπ     for count2:=9 downto -9 doπ     beginππ          for count:=0 to 8 doπ          beginπ            countmove:=count+count2;π           if countmove>8 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else if countmove<0 then for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=0π          else for countloop:=0 to 119 do dotmatarraymove[count,countloop]:=dotmatarray[countmove,countloop];ππππ          end;ππ     gen_display;π     delay(50);π     end;πππend;ππprocedure italics;πbeginπ     for count:=0 to 8 doπ     beginπ          for count2:=0 to 119 doπ          beginπ               if (count mod 2) = 0 thenπ               beginπ                    dotmatarraymove[count,count2]:=dotmatarray[count,count2+(count div 2)];π               end elseπ                    dotmatarraymove[count,count2]:=dotmatarray[count,count2+((count-1) div 2)];π          end;π     end;π     dotmatarray:=dotmatarraymove;πend;ππππprocedure random_fade_out;ππvarπv,h,rnd,countdots:integer;ππbeginπ     randomize;π     dotmatarraymove:=dotmatarray;π     countdots:=0;π     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarraymove[v,h]=1 thenππ         countdots:=countdots+1;π     end;π     end;π     repeatπ     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarraymove[v,h]=1 thenπ         beginπ              rnd:=random(5);π              if rnd = 1 thenπ              beginπ                   countdots:=countdots-1;π                   dotmatarraymove[v,h]:=0;π              end;π         end;π     end;π     end;ππ     gen_display;π     until countdots<=0;ππend;πππprocedure random_fade_in;πvarπv,h,rnd,countdots:integer;πbeginπ     randomize;π     dotmatarraymove:=dotmatempty;π     countdots:=0;π     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if dotmatarray[v,h]=1 thenππ         countdots:=countdots+1;π     end;π     end;π     repeatπ     for v:=0 to 8 doπ     beginπ     for h:=0 to 119 doπ     beginπ         if (dotmatarray[v,h]=1)and (dotmatarraymove[v,h]=0) thenπ         beginπ              rnd:=random(5);π              if rnd = 1 thenπ              beginπ                   countdots:=countdots-1;π                   dotmatarraymove[v,h]:=1;π              end;π         end;π     end;π     end;ππ     gen_display;π     until countdots<=0;ππend;ππprocedure fall_away;πbeginπ     dotmatarraymove:=dotmatarray;π     for count:=8 downto 0 doπ     beginπ         count2:=count;π         repeatπ              for countloop:=0 to 119 doπ              beginπ                   if count2=count thenπ                   beginπ                   dotmatarraymove[count2,countloop]:=dotmatarray[count,countloop];π                   endπ                   elseπ                   beginπ                   dotmatarraymove[count2,countloop]:=dotmatarray[count,countloop];π                   dotmatarraymove[count2-1,countloop]:=0;π                   end;π              end;π            gen_display;π            delay(5);π         count2:=count2+1;π         until count2=10;ππ     end;πend;πππend.ππ{-------------------------------  DEMO  ----------------------------------}πprogram test_dotmat_unit;ππuses dos,crt,graph,dotmat;ππππvarπ   in1,in2:integer;πππbegin              {12345678901234567890}  {length guide}ππ     initgraph(in1,in2,'c:\bp\bgi');  {initialise 640x480x16c mode bgi}π     cleardevice;πππ     display_dotmat_screen(50,50);    {set_up, display blank LED matrix}ππ     create_dotmat('this is a demo !    '); {loads string into matrix array}ππ     straight_display;       {display on matrix}π     delay(1000);πππ     left_right;             {scroll from left to right}π     delay(1000);ππ     right_left;             {scroll from right to left}ππ     create_dotmat('fading in!           ');  {set up new msg}π     random_fade_in;                          {randomised fade}π     delay(1000);ππ     create_dotmat('fade out!!           ');π     straight_display;π     delay(1000);ππ     random_fade_out;πππ     create_dotmat('can scroll 4 ways!!! ');π     left_right;π     top_bot;       {scroll from top to bottom}π     right_left;π     bot_top;       {scroll from bottom to top}πππ     create_dotmat('italics for the font!'); {create new msg}π     italics;                                {generate italics}π     random_fade_in;π     left_right;π     delay(1000);π     random_fade_out;ππ     create_dotmat('and a special effect ');  {create new msg}π     left_right;π     delay(1000);π     create_dotmat('called fall away!    ');π     left_right;π     delay(1000);π     fall_away;                               {demo Special FX}ππ     create_dotmat('well, what dya think?');π     left_right;π     fall_away;ππ     create_dotmat('@ iain whyte 1994    ');π     random_fade_in;π     left_right;π     right_left;π     random_fade_out;π     top_bot;π     bot_top;ππππ     closegraph;                                    {kill graphics mode}ππend.π                                                                                                  107    08-24-9413:37ALL                      JENS LARSSON             Fast Line Drawing        SWAG9408    òy┴    9      ╓   {π SS> I'm looking for a qwick way to draw a line... All I need areπ SS> horizontal and vertical lines, so would it be easiest to use aπ SS> series of PutPixels?ππUnfortunately you don't specify which mode you're working in, soπI assume it is 320x200 (which tends to be the most popular mode here):π}ππProcedure DHL(x, y, Length : Word; Color : Byte); Assembler;π  Asmπ    mov   ax,0a000hπ    mov   es,axπ    mov   ax,yπ    shl   ax,6π    mov   di,axπ    shl   ax,2π    add   di,axπ    add   di,xπ    mov   cx,Lengthπ    mov   al,Colorπ    cldπ    rep   stosb { I bet I'll get loads of replies which uses stosw instead :) }π  End;ππProcedure DVL(x, y, Length : Word; Color : Byte); Assembler;π  Asmπ    mov   ax,0a000hπ    mov   es,axπ    mov   ax,yπ    shl   ax,6π    mov   di,axπ    shl   ax,2π    add   di,axπ    add   di,xπ    mov   al,Colorπ    mov   cx,Lengthπ@DVL1:π    mov   es:[di],alπ    add   di,320π    dec   cxπ    jnz   @DVL1π  End;ππ                                                                            108    08-24-9413:37ALL                      DAAN DE HAAS             Fast Polygons            SWAG9408    ╠ΘM    105    ╓   {πThis unit draws polygons fast. It draws only polygons which are monotoneπvertical. That means only polygons which you can fill with continues horizontalπlines. Fortunately that are the polygons which are mostly used in 3d graphics.π}ππ{*****************************************************************}π{* UnitName    : FASTPOLY.PAS                                    *}π{* Purpose     : Draw monotone vertical polygons fast            *}π{* Version     : 1.5                                             *}π{* Author      : Daan de Haas                                    *}π{* Date        : 20/10/1993                                      *}π{* Last update :  9/06/1994                                      *}π{* Language    : Borland Turbo Pascal 7.0                        *}π{* Fidonet     : Daan de Haas (2:500/104.6141)                   *}π{* Internet    : Daan.de.Haas@p6141.f104.n500.z2.fidonet.org     *}π{*****************************************************************}ππ{* VGA mode $13 and 386 processor *}π{* Literatur : Dr Dobb's XSharp   *}ππ{$R-,S-,Q-,I-}ππUNIT FastPoly;ππ{**************************} INTERFACE {**************************}ππTYPEπ  PPoint = ^TPoint;π  TPoint = RECORDπ             x,y:integer;π           END;π  PPolygon = ^TPolygon;π  PPointsList = ^TPointsList;π  TPointsList = ARRAY[0..9999] OF TPoint;π  TPolygon = RECORDπ               length,color:word;π               PointPtr:PPointsList;π             END;π  PHLine = ^THLine;π  THLine = RECORDπ             XStart,XEnd:word;π           END;π  PHLineArray = ^THLineArray;π  THLineArray = ARRAY[0..9999] OF THLine;π  THLineList = RECORDπ                 length,YStart:integer;π                 HLinePtr : PHLineArray;π               END;ππPROCEDURE HLine(x1,y1,x2:word; color:word);πPROCEDURE InitPoly(VAR p:TPolygon; len,col:word);πPROCEDURE DonePoly(VAR p:TPolygon);πPROCEDURE FillMonotoneVerticalPolygon(XOffset,YOffset:word;π                                      VertexList:TPolygon);ππCONSTπ  MaxX=320;π  MaxY=200;π  VidSegment=$A000;ππ{************************} IMPLEMENTATION {***********************}ππPROCEDURE HLine; ASSEMBLER;πASMπ  mov ax,x1             { x1 < x2 }π  cmp ax,x2π  jl  @@skip1π  je  @@lijnexitπ  xchg ax,x2π  mov  x1,axπ@@skip1:π  mov ax,maxX           { calculate y1*maxX+x1 }π  mul y1π  add ax,x1π@@1:π  mov di,ax             { dx=segment, di=offset }π  mov ax,VidSegmentππ@@skip2:π  cld                   { forward direction }π  mov cx,x2π  sub cx,x1π  inc cx                { cx = number of pixels in line }π  mov dx,diπ  add dx,cxπ  mov es,ax             { load segment register }π  mov ax,color          { get color into 386 register eax }π  mov ah,alπ  mov dx,axπ  db  $66,$c1,$e0,$10   { shl eax,16 (386 code) }π  mov ax,dxπ  test di,00000011bπ  jz @@skip             { test for doubleword border, if so jump }π@@waitdd:π  mov  es:[di],al       { put one pixel }π  inc  di               { di:=next pixel address }π  test di,00000011b     { doubleword border  ? }π  loopnz @@waitdd       { stop if cx=0 or zeroflag 1 }π  or  cx,cx             { cx=0 ? }π  jz  @@lijnexit        { if so, line is ready }π  cmp cx,4              { is a stosd possible ? }π  jl  @@waitdd          { no, then pixel after pixel }π@@skip:π  mov  dx,cxπ  shr  cx,2π  db   $f3,$66,$AB      { rep stosd (386 code) }π  mov  cx,dxπ  and cx,00000011b      { line finished ? }π  jnz @@waitddπ@@lijnexit:πEND;ππPROCEDURE ScanEdge(x1,y1,x2,y2,SetXStart,SkipFirst:integer;π                   VAR EdgePointPtr:PHLineArray); ASSEMBLER;π{ Scan converts an edge from (X1,Y1) to (X2,Y2), not including theπ point at (X2,Y2). If SkipFirst == 1, the point at (X1,Y1) isn'tπ drawn; if SkipFirst == 0, it is. For each scan line, the pixelπ closest to the scanned edge without being to the left of the scannedπ edge is chosen. Uses an all-integer approach for speed & precision.ππ Edges must not go bottom to top; that is, Y1 must be <= Y2.π Updates the pointer pointed to by EdgePointPtr to point to the nextπ free entry in the array of HLine structures. }ππVARπ  AdvanceAmt,Height:word;ππASMπ les di,EdgePointPtrπ les di,es:[di]  { point to the HLine array }π cmp SetXStart,1      { set the XStart field of each HLineπ     { struc? }π jz @@HLinePtrSet  { yes, DI points to the first XStart }π add di,2   { no, point to the XEnd field of the }π     {  first HLine struc }π@@HLinePtrSet:π mov bx,Y2π sub bx,Y1         { edge height }π jle @@ToScanEdgeExit{ guard against 0-length & horz edges }π mov Height,bx { Height = Y2 - Y1 }π sub cx,cx  { assume ErrorTerm starts at 0 (true if }π                                {  we're moving right as we draw) }π mov dx,1  { assume AdvanceAmt = 1 (move right) }π mov ax,X2π sub ax,X1           { DeltaX = X2 - X1 }π        jz      @@IsVertical   { it's a vertical edge--special case it }π jns @@SetAdvanceAmt { DeltaX >= 0 }π mov cx,1  { DeltaX < 0 (move left as we draw) }π sub cx,bx  { ErrorTerm = -Height + 1 }π neg dx  { AdvanceAmt = -1 (move left) }π        neg     ax              { Width = abs(DeltaX) }π@@SetAdvanceAmt:π mov AdvanceAmt,dxπ{ Figure out whether the edge is diagonal, X-major (more horizontal), }π{ or Y-major (more vertical) and handle appropriately. }π cmp ax,bx  { if Width==Height, it's a diagonal edge }π jz @@IsDiagonal { it's a diagonal edge--special case }π jb @@YMajor { it's a Y-major (more vertical) edge }π    { it's an X-major (more horz) edge }π        sub     dx,dx           { prepare DX:AX (Width) for division }π        div     bx  { Width/Height }π    { DX = error term advance per scan line }π mov si,ax  { SI = minimum # of pixels to advance X }π    { on each scan line }π        test    AdvanceAmt,8000h { move left or right? }π        jz      @@XMajorAdvanceAmtSet   { right, already set }π        neg     si              { left, negate the distance to advance }π    { on each scan line }π@@XMajorAdvanceAmtSet:π mov ax,X1  { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π        jz @@XMajorSkipEntry  { yes }π@@XMajorLoop:π mov es:[di],ax  { store the current X value }π add di,4     { point to the next HLine struc }π@@XMajorSkipEntry:π add ax,si  { set X for the next scan line }π add cx,dx  { advance error term }π jle @@XMajorNoAdvance { not time for X coord to advance one }π    { extra }π add ax,AdvanceAmt { advance X coord one extra }π        sub     cx,Height     { adjust error term back }π@@XMajorNoAdvance:π        dec     bx  { count off this scan line }π        jnz     @@XMajorLoopπ jmp @@ScanEdgeDoneπ@@ToScanEdgeExit:π jmp @@ScanEdgeExitπ@@IsVertical:π mov ax,X1 { starting (and only) X coordinate }π sub bx,SkipFirst { loop count = Height - SkipFirst }π        jz      @@ScanEdgeExit  { no scan lines left after skipping 1st }π@@VerticalLoop:π mov es:[di],ax  { store the current X value }π add di,4 { point to the next HLine struc }π dec bx  { count off this scan line }π jnz @@VerticalLoopπ jmp @@ScanEdgeDoneπ@@IsDiagonal:π mov ax,X1 { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π jz @@DiagonalSkipEntry { yes }π@@DiagonalLoop:π mov es:[di],ax  { store the current X value }π add di,4 { point to the next HLine struc }π@@DiagonalSkipEntry:π add ax,dx  { advance the X coordinate }π dec bx  { count off this scan line }π jnz @@DiagonalLoopπ jmp @@ScanEdgeDoneππ@@YMajor:π push bp { preserve stack frame pointer }π mov si,X1  { starting X coordinate }π        cmp     SkipFirst,1 { skip the first point? }π mov bp,bx { put Height in BP for error term calcs }π        jz @@YMajorSkipEntry { yes, skip the first point }π@@YMajorLoop:π mov es:[di],si { store the current X value }π add di,4 { point to the next HLine struc }π@@YMajorSkipEntry:π add cx,ax  { advance the error term }π jle @@YMajorNoAdvance { not time for X coord to advance }π add si,dx  { advance the X coordinate }π        sub     cx,bp  { adjust error term back }π@@YMajorNoAdvance:π        dec     bx  { count off this scan line }π        jnz     @@YMajorLoopπ pop bp  { restore stack frame pointer }π@@ScanEdgeDone:π cmp SetXStart,1 { were we working with XStart field? }π jz @@UpdateHLinePtr { yes, DI points to the next XStart  }π sub di,2  { no, point back to the XStart field }π@@UpdateHLinePtr:π        mov     bx,word ptr EdgePointPtr { point to pointer to HLine array }π mov ss:[bx],di  { update caller's HLine array pointer }π@@ScanEdgeExit:πEND;ππPROCEDURE DrawHorizontalLineList(VAR list:THLineList; color:word); ASSEMBLER;πASMπ  les si,listπ  mov cx,es:[si]                { cx = number of lines }π  mov ax,es:[si+2]              { ax = startY }π  les si,es:[si+4]              { es:si points to pointlist }π@@loop:π  mov bx,es:[si]                { get startX }π  mov dx,es:[si+2]              { get endX }π  push cx                       { save registers }π  push axπ  push siπ  push esππ  push bx                       { draw horizontal line }π  push axπ  push dxπ  mov  dx,color                 { get color }π  push dxπ  call HLineππ  pop es                        { restore registers }π  pop siπ  pop axπ  pop cxπ  inc ax                        { y:=y+1 }π  add si,4                      { next points }π  loop @@loop                   { if length=0 then stop }πEND;ππPROCEDURE FillMonotoneVerticalPolygon;πVARπ  i,MinIndex,MaxIndex,MinPoint_y,MaxPoint_y,NextIndex,π  CurrentIndex,PreviousIndex:integer;π  WorkingHLineList:THLineList;π  EdgePointPtr:PHLineArray;π  VertexPtr:PPointsList;πBEGINπ  IF VertexList.Length=0 THEN Exit;π  VertexPtr:=VertexList.PointPtr;π  MaxPoint_y:=VertexPtr^[0].y;π  MinPoint_y:=MaxPoint_y;π  MinIndex:=0;π  MaxIndex:=0;π  FOR i:=1 TO VertexList.Length-1 DOπ    WITH VerTexPtr^[i] DOπ      IF y<MinPoint_y THENπ        BEGINπ          MinPoint_y:=y;π          MinIndex:=i;π        ENDπ      ELSEπ        IF y>MaxPoint_y THENπ          BEGINπ            MaxPoint_y:=y;π            MaxIndex:=i;π          END;π  WITH WorkingHLineList DOπ    BEGINπ      length:=MaxPoint_y-MinPoint_y;π      IF length<=0 THEN Exit;π      YStart:=YOffset+MinPoint_y;π      GetMem(HLinePtr,SizeOf(THLine)*length);π      EdgePointPtr:=HLinePtr;π    END;π  CurrentIndex:=MinIndex;π  PreviousIndex:=MinIndex;π  REPEATπ    CurrentIndex:=(CurrentIndex+VertexList.length-1) MOD VertexList.length;π    ScanEdge(VertexPtr^[PreviousIndex].x+XOffset,π             VertexPtr^[PreviousIndex].y,π             VertexPtr^[CurrentIndex].x+XOffset,π             VertexPtr^[CurrentIndex].y,π             1,0,EdgePointPtr);π    PreviousIndex:=CurrentIndex;π  UNTIL CurrentIndex=MaxIndex;π  EdgePointPtr:=WorkingHLineList.HLinePtr;π  CurrentIndex:=MinIndex;π  PreviousIndex:=MinIndex;π  REPEATπ    CurrentIndex:=(CurrentIndex+1) MOD VertexList.length;π    ScanEdge(VertexPtr^[PreviousIndex].x+XOffset,π             VertexPtr^[PreviousIndex].y,π             VertexPtr^[CurrentIndex].x+XOffset,π             VertexPtr^[CurrentIndex].y,π             0,0,EdgePointPtr);π    PreviousIndex:=CurrentIndex;π  UNTIL CurrentIndex=MaxIndex;π  DrawHorizontalLineList(WorkingHLineList,VertexList.color);π  WITH WorkingHLineList DO FreeMem(HLinePtr,SizeOf(THLine)*length);πEND;ππPROCEDURE InitPoly;πBEGINπ  WITH p DOπ    BEGINπ      length:=len;π      color:=col;π      { No Error checking !}π      GetMem(PointPtr,len*SizeOf(TPoint));π    END;πEND;ππPROCEDURE DonePoly;πBEGINπ  WITH p DOπ    BEGINπ      IF PointPtr<>NIL THEN FreeMem(PointPtr,length*SizeOf(TPoint));π      PointPtr:=NIL;π    END;πEND;ππEND.ππ{*****************************************************************}π{* ProgramName : FASTPOL.PAS                                     *}π{* Purpose     : Demonstration of unit FastPoly                  *}π{* Version     : 1.0                                             *}π{* Author      : Daan de Haas                                    *}π{* Date        : 9 jun 1994                                      *}π{* Last update : 9 jun 1994                                      *}π{* Language    : Borland Pascal 7.0                              *}π{* Fidonet     : Daan de Haas (2:500/104.6141)                   *}π{* Internet    : Daan.de.Haas@p6141.f104.n500.z2.fidonet.org     *}π{*****************************************************************}ππ{$R-,I-,Q-,S-}ππUSESπ  Crt, FastPoly;ππPROCEDURE SetVideo(m:word); ASSEMBLER;πASMπ  mov ax,mπ  int $10πEND;ππPROCEDURE Polydemo;πVARπ  p1,p2:TPolygon;πBEGINπ  InitPoly(p1,6,YELLOW);π  p1.PointPtr^[0].X:=10;π  p1.PointPtr^[0].Y:=0;π  p1.PointPtr^[1].X:=20;π  p1.PointPtr^[1].Y:=0;π  p1.PointPtr^[2].X:=30;π  p1.PointPtr^[2].Y:=10;π  p1.PointPtr^[3].X:=20;π  p1.PointPtr^[3].Y:=20;π  p1.PointPtr^[4].X:=10;π  p1.PointPtr^[4].Y:=20;π  p1.PointPtr^[5].X:=0;π  p1.PointPtr^[5].Y:=10;π  InitPoly(p2,6,BLUE);π  p2.PointPtr^[0].X:=10;π  p2.PointPtr^[0].Y:=0;π  p2.PointPtr^[1].X:=20;π  p2.PointPtr^[1].Y:=0;π  p2.PointPtr^[2].X:=30;π  p2.PointPtr^[2].Y:=10;π  p2.PointPtr^[3].X:=20;π  p2.PointPtr^[3].Y:=20;π  p2.PointPtr^[4].X:=10;π  p2.PointPtr^[4].Y:=20;π  p2.PointPtr^[5].X:=0;π  p2.PointPtr^[5].Y:=10;π  REPEATπ    FillMonotoneVerticalPolygon(Random(MaxX-35),Random(MaxY-25),p1);π    FillMonotoneVerticalPolygon(Random(MaxX-35),Random(MaxY-25),p2);π  UNTIL KeyPressed;π  ReadKey;π  DonePoly(p1);π  DonePoly(p2);πEND;ππBEGINπ  ClrScr;π  Randomize;π  SetVideo($13);π  PolyDemo;π  SetVideo(3);πEND.π                                             109    08-24-9413:38ALL                      ALEX CHALFIN             Fire Graphic             SWAG9408    4[╒¿    32     ╓   {πHere is a little something for all you pyromaniacs, and demo coders out there.ππI got my hands on Jare's fire code and thought it was pretty cool, so I madeπmy own fire program. Although it didn't turn out like I thought it would (likeπJare's) what I have is (at least I think so) something that looks moreπrealistic.ππThis program was completely written by myself and was inspired by Jare's fireπcode (available on Internet FTP at ftp.eng.ufl.edu  pub/msdos/demos/programmingπ/source). A 386 computer is required (Double Word copies are used), but a 486πis highly recommended, as 28800 pixels are calculated each frame (I useπstandard mode 13h). The entire source is Pascal/Inline asm and was writtenπusing Turbo Pascal v6.0.    I hope you like it.πππ{ **** Program starts here ******** }ππProgram Phire;π{$G+}    { Enable 286 instructions }π{ coded by Phred  7/23/94     aka Alex Chalfin    }π{               Internet: achalfin@uceng.uc.edu   }π{ A fast computer is HIGHLY recommended.          }π{ Inspired by Jare's fire code                    }ππVarπ  Screen : Array[0..63999] of Byte ABSOLUTE $A000:$0000; { the VGA screen }π  VScreen : Array[0..63999] of Byte;                { an offscreen buffer }π  Lookup : Array[0..199] of Word;    { an Offset lookup table }ππProcedure SetPalette; Near;π{ Sets the Palette }ππVarπ  p : Array[0..767] of Byte;π  x : integer;ππBeginπ  for x := 0 to 255 do            { Generate fade from orange to black }π    Beginπ      p[x*3] := (x * 63) Shr 8;π      P[x*3+1] := (x * 22) Shr 8;π      P[x*3+2] := 0;π    End;π  Port[$3C8] := 0;π  For x := 0 to 255 do        { Set the palette }π    Beginπ      Port[$3C9] := P[x*3];π      Port[$3C9] := P[x*3+1];π      Port[$3C9] := P[x*3+2];π    End;πEnd;ππProcedure Burnin_Down_The_House;ππVarπ  c : Integer;ππBeginπ  Randomize;π  Repeatπ    For c := 0 to 319 do    { Setup bottom line "hot spots" }π      If Random(4) = 1π        Then VScreen[LookUp[199] + c] := Random(3) * 255;π    Asmπ      MOV  CX,28800         { Number of pixels to calculate }π      PUSH CX               { Store count on stack }π      MOV  AX,Offset VScreenπ      PUSH AX               { Store value on stack }π      MOV  SI,AXπ      MOV  BX,199π      SHL  BX,1π      MOV  AX,Word Ptr [LookUp + BX]π      ADD  SI,AXπ      DEC  SI            { DS:SI := VScreen[LookUp[198]+319] }π     @Looper:π      XOR  AX,AXπ      XOR  BX,BXπ      MOV  AL,DS:[SI+319]π      ADD  BX,AXπ      MOV  AL,DS:[SI+320]π      ADD  BX,AXπ      MOV  AL,DS:[SI+321]π      ADD  BX,AXπ      MOV  AL,DS:[SI]π      ADD  BX,AX    { Average the three pixels below and the one that its on}π      SHR  BX,2     { Divide by 4 }π      JZ  @Skipπ      DEC  BX       { Subtract 1 if value > 0 }π     @Skip:π      MOV  DS:[SI],BL  { Store pixel to screen }π      DEC  SI          { Move to next pixel }π      DEC  CXπ      JNZ @Looperπ    { Copy the screen Buffer using Double Word copies }π      MOV  BX,110π      SHL  BX,1π      MOV  AX,Word Ptr [LookUp + BX]π      MOV  DX,AXπ      POP  SI        { Restore starting offset of VScreen  }π      MOV  AX,$A000π      MOV  ES,AX     { DS:SI = starting location in buffer }π      XOR  DI,DI     { ES:DI = Starting location in screen }π      ADD  SI,DXπ      ADD  DI,DXπ      POP  CX        { Retrive Count off the stack }π      SHR  CX,2      { divide by 4 to get # of double words.              }π     db 66h          { Since TP won't allow 386 instructions, fake it.    }π      REP  MOVSW     { This translates into REP MOVSD (move double words) }π    End;π  Until Port[$60] = 1;   { Until ESC is pressed }πEnd;ππBeginπ  Asm              { Initialize mode 13h VGA mode }π    MOV  AX,13hπ    INT  10hπ  End;π  For LookUp[0] := 1 to 199 do            { Calculate lookup table }π    LookUp[LookUp[0]] := LookUp[0] * 320;π  LookUp[0] := 0;π  SetPalette;π  FillChar(VScreen, 64000, 0);π  Burnin_Down_The_House;π  Asmπ    MOV  AX,3π    INT  10hπ  End;πEnd.ππ                                               110    08-24-9413:40ALL                      FRED JOHNSON             FONTS WITH TURBOPASCAL V7SWAG9408    ù┤ƒì    19     ╓   π{compile the *.bgi and *.chr files into a .exe file?  If so how?ππ1. Collect all the fonts you canπ   If you don't have them all, fake it (use old one in place of real one)π2. Compile them separately into OBJ filesπ   example: binobj bold.chr bold.obj boldππ3. DO the BGI driver for your video card.π   example: binobj egavga.bgi egavga.obj egavgaππ4. use the TPUs in your main progπ5. Load the video driver like an external procedure;πππ{-------------------------------example 1 (converts chr->obj->tpu)}ππunit boldfont;   {use the name + font for all of the fonts}ππinterfaceπprocedure bold;πimplementationπprocedure bold; external;π{$L bold.obj}πend.π{------------------------------------------------------------------------}ππ{--------------------------------example 2}πuses graph,π   boldfont, eurofont, gothfont, lcomfont, littfont,π   sansfont, simpfont, scrifont, tripfont, tscrfont;ππprocedure egavga; external;π{$L egavga.obj}ππconstπ   xFonts : array[0..10] of recordπ      sFontName  : string;π      xpFontAddr : pointer;π   end =π   ( {Fonts must remain in this order because of settextstyle()}π   (sFontName :'Default'; xpFontAddr : nil),  {style 00}π   (sFontName :'Triplex'; xpFontAddr : @TRIP),{style 01}π   (sFontName :'Small';   xpFontAddr : @LITT),{style 02}π   (sFontName :'Sans';    xpFontAddr : @SANS),{style 03}π   (sFontName :'Gothic';  xpFontAddr : @GOTH),{style 04}π   (sFontName :'Script';  xpFontAddr : @SCRI),{style 05}π   (sFontName :'Simplex'; xpFontAddr : @SIMP),{style 06}π   (sFontName :'Tscr';    xpFontAddr : @TSCR),{style 07}π   (sFontName :'Lcom';    xpFontAddr : @LCOM),{style 08}π   (sFontName :'Euro';    xpFontAddr : @EURO),{style 09}π   (sFontName :'Bold';    xpFontAddr : @BOLD) {style 10}π   );ππvarπ   gd, gm, i : integer;ππbeginπ   if RegisterBGIDriver(@EGAVGA) < 0 then halt;π   for i := 1 to 10 doπ      if RegisterBGIFont(xFonts[i].xpFontAddr) < 0 thenπ         write('Can''t register', xFonts[i].sFontName,' font');ππ   gd := VGA;π   gm := VGAHi;π   initgraph(gd, gm, '');ππ   for i := 0 to 10 doπ      beginπ         settextstyle(i,0,10);π         outtextxy(10,20,xFonts[i].sFontName);π         readln;π         cleardevice;π      end;π   closegraph;πend.π                                                                                              111    08-24-9413:40ALL                      DAVID DANIEL ANDERSON    Gif info display         SWAG9408    ▓ÆA╨    36     ╓   {πBS> Can anone out there tell me where you get the resoloution out of a Gif fileπBS> from? What I am saying is, I would like to make a program to look at a GifπBS> and grab the resoloution out of it for my dir list files. Any help would beπBS> appreciated.ππI've written a freeware program to do just this.  Program name is GRR,πand Pascal source accompanies it.  Here is the source from the latestπ(and only) version.  I apologize for the lack of comments, but it isπrather straightforward, I think. }ππprogram getGIFheader;πusesπ  dos;πconstπ  progdata = 'GRR- Free DOS utility: GIF file info displayer.';π  progdat2 =π  'V1.00: August 19, 1993. (c) 1993 by David Daniel Anderson - Reign Ware.';π  usage =π  'Usage:  GRR directory and/or file_spec[.GIF]   Example:  GRR cindyc*';πvarπ  header : string[6];π  gpixn : byte;π  gpixels, gback, rwidthLSB, rheightLSB, rwidth, rheight : char;π  gifname : string[12];π  giffile : text;π  dirinfo : searchrec;π  gpath : pathstr;π  gdir : dirstr;π  gname : namestr;π  gext : extstr;ππprocedure showhelp;πbegin {-- showhelp --}π  writeln(progdata);π  writeln(progdat2);π  writeln(usage);π  halt;πend {-- showhelp --};ππfunction taffy(astring : string; newlen : byte) : string;πbegin {-- taffy --}π  while (length(astring) < newlen) doπ    astring := astring + ' ';π  taffy := astring;πend {-- taffy --};ππfunction LeadingZero(w : Word) : string;πvarπ  s : string;πbegin {-- LeadingZero --}π  Str(w : 0, s);π  if (length(s) = 1) thenπ    s := '0' + s;π  LeadingZero := s;πend {-- LeadingZero --};ππprocedure writeftime(fdatetime : longint);πvarπ  Year2 : string;π  DateTimeInf : DateTime;πbegin {-- writeftime --}π  UnpackTime(fdatetime, DateTimeInf);π  with DateTimeInf doπ  beginπ  Year2 := LeadingZero(Year);π  Delete(Year2, 1, 2);π  Write(LeadingZero(Month), '-', LeadingZero(Day), '-', Year2, '  ',π  LeadingZero(Hour), ':', LeadingZero(Min), ':', LeadingZero(Sec));π  end;πend {-- writeftime --};πππprocedure displaygifscreenstats(screendes : byte);πvarπ  GCM : Boolean;πbegin {-- displaygifscreenstats --}π  GCM := screendes > 128;π  if (screendes > 128) thenπ    screendes := screendes - 128;π  if (screendes > 64) thenπ    screendes := screendes - 64;π  if (screendes > 32) thenπ    screendes := screendes - 32;π  if (screendes > 16) thenπ    screendes := screendes - 16;π  if (screendes > 8) thenπ    screendes := screendes - 8;π  case (screendes) ofπ    0: Write('  2');π    1: Write('  4');π    2: Write('  8');π    3: Write(' 16');π    4: Write(' 32');π    5: Write(' 64');π    6: Write('128');π    7: Write('256');π  end {-- CASE --};π  if (GCM) thenπ    Write(' ]  GCM/')π  elseπ    Write(' ]  ---/');πend {-- displaygifscreenstats --};ππprocedure checkforgiflite(var thefile : text);πvarπ  ic : Word;π  dummy, glite : char;π  gliteword : string[7];πbegin {-- checkforgiflite --}π  for ic := 13 to 784 doπ    read(thefile, dummy);π  gliteword := '       ';π  for ic := 1 to 7 doπ    beginπ    read(thefile, glite);π    gliteword[ic] := glite;π    end;π  if (pos('GIFLITE', gliteword) = 1) thenπ    Write('GL')π  elseπ    Write('--');πend {-- checkforgiflite --};ππbegin {-- getGIFheader --}π  gpath := '';π  gpath := paramstr(1);π  if (gpath = '') thenπ    gpath := '*.gif';π  if (pos('.', gpath) <> 0) thenπ    beginπ    gpath := copy(gpath, 1, pos('.', gpath));π    gpath := gpath + 'gif'π    endπ  elseπ    gpath := gpath + '*.gif';π  fsplit(fexpand(gpath), gdir, gname, gext);π  findfirst(gpath, archive, dirinfo);π  if (doserror <> 0) thenπ    showhelp;π  while (doserror = 0) doπ    beginπ    gifname := dirinfo.name;π    assign(giffile, gdir + gifname);π    reset(giffile);π    read(giffile, header);π    if (pos('GIF', header) <> 1) thenπ      header := '?_GIF?';π    read(giffile, rwidthLSB, rwidth, rheightLSB, rheight, gpixels, gback);π    gifname := taffy(gifname, 12);π    Write(gifname, '  ', dirinfo.size:7, '  ');π    writeftime(dirinfo.time);π    Write('    ', header, '   [');π    Write((ord(rwidthLSB) + (256 * ord(rwidth))):4, ' ',π         (ord(rheightLSB) + (256 * ord(rheight))):4, '  ');π    gpixn := ord(gpixels);π    displaygifscreenstats(gpixn);π    {         write ( ', ', ord ( gback )); }π    { This is the background color, commented out since it is not used }π    checkforgiflite(giffile);π    writeln;π    close(giffile);π    findnext(dirinfo);π    end;πend {-- getGIFheader --}.π                                                                                                              112    08-24-9413:41ALL                      ERIC MILLER              Graphic Compression      SWAG9408    ╫'∙U    10     ╓   {π TW> I'll need an algorithm to make a graphic smaller.ππ TW> I will read a 640x480x256 and want to make it a smaller size.π TW> For example 80x60x256 or 160x120x256 or something else.π TW> Maybe someone could send me an algorithm or a sample.ππ   If you simply want a smaller version of the original image, thenπ   it's easy.ππ  ie, for 640x480 to 160x120 ( 1/4 original size)π}ππ  FOR Y := 0 TO 119 { 160x120 Y axis }π    BEGINπ      NewY := (Y * 4);  { corresponding point on 640x480 Y axis }π      FOR X := 0 TO 159 DO  { 160x120 X axis }π        BEGINπ          NewX := (X * 4); { corresponding point on 640x480 X axis }π          Image160x120[Y, X] := Image640x480[NewY, NewX];π        END;π    END;ππ  See, simply multiply each point in 160x120 by 4 to get correspondingπ  point in 640x480.  This of course skips all pixels in between...π  Also, the in the example above, note that you cannot haveπ  an array of [0..479, 0..639] of Byte!  I just put that in thereπ  to show how it is done.ππ  Eric Millerπ  mysticm@ephsa.sat.tx.usπ                                                                                                                 113    08-24-9413:42ALL                      PAUL BROMAN              Pallete Handling         SWAG9408    g├v6    53     ╓   { GrafCont initializes the graphics mode and handles pallete fades. }ππunit GrafCont;ππinterfaceππusesπ  Crt, Dos, Graph;ππtypeπ  Palette256 = array[0..255, 0..2] of Byte;π  Palette16 = array[0..15, 0..2] of Byte;ππvarπ  Mode           : byte;ππprocedure Init256VGA;πprocedure Init16VGA;πprocedure SetVGAPalette256(PalBuf: Palette256);πprocedure GetVGAPalette256(var PalBuf: Palette256);πprocedure SetVGAPalette16(PalBuf: Palette16);πprocedure GetVGAPalette16(var PalBuf: Palette16);πprocedure GetRGBPalette(PalNum: integer; var R, G, B: byte);πprocedure FadeOutScreen256;πprocedure FadeOutScreen16;πprocedure FadeInScreen256(PalToMake: Palette256);πprocedure FadeInScreen16(PalToMake: Palette16);ππimplementationππprocedure Init256VGA;π   {This procedure relies on BGI drivers obtained for Pascal.π    You may need to create a new procedure based on your ownπ    method for turning on the graphics mode.}ππ   varπ     graphmode      : integer;π     graphdriver    : integer;ππ   beginπ   graphdriver := VGA256Graph;  {Defined as an OBJ}π   graphmode := 0;π   initgraph(graphdriver, graphmode, '');π   end;ππprocedure Init16VGA;π   varπ     graphdriver    : integer;π     graphmode      : integer;ππ   beginπ   graphdriver := 9;π   graphmode := 2;π   initgraph(graphdriver, graphmode, '');π   end;ππprocedure SetVGAPalette256;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 0;π  for ColorOn := 0 to 255 doπ      beginπ      Port[$3C9] := PalBuf[ColorOn, 0];π      Port[$3C9] := PalBuf[ColorOn, 1];π      Port[$3C9] := PalBuf[ColorOn, 2];π      end;πend;ππprocedure GetVGAPalette256;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 1;π  for ColorOn := 0 to 255 doπ      beginπ      PalBuf[ColorOn, 0] := Port[$3C9];π      PalBuf[ColorOn, 1] := Port[$3C9];π      PalBuf[ColorOn, 2] := Port[$3C9];π      end;π  PalBuf[0, 0] := 0;π  PalBuf[0, 1] := 0;π  PalBuf[0, 2] := 0;πend;ππprocedure SetVGAPalette16;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 0;π  for ColorOn := 0 to 15 doπ      beginπ      Port[$3C9] := PalBuf[ColorOn, 0];π      Port[$3C9] := PalBuf[ColorOn, 1];π      Port[$3C9] := PalBuf[ColorOn, 2];π      end;πend;ππprocedure GetVGAPalette16;πvarπ  ColorOn : byte;ππbeginπ  Port[$3C8] := 1;π  for ColorOn := 0 to 15 doπ      beginπ      PalBuf[ColorOn, 0] := Port[$3C9];π      PalBuf[ColorOn, 1] := Port[$3C9];π      PalBuf[ColorOn, 2] := Port[$3C9];π      end;π  PalBuf[0, 0] := 0;π  PalBuf[0, 1] := 0;π  PalBuf[0, 2] := 0;πend;πππprocedure GetRGBPalette;ππbeginπ  Port[$3C8] := PalNum;π  R := Port[$3C9];π  G := Port[$3C9];π  B := Port[$3C9];πend;ππprocedure FadeOutScreen256;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette256;π     PaletteStuff : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(1);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeOutText;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette256;π     PaletteStuff : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(20);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeInScreen256;π   varπ     Count        : byte;π     ColorOn      : byte;π     PaletteStuff : Palette256;π     FastPal      : Palette256;ππ   beginπ   GetVGAPalette256(PaletteStuff);π   for Count := 0 to 63 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(1);π       for ColorOn := 0 to 255 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeOutScreen16;π   varπ     Count        : word;π     ColorOn      : byte;π     PalToMake    : Palette16;π     PaletteStuff : Palette16;ππ   beginπ   GetVGAPalette16(PaletteStuff);π   PalToMake := PaletteStuff;π   for Count := 63 downto 0 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(5);π       for ColorOn := 0 to 15 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππprocedure FadeInScreen16;π   varπ     Count        : byte;π     ColorOn      : byte;π     PaletteStuff : Palette16;π     FastPal      : Palette16;ππ   beginπ   GetVGAPalette16(PaletteStuff);π   for Count := 0 to 63 doπ       beginπ       Port[$3C8] := 0;π       PaletteStuff := PalToMake;π       Delay(5);π       for ColorOn := 0 to 15 doπ           beginπ           PaletteStuff[ColorOn, 0] := (PaletteStuff[ColorOn, 0] * Count) div 63;π           PaletteStuff[ColorOn, 1] := (PaletteStuff[ColorOn, 1] * Count) div 63;π           PaletteStuff[ColorOn, 2] := (PaletteStuff[ColorOn, 2] * Count) div 63;π           Port[$3C9] := PaletteStuff[ColorOn, 0];π           Port[$3C9] := PaletteStuff[ColorOn, 1];π           Port[$3C9] := PaletteStuff[ColorOn, 2];π           end;π       end;π   end;ππend.ππ                 114    08-24-9413:46ALL                      GARTH KRUMINS            MODE-X Routines          SWAG9408    ╬å2    17     ╓   {π JW> What is mode-x or ($13) or whatever in graphics.  I like to writeπ     Mode-x is just your 320x200x256 VGA graphics mode.ππIt's pretty similar to using pascal's graph unit, except you don't!  You haveπto get all the procedures and functions set-up yourself.π}ππPROCEDURE InitVGA; ASSEMBLER;  {Puts you in 320x200x256 VGA}πasm π   mov  ax, 13h π   int  10h πend; π πPROCEDURE InitTEXT; ASSEMBLER; {Puts you back in 80x25 text mode} πasm π   mov  ax, 03h π   int  10h πend; ππPROCEDURE SetColor (ColorNo, Red, Green, Blue : byte); πbegin     {Changes the pallete data for a particular colour} π     PORT[$3C8] := ColorNo; π     PORT[$3C9] := Red; π     PORT[$3C9] := Green; π     PORT[$3C9] := Blue; πend; π πPROCEDURE MovCursor (X,Y : byte);  {Moves the cursor to (X,Y)} πbegin π  asm π  MOV   ah, 02h π  XOR   bx, bx π  MOV   dh, Y π  MOV   dl, X π  INT   10h π  end; πend; π πFUNCTION ReadCursorX: byte; assembler;  {Get X position of cursor}πasm π  MOV   ah, 03h π  XOR   bx, bx π  INT   10h π  MOV   al, dl πend; π πFUNCTION ReadCursorY: byte; assembler;  {Get Y position of cursor} πasm π  MOV   ah, 03h π  XOR   bx, bx π  INT   10h π  MOV   al, dh πend; π πPROCEDURE PutText (TextData : string; Color : byte);  {Write a string} πvar      {It's not the fastest way to do it, but it does the job} π z, ASCdata, CursorX, CursorY : byte; πbegin π CursorX := ReadCursorX;π CursorY := ReadCursorY; π for z := 1 to Length(TextData) do π begin π  ASCdata := Ord(TextData[z]); π  asm π  MOV   ah, 0Ah π  MOV   al, ASCdata π  XOR   bx, bx π  MOV   bl, Color π  MOV   cx, 1 π  INT   10h π  end; π  inc(CursorX); π  if CursorX=40 then begin CursorX:=0; inc(CursorY); end; π  MovCursor(CursorX,CursorY); π end; πend; π πPROCEDURE PlotPixel(X, Y: Word; Color: Byte); ASSEMBLER; {Plots a pixel} πasmπ   push es π   push di π   mov  ax, Y π   mov  bx, ax π   shl  ax, 8 π   shl  bx, 6 π   add  ax, bx π   add  ax, X π   mov  di, ax π   mov  ax, $A000 π   mov  es, ax π   mov  al, Color π   mov  es:[di], al π   pop  diπ   pop  esπend;π                 115    08-24-9413:50ALL                      JAMES COOK               Pcx Viewer!              SWAG9408    φE:]    30     ╓   πUses Crt;π{ Sample program to display a 320x200x256 PCX inπ  mode 13h.  PCX source copied from MCGA07, a MCGAπ  graphics unit written by James Cook in his MCGAπ  programming tutorial on Quantum Leap BBS }ππTYPEπ  TPalette = array[0..767] of Byte;π  PalettePtr = ^TPalette;π{ PCX stuff }π  PCXHeaderPtr=  ^PCXHeader;π  PCXHeader   =  recordπ                   Signature      :  Char;π                   Version        :  Char;π                   Encoding       :  Char;π                   BitsPerPixel   :  Char;π                   XMin,YMin,π                   XMax,YMax      :  Integer;π                   HRes,VRes      :  Integer;π                   Palette        :  Array [0..47] of byte;π                   Reserved       :  Char;π                   Planes         :  Char;π                   BytesPerLine   :  Integer;π                   PaletteType    :  Integer;π                   Filler         :  Array [0..57] of byte;π                 end;ππProcedure ExtractLineASM (BytesWide:Integer;Var Source,Dest:Pointer);πvarπ  DestSeg,π  DestOfs,π  SourceSeg,π  SourceOfs   :  Word;πbeginπ  SourceSeg := Seg (Source^);π  SourceOfs := Ofs (Source^);π  DestSeg   := Seg (Dest^);π  DestOfs   := Ofs (Dest^);ππ  asmπ    push  dsπ    push  siππ    cldππ    mov   ax,DestSegπ    mov   es,axπ    mov   di,DestOfs     { es:di -> destination pointer }π    mov   ax,SourceSegπ    mov   ds,axπ    mov   si,SourceOfs   { ds:si -> source buffer }ππ    mov   bx,diπ    add   bx,BytesWide   { bx holds position to stop for this row }π    xor   cx,cxππ  @@GetNextByte:π    cmp   bx,di          { are we done with the line }π    jbe   @@ExitHereππ    lodsb                { al contains next byte }ππ    mov   ah,alπ    and   ah,0C0hπ    cmp   ah,0C0hππ    jne    @@SingleByteπ                         { must be a run of bytes }π    mov   cl,alπ    and   cl,3Fhπ    lodsbπ    rep   stosbπ    jmp   @@GetNextByteππ  @@SingleByte:π    stosbπ    jmp   @@GetNextByteππ  @@ExitHere:π    mov   SourceSeg,dsπ    mov   SourceOfs,siπ    mov   DestSeg,esπ    mov   DestOfs,diππ    pop   siπ    pop   dsπ  end;ππ  Source := Ptr (SourceSeg,SourceOfs);π  Dest   := Ptr (DestSeg,DestOfs);πend;ππProcedure DisplayPCX (X,Y:Integer;Buf:Pointer);πvarπ  I,NumRows,π  BytesWide   :  Integer;π  Header      :  PCXHeaderPtr;π  DestPtr     :  Pointer;π  Offset      :  Word;ππbeginπ  Header    := Ptr (Seg(Buf^),Ofs(Buf^));π  Buf       := Ptr (Seg(Buf^),Ofs(Buf^)+128);π  Offset    := Y * 320 + X;π  NumRows   := Header^.YMax - Header^.YMin + 1;π  BytesWide := Header^.XMax - Header^.XMin + 1;π  If Odd (BytesWide) then Inc (BytesWide);ππ  For I := 1 to NumRows do beginπ    DestPtr := Ptr ($A000,Offset);π    ExtractLineASM (BytesWide,Buf,DestPtr);π    Inc (Offset,320);π    end;πend;π{ end PCX stuff }ππProcedure Graph13h; assembler;πasmπ  mov al,$13π  mov ah,0π  int 10hπend;ππVARπ  F: File;           { PCX file }π  Hdr: PCXHeaderPtr; { PCX header structure & file }π  Pal: PalettePtr;   { PCX palette }π  Shade, Size: Word; { RGB shade, file size }ππBEGINπ  Graph13h;                          { set mode 13h }π  Assign(F, 'filename.pcx');         { open PCX file }π  Reset(F,1);π  Size := FileSize(F);π  GetMem(Hdr, Size);                 { load PCX into memory }π  Blockread(F, Hdr^, Size);π  Close(F);π  Pal := Ptr( Seg(Hdr^), Ofs(Hdr^) + Size - 768);    { get palette location }π  Port[968] := 0;                                    { set palette }π  FOR Shade := 0 TO 767 DOπ    Port[969] := Pal^[Shade] SHR 2;π  DisplayPCX(0, 0, Hdr);                             { decode PCX to screen }π  WHILE Readkey <> #13 DO;                           { wait for return key }π  TextMode(CO80);πEND.π                                                   116    08-24-9413:50ALL                      OLAF BARTELT             Vga 256 Color PCX        SWAG9408    ┘*ô    22     ╓   {π CF> I am working with VGA 320x200x256.  Can anyone please helpπ CF> me with a good line routine and the PCX format?  I haveπ CF> tryed both and things go bad.. If you have code layingπ CF> around it would help me a lot...  Thanksππ}ππPROCEDURE load_pcx(dx, dy : WORD; name : STRING);πVAR q                          : FILE;        { Quellendatei-Handle         }π    b                          : ARRAY[0..2047] OF BYTE;  { Puffer          }π    anz, pos, c, w, h, e, pack : WORD;        { diverse benötigte Variablen }π    x, y                       : WORD;        { für die PCX-Laderoutine     }ππLABEL ende_background;                        { Sprungmarken definieren     }ππBEGINπ  x := dx; y := dy;                           { Nullpunkt festsetzen        }ππ  ASSIGN(q, name); {$I-} RESET(q, 1); {$I+}   { Quellendatei öffnen         }π  IF IORESULT <> 0 THEN                       { Fehler beim Öffnen?         }π    GOTO ende_background;                     { Ja: zum Ende springen       }ππ  BLOCKREAD(q, b, 128, anz);                  { Header einlesen             }ππ  IF (b[0] <> 10) OR (b[3] <> 8) THEN         { wirklich ein PCX-File?      }π  BEGINπ    CLOSE(q);                                 { Nein: Datei schließen und   }π    GOTO ende_background;                     {       zum Ende springen     }π  END;ππ  w := SUCC((b[9] - b[5]) SHL 8 + b[8] - b[4]);  { Breite auslesen          }π  h := SUCC((b[11] - b[7]) SHL 8 + b[10] - b[6]);  { Höhe auslesen          }ππ  pack := 0; c := 0; e := y + h;π  REPEATπ    BLOCKREAD(q, b, 2048, anz);ππ    pos := 0;π    WHILE (pos < anz) AND (y < e) DOπ    BEGINπ      IF pack <> 0 THENπ      BEGINπ        FOR c := c TO c + pack DOπ          MEM[SEGA000:y*320+(x+c)] := b[pos];π        pack := 0;π      ENDπ      ELSEπ        IF (b[pos] AND $C0) = $C0 THENπ          pack := b[pos] AND $3Fπ        ELSEπ        BEGINπ          MEM[SEGA000:y*320+(x+c)] := b[pos];π          INC(c);π        END;ππ      INC(pos);π      IF c = w THEN                           { letzte Spalte erreicht?     }π      BEGINπ        c := 0;                               { Ja: Spalte auf 0 setzen und }π        INC(y);                               {     in die nächste Zeile    }π      END;π    END;π  UNTIL (anz = 0) OR (y = e);ππ  SEEK(q, FILESIZE(q) - 3 SHL 8 - 1);π  BLOCKREAD(q, b, 3 SHL 8 + 1);ππ  IF b[0] = 12 THENπ    FOR x := 1 TO 3 SHL 8 + 1 DOπ      b[x] := b[x] SHR 2;ππ  PORT[$3C8] := 0;ππ  FOR x := 0 TO 255 DOπ  BEGINπ    PORT[$3C9] := b[x*3+1];π    PORT[$3C9] := b[x*3+2];π    PORT[$3C9] := b[x*3+3];π  END;ππ  CLOSE(q);ππende_background:πEND;ππBEGINπ    Load_Pcx(1,1,'c:\lpexface.pcx');πEND.                                            117    08-24-9413:50ALL                      ANDREW EIGUS             Pcx Bitmap Rotating      SWAG9408    tôp    127    ╓   { ROTATE.PAS }ππ{π  Rotating textured surface.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue members.π  You can do anything with this code until this commentsπ  remain unchanged.ππ  Bugs corrected by Alex Grischenkoπ}ππ{$G+,A-,V-,X+}π{$M 16384,0,16384}ππuses Crt, Objects, Memory, VgaGraph;  { unit code at the end of program }ππconstπ{ Try to play with this constants }π  RotateSteps  = {64*5}65*10;π  AngleStep    = {3}1;π  MoveStep     = {10}1;π  ScaleStep    : Real =  0.02;ππtypeπ  TBPoint = record X,Y: { Byte} Integer; end;π  TPointArray = array[ 1..500 ] of TBPoint;ππ  TRotateApp = object(TGraphApplication)π    StartTime,π    FramesNumber:LongInt;π    {Texture: TImage;}π    X,Y    : Integer;π    WSX,WSY: Integer;π    WSXR,π    WSYR   : Real;π    Angle  : Integer;π    Size   : TPoint;π    CurPage: Integer;π    Texture: TImage;π    constructor Init;π    procedure Run;      virtual;π    destructor Done;    virtual;π    procedure Draw;     virtual;π    procedure FlipPage; virtual;π    procedure Rotate( AngleStep: Integer );π    procedure Move( DeltaX, DeltaY: Integer );π    procedure Scale( Factor: Real );π    procedure Update;π  end;πvarπ  Pal:  TRGBPalette;π  Time:  LongInt absolute $0:$46C;ππprocedure TRotateApp.FlipPage;πbeginπ  CurPage := 1-CurPage;π  ShowPage(1-CurPage);πend;ππconstructor TRotateApp.Init;πvarπ  I, J: Integer;πbeginπ  if not inherited Init(True) or not Texture.Load( ParamStr(1) ) then Fail;π  SetPalette( Texture.Palette );π  X := 0;π  Y := 0;π  WSX := 240;π  WSY := 360;π  WSXR := WSX;π  WSYR := WSY;π  Angle := 0;π  Size.X := HRes div 2;π  Size.Y := VRes div 2;π  FramesNumber := 0;π  StartTime := Time;  {     asm mov ax,13h; int 10h; end;}π  system.move (Texture.Data^,Screen,64000);π    SetPalette( Texture.Palette );π{  readkey;}πend;ππprocedure TRotateApp.Rotate( AngleStep: Integer );πbeginπ  Inc( Angle, AngleStep );π  Angle := Angle mod RotateSteps;πend;ππprocedure TRotateApp.Move( DeltaX, DeltaY: Integer );πbeginπ  Inc( X, DeltaX );π  Inc( Y, DeltaY );πend;ππprocedure TRotateApp.Scale( Factor: Real );πbeginπ  WSXR := WSXR*Factor;π  WSX := Round(WSXR);π  WSYR := WSYR*Factor;π  WSY := Round(WSYR);πend;ππprocedure TRotateApp.Update;πbeginπ  Move( MoveStep, MoveStep );π  Rotate(AngleStep);π  Scale(1+ScaleStep);π  if (WSY >= 2000) or (WSY<=100) then ScaleStep := -ScaleStep;πend;ππprocedure TRotateApp.Draw;ππvarπ  I :  Integer;π  Border,π  LineBuf: TPointArray;π  BorderLen: Integer;π  X1RN,X1LN,π  Y1RN,Y1LN,π  X2RN,X2LN,π  Y2RN,Y2LN,π  X1R,X1L,π  Y1R,Y1L,π  X2R,X2L,π  Y2R,Y2L,π  XL,YL: Integer;ππ{ This function can be heavly optimized but I'm too lazy to do absoletelyπ  meaningless things :-) }πfunction BuildLine( var Buffer: TPointArray; X1,Y1, X2,Y2: Integer;π      Len: Integer ): Integer;πvarπ  I: Word;π  XStep,π  YStep: LongInt;πbeginπ  XStep := (LongInt(X2-X1) shl 16) div Len;π  YStep := (LongInt(Y2-Y1) shl 16) div Len;π  for I := 1 to Len doπ  beginπ    Buffer[I].X := Integer( ((XStep*I) shr 16) - ((XStep*(I-1)) shr 16) );π    Buffer[I].Y := Integer( ((YStep*I) shr 16) - ((YStep*(I-1)) shr 16) );π  end;πend;ππprocedure DrawPicLine( var Buffer; BitPlane: Integer;π        StartX, StartY: Integer; Len: Integer; var LineBuf );πvarπ  PD :  Pointer;πbeginπ  PD := Texture.Data;           { pointer to unpacked screen image }π  Port[$3C4] := 2;π  if BitPlane = 0 thenπ    Port[$3C5] := 3π  elseπ    Port[$3C5] := 12;ππ  asmπ    push  dsπ    mov   bx,[StartX]             { bx = StartX }π    mov   dx,[StartY]             { dx = StartY }π    les   di,Buffer               { ES:DI = @Screen }π    add   di,VPageLen/2-Hres/4    { calc target page }π    mov   cx,Len                  { Drawing buffer length }π    lds   si,PD                   { DS:SI = pointer to data }π    push  bp                      { store BP }π    mov   bp,word ptr LineBuf     { BP = offset LineBuf }π    cldπ@loop:π      PUSH DXπ      MOV  AX,320π      MUL  DX                     { AX = StartY*320 }π      POP  DXππ      PUSH BXπ      ADD  BX,AXπ      mov  al,[bx+SI]π      POP  BXππ      stosbπ      sub  di,HRes/4+1{ add di,hres-1}π      add  BX,[bp]π      ADD  bp,2π      add  DX,[bp]π      ADD  bp,2ππ{      CMP  BX,320π      JB   @@1π      XOR  BX,BXπ@@1:  CMP  DX,200π      JB   @@2π      XOR  DX,DXπ@@2:}π      loop @loopππ      pop bpπ      pop dsπ  end;πend;ππbeginππ{ Just imagine what can be if the next 8 lines would be more complex.π  I'm working around it. }π{π     (X1L,Y1L)        (X2R,Y1R)π        +---------------+π        |               |π        |               |π        |               |π        +---------------+π     (X2L,Y2L)        (X2R,Y2R)ππ     (X1LN,Y1LN)        (X2RN,Y1RN)π        +---------------+π        |               |π        |               |π        |               |π        +---------------+π     (X2LN,Y2LN)        (X2RN,Y2RN)ππ}π  X1L := 0;π  Y1L := 0;π  X2L := 0;π  Y2L := WSY;π  X1R := WSX;π  Y1R := 0;π  X2R := WSX;π  Y2R := WSY;π{ I call Cos and Sin instead of using tables!? Yeah, I do. So what?π  See comments near BuildLine ;-) }π{  I just rotate the rectangle corners, but why I do no more? }π  X1RN := Round(π(X1R*Cos(2*Pi/RotateSteps*Angle)+Y1R*Sin(2*Pi/RotateSteps*Angle)) );π  Y1RN := Round(π(Y1R*Cos(2*Pi/RotateSteps*Angle)-X1R*Sin(2*Pi/RotateSteps*Angle)) );π  X1LN := Round(π(X1L*Cos(2*Pi/RotateSteps*Angle)+Y1L*Sin(2*Pi/RotateSteps*Angle)) );π  Y1LN := Round(π(Y1L*Cos(2*Pi/RotateSteps*Angle)-X1L*Sin(2*Pi/RotateSteps*Angle)) );π  X2RN := Round(π(X2R*Cos(2*Pi/RotateSteps*Angle)+Y2R*Sin(2*Pi/RotateSteps*Angle)) );π  Y2RN := Round(π(Y2R*Cos(2*Pi/RotateSteps*Angle)-X2R*Sin(2*Pi/RotateSteps*Angle)) );π  X2LN := Round(π(X2L*Cos(2*Pi/RotateSteps*Angle)+Y2L*Sin(2*Pi/RotateSteps*Angle)) );π  Y2LN := Round(π(Y2L*Cos(2*Pi/RotateSteps*Angle)-X2L*Sin(2*Pi/RotateSteps*Angle)) );ππ  XL := X+X1LN;π  YL := Y+Y1LN;ππ  BuildLine( Border, XL,YL, X+X2LN,Y+Y2LN, Size.X );π  BuildLine( LineBuf, 0, 0, X1RN-X1LN, Y1RN-Y1LN, Size.Y );ππ{π  The only thing that can be optimized is the loop below. I think it shouldπ  be completely in asm.π}π  for I := 1 to Size.X doπ  beginπ   DrawPicLine( PBuffer(@Screen)^[CurPage*VPageLen+(I-1) shr 1],π   (I-1) {mod 2} and 1, XL, YL, Size.Y, LineBuf );π{π    Inc( XL, Border[I].X );π    Inc( YL, Border[I].Y );π}π  asmπ    mov   di,Iπ    shl   di,2π    mov   ax,word ptr border[di]-4π    add   XL,axπ    mov   ax,word ptr Border[di]-4+2π    add   YL,axπ  end;π  end;πend;ππprocedure TRotateApp.Run;πvarπ  C:  Char;πbeginπ  repeatπ    if KeyPressed thenπ    beginπ      C := ReadKey;π      if C = #0 then C := ReadKey;π      case C ofπ #72: Move(0,-10);π #80: Move(0,-10);π #75: Move(-10,0);π #77: Move(10,0);π #81: Rotate(1);π #79: Rotate(-1);π '+': Scale(1+ScaleStep);π '-': Scale(1-ScaleStep);π #27: Exit;π      end;π    end;π   Draw;π{ You can comment out the line below and do all transformation yourself }π   Update;π   FlipPage;π   Inc( FramesNumber );π  until False;πend;ππdestructor TRotateApp.Done;πbeginπ  inherited Done;π  WriteLn( 'Frames per second = ',π    (FramesNumber / ((Time-StartTime)*0.055) ):5:2 );πend;ππvarπ  RotateApp: TRotateApp;πbeginπ  if not RotateApp.Init then Exit;π  RotateApp.Run;π  RotateApp.Done;πend.ππ{---------------------   UNIT CODE NEEDED HERE -------------------- }ππ{π  VGA graphics unit.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue members.ππ  This this the very small part of my gfx unit. I leave only functions usedπ  by RotateApp.ππ  Bugs corrected by Alex Grischenkoπ}ππunit VGAGraph;ππinterfaceππuses Objects, Memory;ππconstπ  HRes  = 360;π  VRes  = 320;π  VPageLen = HRes*VRes div 4;ππ{  HRes = 320; VRes=200; Vpagelen=0;}ππtypeπ  PBuffer = ^TBuffer;π  TBuffer = array[ 0..65534 ] of Byte;π  PScreenBuffer = ^TScreenBuffer;π  TScreenBuffer = array[ 0..199, 0..319 ] of Byte;π  TRGBPalette = array[ 0..255 ] of record R,G,B: Byte; end;ππ  PImage = ^TImage;π  TImage = object( TObject )π    Size: TPoint;π    Palette: TRGBPalette;π    Data: PBuffer;π    constructor Load( Name: String );π{   This procedures are now killed. If you need them just write me or seeπ    old mail from me.π    procedure Show( Origin: TPoint; var Buffer );π    procedure ShowRect( Origin: TPoint; NewSize: TPoint; var Buffer ); }π    destructor Done; virtual;π  end;ππ  PGraphApplication = ^TGraphApplication;π  TGraphApplication = object( TObject )π    constructor Init( ModeX : Boolean );π    procedure Run; virtual;π    destructor Done; virtual;π  end;ππvarπ  Screen: TScreenBuffer absolute $A000:0;ππ  procedure SetPalette( var Pal: TRGBPalette );π  procedure Set360x240Mode;π  procedure ShowPage( Page: Integer );ππimplementationππuses PCX;ππconstructor TImage.Load( Name: String );πvarπ  S: TDosStream;π  I: Integer;π  P: OldPCXPicture;π  Len: Word;πbeginπ  inherited Init;π  P.Init( Name );π  if P.Status <> pcxOK thenπ  beginπ    P.Done;π    Fail;π  end;π  Size.X := P.H.XMax - P.H.XMin + 1;π  Size.Y := P.H.YMax - P.H.YMin + 1;π{π  I use DOS memory allocation 'cuz GetMem can't allocate 64Kπ  Even thru DPMI.  :-(π  GetMem( Data, Word(Size.X) * Size.Y );π}π  Len := Word((LongInt(Size.X)*Size.Y+15) div 16);π  LEN:=65536 DIV 16;π  asmπ    mov ah,48hπ    mov bx,Lenπ    int 21hπ    jnc @mem_okπ    xor ax,axπ@mem_ok:π    mov word ptr es:[di].Data+2,axπ    xor ax,axπ    mov word ptr es:[di].Data,axπ  end;ππ  if Data = nil thenπ  beginπ    P.Done;π    Fail;π  end;ππ  fillchar(Data^,len*16-1,0);ππ  Move( P.Pal, Palette, SizeOf(Palette) );π  for I := 0 to 255 doπ  beginπ    Palette[I].R := Palette[I].R shr 2;π    Palette[I].G := Palette[I].G shr 2;π    Palette[I].B := Palette[I].B shr 2;π  end;ππ  for I := 0 to Size.Y-1 doπ    P.ReadLine( Data^[ Word(Size.X)*I ] );π  P.Done;πend;ππdestructor TImage.Done;πbeginπ{π  FreeMem( Data, Word(Size.X)*Size.Y );π}π  asmπ    mov ah,49hπ    mov ax,word ptr es:[di].Data+2π    mov es,axπ    int 21hπ  end;π  inherited Done;πend;ππconstructor TGraphApplication.Init( ModeX : Boolean );πbeginπ  Set360x240Modeπend;ππprocedure TGraphApplication.Run;πbeginπ  Abstract;πend;ππdestructor TGraphApplication.Done;πbeginπ  asmπ    mov ax,3hπ    int 10hπ  end;πend;ππprocedure SetPalette( var Pal: TRGBPalette );πvarπ  I : Integer;πbeginπ  for I := 0 to 255 doπ  beginπ    Port[$3C8] := I;π    Port[$3C9] := Pal[I].R;π    Port[$3C9] := Pal[I].G;π    Port[$3C9] := Pal[I].B;π  end;πend;ππ{  Modified from public-domain mode set code by John Bridges. }ππconstπ SC_INDEX  = $03c4;   {Sequence Controller Index}π CRTC_INDEX = $03d4;   {CRT Controller Index}π MISC_OUTPUT  = $03c2;   {Miscellaneous Output register}ππ{ Index/data pairs for CRT Controller registers that differ betweenπ  mode 13h and mode X. }ππCRT_PARM_LENGTH = 17;πCRTParms : array [1..CRT_PARM_LENGTH] of Word = (ππ $6B00,  { Horz total }π $5901,  { Horz Displayed }π $5A02,  { Start Horz Blanking }π $8E03,  { End Horz Blanking }π $5E04,  { Start H Sync }π $8A05,  { End H Sync }π $0d06,  {vertical total}π $3e07,  {overflow (bit 8 of vertical counts)}π $ea10,  {v sync start}π $8c11,  {v sync end and protect cr0-cr7}π $df12,  {vertical displayed}π $e715,  {v blank start}π $0616,  {v blank end}π $4209,  {cell height (2 to double-scan)}π $0014,  {turn off dword mode}π $e317,  {turn on byte mode}π $2D13 {90 bytes per line}π);ππprocedure Set360x240Mode;πbeginπ asmπ mov     ax,13h  {let the BIOS set standard 256-color}π int     10h     {mode (320x200 linear)}ππ mov     dx,SC_INDEXπ mov     ax,0604hπ out     dx,ax   {disable chain4 mode}π mov     ax,0100hπ out     dx,ax   {synchronous reset while switching clocks}ππ mov     dx,MISC_OUTPUTπ mov     al,0E7hπ out     dx,al   {select 28 MHz dot clock & 60 Hz scanning rate}ππ mov     dx,SC_INDEXπ mov     ax,0300hπ out     dx,ax   {undo reset (restart sequencer)}ππ mov     dx,CRTC_INDEX {reprogram the CRT Controller}π mov     al,11h  {VSync End reg contains register write}π out     dx,al   {protect bit}π inc     dx      {CRT Controller Data register}π in      al,dx   {get current VSync End register setting}π and     al,7fh  {remove write protect on various}π out     dx,al   {CRTC registers}π dec     dx      {CRT Controller Index}π cldπ mov     si,offset CRTParms {point to CRT parameter table}π mov     cx,CRT_PARM_LENGTH {# of table entries}π@SetCRTParmsLoop:π lodsw           {get the next CRT Index/Data pair}π out     dx,ax   {set the next CRT Index/Data pair}π push cxπ mov cx,1000π@loop: loop @loopπ pop cxπ loop    @SetCRTParmsLoopππ mov     dx,SC_INDEXπ mov     ax,0f02hπ out     dx,ax   {enable writes to all four planes}π mov     ax,$A000{now clear all display memory, 8 pixels}π mov     es,ax         {at a time}π sub     di,di   {point ES:DI to display memory}π sub     ax,ax   {clear to zero-value pixels}π mov     cx,VRes*HRes/4/2 {# of words in display memory}π rep     stosw   {clear all of display memory}π end;πend;ππprocedure ShowPage( Page: Integer );πbeginπ  asmπ      mov ax,VPageLenπ      mul word ptr Pageπ      mov bx,axππ      mov dx,3d4hπ      mov al,0chπ      mov ah,bhπ      out dx,axπ      mov dx,3d4hπ      mov al,0dhπ      mov ah,blπ      out dx,axπ{ Uncomment this waiting for retrace if you see flickering }π{π      mov dx,3dahπ @@1: in al,dxπ      test al,00001000bπ      jz @@1π @@2: in   al,dxπ      test al,00001000bπ      jnz  @@2π}π  end;πend;ππEnd.ππ{ --------------------------  UNIT CODE NEEDED HERE -------------}ππ{π  256 color PCX bitmaps handling unit.π  NewPCXPicture object are removed to reduce traffic. If youπ  need it just contact me or dig in old mail from me.π  Coded by Mike Shirobokov(MSH) aka Mad Max / Queue Members.π  Free sourceware.π}ππunit PCX;ππinterfaceππuses Objects;ππtypeπ  TRGBPalette = array[ 0..255 ] of record R,G,B: Byte; end;ππ  PCXHeader = recordπ    Creator,π    Version,π    Encoding,π    Bits: Byte;π    XMin,π    YMin,π    XMax,π    YMax,π    HRes,π    VRes: Integer;π    Palette: array [ 1..48 ] of Byte;π    VMode,π    Planes: Byte;π    BytesPerLine,π    PaletteInfo,π    SHRes,π    SVRes: Word;π    Dummy: array [0..53] of Byte;π  end;ππconstπ  pcxOK   = 0;π  pcxInvalidType = 1;π  pcxNoFile  = 2;ππtypeπ  OldPCXPicture = objectπ    H:  PCXHeader;π    S:  TBufStream;π    Pal: TRGBPalette;π    Status: Integer;π    constructor Init( AFileName: String );π    procedure ReadLine( var Buffer );π    function ErrorText: String;π    destructor Done;π  end;π{π  NewPCXPicture = objectπ    H:  PCXHeader;π    S:  TBufStream;π    Pal: TRGBPalette;π    constructor Init( AFileName: String; HSize: Integer );π    procedure WriteLine( var Buffer );π    destructor Done;π  end;π}πimplementationππtypeπ  GetByteFunc = function: Byte;π  ByteArr = array [0..65534] of Byte;π  PByte  = ^ByteArr;ππprocedure UnpackString( GetByte: GetByteFunc; var Dest; Size: Integer );πvarπ  DestPtr: PByte;π  Count: Integer;π  B:  Byte;π  I:  Integer;πbeginπ  DestPtr := @Dest;π  Count := 0;π  while Count < Size doπ  beginπ    B := GetByte;π    if B < $C0 thenπ    beginπ      DestPtr^[Count] := B;π      Inc(Count);π    endπ    elseπ    beginπ      DestPtr^[Count] := GetByte;π      for I := 0 to B-$C1 doπ DestPtr^[Count+I] := DestPtr^[Count];π      Inc( Count, I+1 );π    end;π  end;πend;ππconstructor OldPCXPicture.Init( AFileName: String );πbeginπ  S.Init( AFileName, stOpenRead, 2048 );π  if S.Status <> stOk thenπ  beginπ    Status := pcxNoFile;π    Exit;π  end;π  S.Read( H, SizeOf(H) );π  if (H.Planes <> 1) or (H.Encoding <> 1) or (H.Bits <> 8 ) thenπ  beginπ    Status := pcxInvalidType;π    Exit;π  end;π  S.Seek( S.GetSize - SizeOf(Pal) );π  S.Read( Pal, SizeOf(Pal) );π  S.Seek( SizeOf(H) );π  Status := pcxOK;πend;ππvarπ  __GetS__: PStream;ππfunction Get: Byte; far;πvarπ  B: Byte;πbeginπ  __GetS__^.Read( B, 1 );π  Get := B;πend;ππprocedure OldPCXPicture.ReadLine( var Buffer );πbeginπ  __GetS__ := @S;π  UnpackString( Get, Buffer, H.BytesPerLine );πend;ππfunction OldPCXPicture.ErrorText: String;πbeginπ  case Status ofπ    pcxOK:π      ErrorText := 'No errors';π    pcxNoFile:π      ErrorText := 'Can''t open file';π    pcxInvalidType:π      ErrorText := 'Only 8 bit PCXs are supported';π  end;πend;ππdestructor OldPCXPicture.Done;πbeginπ  S.Done;πend;ππend.ππ                                                             118    08-24-9413:50ALL                      JENS LARSSON             Grabbing Pixel Color     SWAG9408    )D█    6      ╓   {π GK> I have a slight problem.  I have written a program that runs inπ GK> graphics mode ($13).  I use the following routine to get whatπ GK> colour is at that pixel :-π GK>     PixelColor := MEM[$A000:X + (Y*320)];π GK> This works fine, but it is rather slow.  I was wondering ifπ GK> anybody knew how to do this faster?π}ππ   Function PixColor(x, y : Word) : Byte; Assembler;π    Asmπ     push  dsπ     mov   ax,0a000hπ     mov   ds,axπ     mov   ax,yπ     shl   ax,6π     mov   si,axπ     shl   ax,2π     add   si,axπ     add   si,xπ     lodsbπ     pop   dsπ    End;π                                                                     119    08-24-9413:50ALL                      MARCIN BORKOWSKI         Landscape                SWAG9408    ¿ù┬    30     ╓   πuses crt;ππtype lrgarr = array[0..65534]of byte;ππconstπ pal : array[1..384]of byte =π (0,0,0,48,48,48,1,0,43,1,3,43,2,5,44,2,7,44,3,9,45,4,11,46,5,13,47,6,15,48,π  7,17,49,8,19,50,9,21,51,10,22,52,11,24,52,12,26,54,13,28,54,14,30,56,15,32,π  56,16,34,58,17,34,58,17,36,58,18,38,60,19,40,60,20,42,62,21,44,62,10,31,0,π  11,31,0,11,31,1,11,32,1,12,32,1,12,32,2,12,33,2,13,33,2,14,33,3,15,33,3,15,π  34,3,15,34,4,15,35,4,16,35,4,16,35,5,16,36,5,17,36,5,17,36,6,18,37,6,18,38,π  7,19,38,8,20,39,8,20,40,9,21,40,10,22,41,10,22,42,11,23,42,12,24,43,12,24,π  44,13,25,44,14,25,45,14,26,46,15,27,46,16,27,47,17,28,47,18,28,48,19,29,49,π  19,30,49,20,30,50,21,31,51,21,32,51,22,32,52,23,33,53,23,34,53,24,34,54,25,π  35,55,25,36,55,26,36,56,27,37,57,27,38,57,27,39,57,27,41,57,27,42,57,27,43,π  57,27,44,57,27,45,57,27,46,57,27,47,57,27,49,57,27,50,57,27,51,57,27,52,57,π  27,53,57,27,55,57,27,56,57,27,57,57,27,58,57,27,58,57,26,58,57,25,58,57,24,π  58,56,23,58,55,22,58,54,20,58,53,19,58,51,18,58,50,17,58,50,16,58,49,15,58,π  48,14,58,47,13,58,46,12,58,45,11,58,44,11,58,44,10,58,43,10,58,42,9,57,41,π  8,57,40,8,56,39,7,56,38,6,55,37,5,55,35,4,54,33,4,54,31,2,32,32,32,63,63,63,π  63,63,63,63,63,63,63,63,63,48,48,48,63,63,63,63,63,63);ππvarπ mp,scr : ^lrgarr;π rng : array[0..320]of byte;π dir,i,x,y : integer;ππfunction ncol(mc,n,dvd : integer): integer;πvar loc : integer;πbeginπ loc:=(mc+n-random(2*n)) div dvd; ncol:=loc;π if loc>250 then ncol:=250; if loc<5 then ncol:=5πend;ππprocedure plasma(x1,y1,x2,y2 : word);πvar xn,yn,dxy,p1,p2,p3,p4 : word;πbeginπ if (x2-x1<2) and (y2-y1<2) then EXIT;π p1:=mp^[256*y1+x1]; p2:=mp^[256*y2+x1]; p3:=mp^[256*y1+x2];π p4:=mp^[256*y2+x2]; xn:=(x2+x1) shr 1; yn:=(y2+y1) shr 1;π dxy:=5*(x2-x1+y2-y1) div 3;π if mp^[256*y1+xn]=0 then mp^[256*y1+xn]:=ncol(p1+p3,dxy,2);π if mp^[256*yn+x1]=0 then mp^[256*yn+x1]:=ncol(p1+p2,dxy,2);π if mp^[256*yn+x2]=0 then mp^[256*yn+x2]:=ncol(p3+p4,dxy,2);π if mp^[256*y2+xn]=0 then mp^[256*y2+xn]:=ncol(p2+p4,dxy,2);π mp^[256*yn+xn]:=ncol(p1+p2+p3+p4,dxy,4);π plasma(x1,y1,xn,yn); plasma(xn,y1,x2,yn);π plasma(x1,yn,xn,y2); plasma(xn,yn,x2,y2);πend;ππprocedure draw(xp,yp,dir : integer);πvar z,zobs,ix,iy,iy1,iyp,ixp,x,y,s,csf,snf,mpc,i,j : integer;πbeginπ fillchar(rng,sizeof(rng),200);  zobs:=100+mp^[256*yp+xp];π csf:=round(256*cos(dir/180*pi)); snf:=round(256*sin(dir/180*pi));π fillchar(scr^,64000,0);π for iy:=yp to yp+55 doπ beginπ  iy1:=1+2*(iy-yp); s:=4+300 div iy1;π  for ix:=xp+yp-iy to xp-yp+iy doπ  beginπ   ixp:=xp+((ix-xp)*csf+(iy-yp)*snf) div 256;π   iyp:=yp+((iy-yp)*csf-(ix-xp)*snf) div 256;π   x:=160+360*(ix-xp) div iy1;π   if (x>=0) and (x+s<=318) thenπ   beginπ    z:=mp^[256*iyp+ixp]; mpc:=z shr 1;π    if z<47 then z:=46;  y:=100+(zobs-z)*30 div iy1;π    if (y<=199) and (y>=0) thenπ     for j:=x to x+s doπ     beginπ      for i:=y to rng[j] do scr^[320*i+j]:=mpc;π      if y<rng[j] then rng[j]:=yπ     end;π   end;π  end;π end;π move(scr^,mem[$A000:0],64000);πend;ππbeginπ writeln('Use arrow keys to pan in/out left/right ... any key to continue ..');π readkey;π randomize; x:=0; y:=0; dir:=0; new(mp); fillchar(mp^,65535,0);π new(scr); mp^[$0000]:=128; plasma(0,0,256,256);π asm xor ax,ax; mov al,$13; int $10; end;π port[$3C8]:=0; for i:=1 to 384 do port[$3C9]:=pal[i];π repeatπ  dir:=dir mod 360; draw(x,y,dir);π  case readkey ofπ   #0 : case readkey ofπ     #75 : dec(dir,10);π     #77 : inc(dir,10);π     #72 : begin y:=y+round(4*cos(dir/180*pi));π           x:=x+round(4*sin(dir/180*pi)); end;π     #80 : begin y:=y-round(4*cos(dir/180*pi));π           x:=x-round(4*sin(dir/180*pi)); end;π       end;π   #27 : begin asm xor ax,ax; mov al,$3; int $10; end; HALT endπ  endπ until false;πend.π                 120    08-24-9413:50ALL                      JONAS MALMSTEN           plasma                   SWAG9408    Um.    22     ╓   {πYesterday I saw Bas' plasma routine. Real nice! But... a little slow I thoughtπso I improved it. Another thing, Bas, the bouble buffer didn't work on myπet4000, the bplptr never changed in your mode.ππWell, enjoy this new routine!π}ππprogram plasma;ππ{ bigscreenplasma, by Bas van Gaalen & Sven van Heel, Holland, PD   }π{ Improved by GEM, Sweden (convertion to asm --> many times faster) }ππusesπ  crt;ππconstπ  vidseg:word=$a000;ππvarπ  stab1,stab2:array[0..255+80] of byte;π  x:word;ππprocedure setpal(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;ππbeginπ  asmπ     mov ax,0013hπ     int 10hπ     mov dx,03c4hπ     mov ax,0604hπ     out dx,axπ     mov dx,03d4hπ     mov ax,4609hπ     out dx,axπ     mov ax,0014hπ     out dx,axπ     mov ax,0e317hπ     out dx,axπ     mov es,vidsegπ     xor di,diπ     xor ax,axπ     mov cx,16000π     rep stoswπ  end;π  for x:=0 to 63 do beginπ    setpal(x,x div 4,x div 2,x);π    setpal(127-x,x div 4,x div 2,x);π    setpal(127+x,20+x div 4,x div 2,x);π    setpal(254-x,20+x div 4,x div 2,x);π  end;π  for x:=0 to 255+80 do beginπ    stab1[x]:=round(sin(2*pi*x/255)*128)+128;π    stab2[x]:=round(cos(2*pi*x/255)*128)+128;π  end;π  asmπ     mov cl,50π     mov ch,90π     mov es,vidsegπ     push bpπ   @main:ππ{     mov dx,3c8h    (* For checking rastertime *)π     xor al,alπ     out dx,alπ     inc dxπ     out dx,alπ     out dx,alπ     out dx,al}ππ     mov dx,3dahπ   @vert1:π     in al,dxπ     test al,8π     jz @vert1π   @vert2:π     in al,dxπ     test al,8π     jnz @vert2ππ     mov dx,3dah    (* This is kinda rediculous! *)π   @vert1b:         (* I have to insert another vbl to slow it down.... *)π     in al,dxπ     test al,8π     jz @vert1bπ   @vert2b:π     in al,dxπ     test al,8π     jnz @vert2bππ{     mov dx,3c8h    (* For checking rastertime *)π     xor al,alπ     out dx,alπ     mov al,30π     inc dxπ     out dx,alπ     out dx,alπ     out dx,al}ππ     inc clπ     inc chπ     xor di,diπ     mov bp,diπ   @loooooop:π     mov si,offset stab1π     mov bx,bpπ     add bl,clπ     mov dl,[si+bx]π     xor dh,dhπ     mov bl,chπ     mov al,[si+bx]π     add si,dxπ     mov bx,bpπ     add bl,alπ     mov bl,[bx+offset stab2]π     mov bh,blπ     mov dx,40π   @again:π     lodswπ     add ax,bxπ     stoswπ     dec dxπ     jnz @againπ     cmp si,offset stab1[256]π     jb @1π     sub si,256π   @1:π     inc bpπ     cmp bp,58π     jne @loooooopπ     in al,60hπ     cmp al,1π     jne @mainπ     pop bpπ  end;π  textmode(lastmode);πend.ππ                                                                                          121    08-24-9413:50ALL                      OLAF BARTELT             VGA 640X480x16           SWAG9408    G%¿φ    11     ╓   {π NV>     Could somebody tell me how to use mode 640x480x16? Iπ NV> don't mean using     it with int 10, 'cause it's too slow,π NV> but writing directly to VGA     memory. So how do I draw aπ NV> pixel and how do I read a pixel?πwell, you set the mode with:ππ      ASM MOV AX, 12h; INT 10h; END;ππand then draw a pixel with: }ππPROCEDURE plot_640x480x16(x, y : WORD; c : BYTE); ASSEMBLER;πASMπ  {$IFDEF DPMI}π  MOV ES, SEGA000π  {$ELSE}π  MOV AX, $A000π  MOV ES, AXπ  {$ENDIF}π  MOV DI, xπ  MOV CX, DIπ  SHR DI, 3π  MOV AX, 80π  MUL yπ  ADD DI, AXπ  AND CL, $07π  MOV AH, $80π  SHR AH, CLπ  MOV AL, $08π  MOV DX, $03CEπ  OUT DX, AXπ  MOV AL, cπ  MOV AH, [ES:DI]π  MOV [ES:DI], ALπEND;πππ{ and read a pixel with: }πππFUNCTION point_640x480x16(x, y : WORD) : BYTE; ASSEMBLER;πASMπ  MOV  AX, 80π  MUL  yπ  MOV  SI, xπ  MOV  CX, SIπ  SHR  SI, 3π  ADD  SI, AXπ  AND  CL, $07π  XOR  CL, $07π  MOV  CH, 1π  SHL  CH, CLπ  {$IFDEF DPMI}π  MOV  ES, SEGA000π  {$ELSE}π  MOV  AX, $A000π  MOV  ES, AXπ  {$ENDIF}π  MOV  DX, $03CEπ  MOV  AX, 772π  XOR  BL, BLπ@gp1:π  OUT  DX, AXπ  MOV  BH, ES:[SI]π  AND  BH, CHπ  NEG  BHπ  ROL  BX, $0001π  DEC  AHπ  JGE  @gp1π  MOV  AL, BLπEND;ππ                                                                                                                122    08-24-9413:51ALL                      LUIS MEZQUITA            Moving Poligon           SWAG9408    åMká    76     ╓   {πPS> I see that a lot of people around here have polygon, texture mapping andπPS> 3D routines so why don't you all post them here, even if you alreadyπPS> have done in the past cause there are people who didn't get themπPS> and want them :)π}ππ{$G+,R-}πProgram Polygoned_and_shaded_objects;ππ{ Mode-x version of polygoned objects          }π{ Originally by Bas van Gaalen & Sven van Heel }π{ Optimized by Luis Mezquita Raya              }ππuses Crt,x3Dunit2;π         { ^^^^^  Contained in GRAPHICS.SWG file }π{$DEFINE Object1}                       { Try an object between 1..4 }ππconstππ{$IFDEF Object1}                        { Octagon }π nofpolys=9;                            { Number of poligons-1 }ππ nofpoints=11;                          { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=5;                                  { Number of visible planes }ππ cr=23;                                 { RGB components }π cg=8;π cb=3;ππ point:array[0..nofpoints,0..2] of integer=(π    (-20,-20, 30),( 20,-20, 30),( 40,-40,  0),( 20,-20,-30),π    (-20,-20,-30),(-40,-40,  0),(-20, 20, 30),( 20, 20, 30),π    ( 40, 40,  0),( 20, 20,-30),(-20, 20,-30),(-40, 40,  0));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,7,6),(1,2,8,7),(9,8,2,3),(10,9,3,4),(10,4,5,11),π    (6,11,5,0),(0,1,2,5),(5,2,3,4),(6,7,8,11),(11,8,9,10));π{$ENDIF}ππ{$IFDEF Object2}                        { Cube }π nofpolys=5;                            { Number of poligons-1 }ππ nofpoints=7;                           { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=3;                                  { Number of visible planes }ππ cr=0;                                  { RGB components }π cg=13;π cb=23;ππ point:array[0..nofpoints,0..2] of integer=(π    (-40,-40, 40),( 40,-40, 40),( 40,-40,-40),(-40,-40,-40),π    (-40, 40, 40),( 40, 40, 40),( 40, 40,-40),(-40, 40,-40));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,5,4),(1,5,6,2),(6,7,3,2),π    (7,3,0,4),(0,1,2,3),(6,5,4,7));π{$ENDIF}ππ{$IFDEF Object3}                        { Octahedron }π nofpolys=7;                            { Number of poligons-1 }ππ nofpoints=5;                           { Number of points-1 }ππ polypoints=3;                          { Number of points for each poly }ππ sc=4;                                  { Number of visible planes }ππ cr=0;                                  { RGB components }π cg=3;π cb=23;ππ point:array[0..nofpoints,0..2] of integer=(π    (  0, 0,  45),(-40,-40,  0),(-40, 40,  0),( 40, 40,  0),π    ( 40,-40,  0),(  0,  0,-45));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,2,0),(0,2,3,0),(0,3,4,0),(0,4,1,0),π    (5,1,2,5),(5,2,3,5),(5,3,4,5),(5,4,1,5));ππ{$ENDIF}ππ{$IFDEF Object4}                        { Spiky }π nofpolys=15;                           { Number of poligons-1 }ππ nofpoints=19;                          { Number of points-1 }ππ polypoints=4;                          { Number of points for each poly }ππ sc=5;                                  { Number of visible planes }ππ cr=23;                                 { RGB components }π cg=5;π cb=5;ππ point:array[0..nofpoints,0..2] of integer=(π    (-10,-10, 30),( 10,-10, 30),( 30,-30,  0),( 10,-10,-30),π    (-10,-10,-30),(-30,-30,  0),(-10, 10, 30),( 10, 10, 30),π    ( 30, 30,  0),( 10, 10,-30),(-10, 10,-30),(-30, 30,  0),π    ( -2, -2, 60),( -2,  2, 60),(  2, -2, 60),(  2,  2, 60),π    ( -2, -2,-60),( -2,  2,-60),(  2, -2,-60),(  2,  2,-60));ππ planes:array[0..nofpolys,0..3] of byte=(π    (0,1,14,12),(7,15,13,6),(1,14,15,7),(6,13,12,0),π    (1,2,8,7),(9,8,2,3),π    (10,9,19,17),(10,4,16,17),(3,4,16,18),(3,9,19,18),π    (10,4,5,11),π    (6,11,5,0),(0,1,2,5),(5,2,3,4),(6,7,8,11),(11,8,9,10));π{$ENDIF}ππtype  polytype=array[0..nofpolys] of integer;π      pointype=array[0..nofpoints] of integer;ππ      ptnode=word;π      stack=ptnode;ππconst soplt=SizeOf(polytype);π      sopit=SizeOf(pointype);π      xst:integer=1;π      yst:integer=1;π      zst:integer=-2;ππvar   polyz,pind:array[byte] of polytype;π      xp,yp:array[byte] of pointype;π      phix:byte;ππProcedure QuickSort(lo,hi:integer); assembler; { Iterative QuickSort }πvar i,j,x,y:integer;                           { NON RECURSIVE }πasmπ        mov ah,48h                      { Init stack }π        mov bx,1π        int 21hπ        jc @exitπ        mov es,axπ        xor ax,axπ        mov es:[4],axππ        mov cx,lo                       { Push(lo,hi) }π        mov dx,hiπ        call @Pushππ@QS:    mov ax,es:[4]                   { ¿Stack empty? }π        and ax,axπ        jz @Emptyππ        mov cx,es:[0]                   { Top(lo,hi) }π        mov dx,es:[2]π        mov lo,cxπ        mov hi,dxππ        mov bx,es:[4]                   { Pop }π        mov ah,49hπ        int 21hπ        jc @exitπ        mov es,bxππ        mov ax,cx                       { ax:=(i+j) div 2 }π        mov bx,dxπ        add ax,bxπ        shr ax,1ππ        lea bx,polyz                    { ax:=polyz[ax] }π        call @indexπ        mov x,axππ@Rep:   mov ax,cx                       { repeat ... }π        lea bx,polyz                    { while polyz[i]<x do ... }π        call @indexπ        cmp ax,xπ        jge @Rep2π        inc cx                          { inc(i); }π        jmp @Repππ@Rep2:  mov ax,dx                       { while x<polyz[j] do ... }π        call @indexπ        cmp x,axπ        jge @EndRπ        dec dx                          { dec(j); }π        jmp @Rep2ππ@EndR:  cmp cx,dx                       { if i>j ==> @NSwap}π        jg @NBlππ        je @NSwapπ        push cxππ        mov ax,cxπ        call @indexπ        mov cx,ax                       { cx:=polyz[i] }π        mov si,diππ        mov ax,dx                       { polyz[i]:=polyz[j] }π        call @indexπ        mov [si],axππ        mov [di],cx                     { polyz[j]:=cx }π        pop axππ        push axπ        lea bx,pindπ        call @indexπ        mov cx,ax                       { cx:=pind[i] }π        mov si,diππ        mov ax,dx                       { pind[i]:=pind[j] }π        call @indexπ        mov [si],axππ        mov [di],cx                     { pind[j]:=cx }ππ        pop cxπ@NSwap: inc cxπ        dec dxππ@NBl:   cmp cx,dx                       { ... until i>j; }π        jle @Repππ        mov i,cxπ        mov j,dxππ        mov dx,hi                       { if i>=hi ==> @ChkLo }π        cmp cx,dxπ        jge @ChkLoππ        call @Push                      { Push(i,hi) }ππ@ChkLo: mov cx,lo                       { if lo>=j ==> @QSend }π        mov dx,jπ        cmp cx,dxπ        jge @QSendππ        call @Push                      { Push(lo,j) }ππ@QSend: jmp @QS                         { loop while stack isn't empty }ππ@Empty: mov ah,49hπ        int 21hπ        jmp @exitππ@index: shl ax,1                        { ax:=2*ax }π        add ax,bxπ        mov di,axπ        push bxπ        mov bl,sopltπ        mov al,phixπ        xor ah,ahπ        mul blπ        add di,ax                       { di=2*index+SizeOf(polytype)+polyz }π        pop bxπ        mov ax,[di]π        retππ@Push:  mov ah,48h                      { Push into stack }π        mov bx,1π        int 21hπ        jc @exitπ        mov bx,esπ        mov es,axπ        mov es:[0],cxπ        mov es:[2],dxπ        mov es:[4],bxπ        mov di,axπ        retππ@exit:πend;ππProcedure Calc;πvar z:pointype;π    spx,spy,spz,π    cpx,cpy,cpz,π    zd,x,y,i,j,k:integer;π    n,key,phiy,phiz:byte;πbeginπ phix:=0;π phiy:=0;π phiz:=0;π FillChar(xp,sizeof(xp),0);π FillChar(yp,sizeof(yp),0);ππ repeatππ  spx:=sinus(phix);                     { 'Precookied' constanst }π  spy:=sinus(phiy);π  spz:=sinus(phiz);ππ  cpx:=cosinus(phix);π  cpy:=cosinus(phiy);π  cpz:=cosinus(phiz);ππ  for n:=0 to nofpoints doπ   beginπ    i:=(cpy*point[n,0]-spy*point[n,2]) div divd;π    j:=(cpz*point[n,1]-spz*i) div divd;π    k:=(cpy*point[n,2]+spy*point[n,0]) div divd;π    x:=(cpz*i+spz*point[n,1]) div divd;π    y:=(cpx*j+spx*k) div divd;π    z[n]:=(cpx*k-spx*j) div divd;π    zd:=z[n]-dist;π    xp[phix,n]:=(160+cpx)-(x*dist) div zd;π    yp[phix,n]:=(200+spz) div 2-(y*dist) div zd;π   end;ππ  for n:=0 to nofpolys doπ   beginπ    polyz[phix,n]:=(z[planes[n,0]]+z[planes[n,1]]+π                    z[planes[n,2]]+z[planes[n,3]]) div 4;π    pind[phix,n]:=n;π   end;ππ  QuickSort(0,nofpolys);π  inc(phix,xst);π  inc(phiy,yst);π  inc(phiz,zst);π until phix=0;πend;ππProcedure ShowObject;πvar n:byte; pim:integer;πbeginπ retrace;π if address=0π then address:=16000π else address:=0;π setaddress(address);π cls;π for n:=sc to nofpolys doπ  beginπ   pim:=pind[phix,n];π   polygon(xp[phix,planes[pim,0]],yp[phix,planes[pim,0]],π           xp[phix,planes[pim,1]],yp[phix,planes[pim,1]],π           xp[phix,planes[pim,2]],yp[phix,planes[pim,2]],π           xp[phix,planes[pim,3]],yp[phix,planes[pim,3]],π           polyz[phix,n]+30);π  end;πend;ππProcedure Rotate;πvar i:byte;πbeginπ setmodex;π address:=0;π Triangles:=polypoints=3;π for i:=1 to 80 do setpal(i,cr+i shr 1,cg+i shr 1,cb+i shr 1);π setborder(63);π repeatπ  ShowObject;π  inc(phix,xst);π until KeyPressed;π setborder(0);πend;ππvar i:byte;π    s:stack;π    x,y:integer;ππbeginπ {border:=True;}π if ParamCount=1π then beginπ       Val(ParamStr(1),xst,yst);π       if yst<>0 then Halt;π       zst:=-2*xst;π       yst:=xst;π      end;π WriteLn('Wait a moment ...');π Calc;π Rotate;π TextMode(LastMode);πend.ππ        But ... wait a moment ... you also need x3dUnit2.pasπ        which is also included in the SWAG filesπ                              123    08-24-9413:56ALL                      SIMEON SPRY              SCI File Viewer          SWAG9408    ;{åµ    19     ╓   πProgram ViewASCi;ππ{ Simple SCi Viewer - By Simeon SpryππThis code will display a SCi (320*200*256) file. I would reccomend that youπadd code to find out if the SCi File name is valid. I had some, but I gotπit out of a book so it *might* be copyrighted :-(. You also might want toπsave the old pallete and restore it afterwards I didn't do it because Iπlost my reference.ππThis may be freely distributed, if you incorporate any portions of thisπcode into a part of anything you MUST give me some credit.π}πππProcedure ViewSci( SciF : STRING);π CONST    Header : Array[1..4] OF CHAR = ('R','I','X','3');ππ VAR     SciFile : File;π         HeaderBuf : Array[1..10] OF CHAR;π         NewPal    : Array[1..768] OF BYTE; { 3 Bytes Per colour, 3*256 = 768}π         OldPal    : Array[1..768] OF BYTE; { "  "  "}π         Screen    : Array[1..64000] OF BYTE ABSOLUTE $A000:0000; { Direct toπthe screen }π         i         : integer;π Procedure SetPal(Pallete : Array OF BYTE);π VARπ   PalPtr : POINTER;π BEGINπ  PalPtr := @Pallete;π  asmπ   mov ax,1012hπ   xor bx,bxπ   mov cx,0100hπ   les dx,PalPtrπ   int 10hπ  end;π END;ππ Procedure WaitForKey;assembler;π  ASMπ   xor ax,axπ   int 16hπ  END;πProcedure SetMode(Mode : BYTE); assembler;π  ASMπ    mov ah, 00π    mov al, modeπ    int 10hπ  END;ππ BEGINπ  { Open The File }π  assign(SciFile, SciF);π  Reset(SciFile,1);ππ  { Check The Header }π  BlockRead(SciFile,HeaderBuf,SizeOF(HeaderBuf));π  For i := 1 to 4 DOπ   Beginπ    If HeaderBuf[i] <> Header[i] Thenπ     BEGINπ      WriteLn;π      WriteLn(' Invalid SCI File. ');π      WriteLn;π      Halt(1);π     END;π   End;ππ { Set Mode $13 }π SetMode($13);ππ { Read Pallete into a 768 Byte Buffer & DisPlay. }π  BlockRead(SciFile,NewPal,768);π  SetPal(NewPal);ππ { Read 64000 bytes then write DIRECTLY to Video Memory }π  BlockRead(SCIFile,Screen,64000);π  cLOSE(SCIFILE);π { Wait Until Key Pressed }π WaitForKey;ππ { Set Text Mode }π  SetMode($3);πEND;ππVar SciFile : String[12];ππBEGINπ   { Ask For File To View }π  WriteLn('SCi Viewer - By Simeon Spry');π  Write('View File: ');π  ReadLn(SciFile);ππ   { View SCi File }π  ViewSCI( SciFile );ππ   { Display Made-By Message }π  WriteLn('Simple SCi Viewer by Simeon Spry');π  WriteLn;πEND.π                                                                      124    08-24-9413:56ALL                      BAS VAN GAALEN           Scroll Bars              SWAG9408    Ω╠E▒    36     ╓   USES dos, crt;ππCONSTπ    v_vidseg   : WORD = $B800;  { $B000 for mono }π    v_columns  : BYTE = 80;     { Number of CRT columns }ππVARπ    x : BYTE;π{πthe dspat routine, as you can see.  Displays a string QUICKLYπIf 'Col' (=columns, NOT color) is negative (-1) the centence will be centered.πWorks also in exotic screenmodes, like 132x44, 100x44 or whatever you like.π}πprocedure dspat(Str : string; Col : integer; Row,Attr : byte); assembler;πasmπ  push ds          { Save Turbo's DS }π  mov es,v_vidseg  { Place VideoBuffer in es }π  xor dh,dh        { Clear DH }π  mov dl,v_columns { Bytes per row }ππ  lds si,Str       { DS:SI pts to Str }π  xor cx,cx        { clear CX }π  mov cl,[si]      { String len counted in CX }π  jcxz @l5         { If null, quit }π  inc si           { Point DS:SI to first char }ππ  mov ax,Col       { Get Column value }π  cmp ax,0π  jge @l6          { Absolute, or centered? }ππ  mov ax,dxπ  sub ax,cx        { Substract stringlen from total }π  shr ax,1         { Centre}ππ @l6:π  mov di,axπ  shl di,1         { Double for attributes }ππ  mov al,Row       { Get Row value }π  mul dl           { Times rows }π  shl ax,1ππ  add di,ax        { ES:DI pts to lst pos }π  cld              { Direction flag forward }π  mov ah,Attr      { Get Attribute }π @l1:π  lodsb            { Get a character}π  stosw            { Write it with attribute }π  loop @l1         { Go do next }π @l5:π  pop ds           { Restore DS and quit }πend;ππprocedure filltext(Dir : char; X1,Y1,X2,Y2,Col : byte); assembler;πasmπ  push ds          { Save Turbo's DS }ππ  xor dh,dh        { Clear DH }π  mov dl,v_columns { Bytes per row (number of columns) }ππ  xor ah,ahπ  mov es,v_vidseg  { Place VideoBuffer in ES and DS }π  mov al,[X1]π  mov di,axπ  shl di,1         { Double for attributes }π  mov al,[Y1]      { Get Row value }π  mul dl           { Times rows }π  shl ax,1π  add di,ax        { ES:DI pts to upperleft corner }ππ  xor ch,chπ  mov cl,[X2]π  inc clπ  sub cl,[X1]      { Number of bytes to move in CL (columns) }π  xor bh,bhπ  mov bl,[Y2]π  inc blπ  sub bl,[Y1]      { Number of rows to move in BL }ππ  sub dl,[X2]      { Substract right site }π  dec dlπ  shl dx,1         { Times two for attribs }π  xor ah,ah        { Clear AH }π  mov al,[X1]      { Left site }π  shl ax,1         { Times two for attribs }π  add dx,ax        { Calculated difference between last col - first col }ππ  mov al,[Dir]π  mov ah,[Col]ππ  cld              { Direction flag forward }π @L1:π  push cxπ  rep stoswπ  pop cxπ  add di,dxπ  dec blπ  jnz @L1ππ  pop ds           { Restore DS and quit }πend;ππ{ Displays Veritical scrollbar }πprocedure ScrollBar(BarXPos,π                    BarYPos : byte;π                    CurPos,π                    ScrLen,                     { max screen row }π                    NofItems : word;π                    ColAttr : byte);πvar barpos,maxpos : word;πbeginπ  dspat(#30,barxpos,barypos,colattr);π  dspat(#31,barxpos,barypos+scrlen-1,colattr);π  filltext('▒',barxpos,barypos+1,barxpos,barypos+scrlen-2,colattr);π  if nofitems >= 1 then beginπ    maxpos := scrlen-3;π    if nofitems <> 1 then barpos := round(((curpos-1)/(nofitems-1))*maxpos)π    else barpos := 0;π    dspat('■',barxpos,barypos+barpos+1,colattr);π  end;πend; { ScrollBar }ππBEGIN  { demo coded by Gayle Davis for SWAG 8/18/94 }ππ   ClrScr;π   { put at col 40 of Row x, 3rd item selected }ππ   FOR X := 1 to 24 DOπ       BEGINπ       ScrollBar(40,1,x,22,40,31);π       DELAY(300);π       END;ππEND.ππThe assembler stuff is nicely documented, so shouldn't be a problem. What'sπmissing here, you can define as constants at the top of your source, or try toπfind out using interrupt-calls or whatever...ππBtw: these routines are taken from my very private video-unit, and seem to workπon many different configurations (so far...) But that's also due to the factπthat the v_columns is found through some interrupt-calls and stuff...πThe routines work also in 132x44 or whatever strange video-mode.ππAnother point of discussion: no snow-checking is performed. I got in someπanoying discussions about this, because (imho) CGA's are hardly used theseπdays. So it seems a little ... nuts ... to make support for that hand full ofπCGA-users. Ah well, enclose the sc yourself. it's not hard, but it REALY slow'sπstuff down. And these routines were designed with SPEED as first concern andπcompatibily with MODERN hardware as a second...ππ _    _π|_]  | _π|__].|__].π                     125    08-24-9413:56ALL                      JENS LARSSON             Scrolling Images         SWAG9408    »ƒm    18     ╓   {πMichael, you wondered how you could scroll an image (320*200) over theπscreen. And yes, as you probably have figured out, the most reliableπsolution to that is mode-x (or tweaked mode or whatever...).πHere's an example program:ππ--------------------------------------------------------->8-------------------π{ππ Mode-x scrolling, by Jens Larsson 2:201/2120.3, Sweden, PD.π ( btw, hope you know some assembly... <g> )ππ}π{$G+}πUses Crt;ππ   Var i, ScrBase : Word;ππ    Procedure PutPix(x, y : Word; Color : Byte); Assembler;π      Asmπ        mov     ax,0a000hπ        mov     es,axπ        mov     bx,xπ        mov     dx,3c4hπ        mov     ax,0102hπ        mov     cl,blπ        and     cl,3π        shl     ah,clπ        out     dx,axπ        mov     ax,yπ        shl     ax,4π        mov     di,axπ        shl     ax,2π        add     di,axπ        shr     bx,2π        add     di,bxπ        add     di,ScrBaseπ        mov     al,Colorπ        mov     es:[di],alπ      End;ππ    Procedure ScrPan(ScrOfs : Word); Assembler;π      Asmπ        mov     bx,ScrOfsπ        mov     dx,3d4hπ        mov     ah,bhπ        mov     al,0chπ        out     dx,axπ        mov     ah,blπ        inc     alπ        out     dx,axπ      End;ππ    Procedure SetModeX; Assembler;π      Asmπ        mov     ax,0012hπ        int     10hπ        mov     ax,0013hπ        int     10hπ        mov     dx,3c4hπ        mov     ax,0604hπ        out     dx,axπ        mov     dx,3d4hπ        mov     ax,0014hπ        out     dx,axπ        mov     ax,0e317hπ        out     dx,axπ      End;ππ    Procedure Synk; Assembler;π      Asmπ        mov     dx,3dahπ@L1:π        in      al,dxπ        test    al,08hπ        jne     @L1π@L2:π        in      al,dxπ        test    al,08hπ        je      @L2π      End;ππ       Beginπ         Randomize;π         SetModeX;π         ScrBase := 200*80;π         For i := 0 to 9999 do PutPix(Random(320),Random(200),Random(256));π         For i := 0 to 200 do Beginπ           ScrPan(i*80);π           Synk;π          End;π         ReadKey;π         Asm; mov ax,0003h; int 10h; End;π       End.ππ                                                                    126    08-24-9413:58ALL                      JOHN HOWARD              Sprite Game              SWAG9408    ▀î/{    94     ╓   πprogram SpriteGame;         {Verifies a VGA is present}π{$G+,R-}π(* jh  Syntax:  spritegame.exe  [number]π  optional number is the total population of sprites.  Default is maxsprites.π*)π{ Original Sprites program by Bas van Gaalen, Holland, PD }π{ Modified by Luis Mezquita Raya }π{ Modified by John Howard (jh) into a game }π{ 30-MAY-1994 jh Version 1.0π  Now a game to see which sprite survives the longest.π  Renamed tScrArray to Screen, and tSprArray to SpriteData.π  Removed CRT unit & saved around 1616 bytes.  Added command line parameter.π  Added timer and energy definitions to provide statistics.π  21-JUN-1994 jh Version 1.1 = ~7.5kπ  Added OnlyVGA and SetMode procedures.  Added CharSet & CharType definitions.π  Implemented characters as sprites.π  29-JUN-1994 jh Version 1.2 = ~8.5k due to command line helpπ  Places identification on each sprite by using HexDigits.  CharColor defaultsπ  to sprite number (0..maxsprites) as a color index in the palette.  Fixed bugπ  in moire background screen limits.π}πconstπ      maxsprites=128;                   { Number of sprites is [1..128] }π      pxsize=320;                       { screen x-size }π      pysize=200;                       { screen y-size }π      xsize=32;                         { sprite x-size }π      ysize=32;                         { sprite y-size }π      CharRows=8;                       { Characters are 8 rows high }π      HexDigits : ARRAY[0..15] OF Char = '0123456789ABCDEF';ππtypeπ      Screen=array[0..pysize-1, 0..pxsize-1] of byte;π      pScreen=^Screen;π      SpriteData=array[0..ysize-1, 0..xsize-1] of byte;π      pSpriteData=^SpriteData;π      SprRec=recordπ              x,y : word;              {Absolute location of sprite}π              xspd,yspd : shortint;    {Velocity horizontal and vertical}π              energy : shortint;       {Hide is neg., dead is 0, show is pos.}π              buf : pSpriteData;       {Rectangle of sprite definition}π             end;π      CharType = array[1..CharRows] of Byte;ππvarπ      CharSet : array[0..255] of CharType absolute $F000:$FA6E;π      sprite : array[1..maxsprites] of SprRec;π      vidscr,virscr,bgscr : pScreen;   {video, virtual, background screens}π      dead : byte;                     {Counts the dead sprites}π      survivor : byte;                 {Identify the last dead sprite}π      Population : word;               {Population from 1..128}π      {CharColor : byte;}              {Character digit color 0..255}ππ      Timer : longint;                 {Stopwatch}π      H, M, S, S100 : Word;π      Startclock, Stopclock : Real;π      mins, secs     : integer;π      Code: integer;                     {temporary result of VAL conversion}ππprocedure GetTime(var Hr, Mn, Sec, S100 : word); assembler; {Avoids DOS unit}πasmπ    mov ah,2chπ    int 21hπ    xor ah,ah                 {fast register clearing instead of MOV AH,0}π    mov al,dlπ    les di,S100π    stoswπ    mov al,dhπ    les di,Secπ    stoswπ    mov al,clπ    les di,Mnπ    stoswπ    mov al,chπ    les di,Hrπ    stoswπend;ππprocedure StartTimer;πbeginπ  GetTime(H, M, S, S100);π  StartClock := (H * 3600) + (M * 60) + S + (S100 / 100);πend;ππprocedure StopTimer;πbeginπ  GetTime(H, M, S, S100);π  StopClock := (H * 3600) + (M * 60) + S + (S100 / 100);π  Timer := trunc(StopClock - StartClock);π  secs := Timer mod 60;                             {Seconds remaining}π  mins := Timer div 60;                             {Reduce into minutes}πend;πfunction KeyPressed : boolean; assembler;   {Avoids unit CRT.KeyPressed}πasmπ    mov ah,01h;    int 16h;    jnz @0;    xor ax,ax;    jmp @1;π@0: mov al,1π@1:πend;ππprocedure SetMode(M:byte); assembler;πasmπ    mov ah,0;        mov al,M;        int 10h;πend;πprocedure SetPal(col,r,g,b:byte); assembler;      {256 color palette}πasmπ    mov dx,03c8hπ    mov al,col             {color}π    out dx,alπ    inc dxπ    mov al,r               {red component}π    out dx,alπ    mov al,g               {green component}π    out dx,alπ    mov al,b               {blue component}π    out dx,alπend;πprocedure flip(srcscr, destscr : pScreen); assembler;   {copy screen}πasmπ    push dsπ    lds si,srcscrπ    les di,destscrπ    mov cx,pxsize*pysize/2π    rep movswπ    pop dsπend;πprocedure cls(scr : pScreen); assembler;   {clear screen}πasmπ    les di,scr;  xor ax,ax;  mov cx,pxsize*pysize/2;  rep stoswπend;πprocedure retrace; assembler;πasmπ        mov dx,03dahπ@vert1: in al,dxπ        test al,8π        jnz @vert1π@vert2: in al,dxπ        test al,8π        jz @vert2πend;πprocedure PutSprite(var sprite: SprRec; virseg: pScreen); assembler;πasmπ        push dsπ        lds si,sprite                   { get sprite segment }π        les di,virseg                   { get virtual screen segment }π        mov ax,SprRec[ds:si].yπ        shl ax,6π        mov di,axπ        shl ax,2π        add di,ax                       { y*pxsize }π        add di,SprRec[ds:si].x          { y*pxsize+x }π        mov dx,pxsize-xsize             { number of pixels left on line }π        lds si,SprRec[ds:si].bufπ        mov bx,ysizeπ@l1:    mov cx,xsizeπ@l0:    lodsbπ        or al,alπ        jz @skip                        { check if transparent "Black" }π        mov es:[di],al                  { draw it }π@skip:  inc diπ        dec cxπ        jnz @l0π        add di,dxπ        dec bxπ        jnz @l1π        pop dsπend;πprocedure OnlyVGA; assembler;πasmπ  @CheckForVga: {push    es}π                mov     AH,1ah         {Get Display Combination Code}π                mov     AL,00h         {AX := $1A00;}π                int     10h            {Intr($10, Regs);}π                cmp     AL,1ah         {IsVGA:= (AL=$1A) AND((BL=7) OR(BL=8))}π                jne     @NoVGAπ                cmp     BL,07h         {VGA w/ monochrome analog display}π                je      @VgaPresentπ                cmp     BL,08h         {VGA w/ color analog display}π                je      @VgaPresentπ  @NoVGA:π                mov     ax,3           {text mode}π                int     10hπ                push    csπ                pop     dsπ                lea     dx,@messageπ                mov     ah,9π                int     21h            {print $ terminated string}π                mov     ax,4c00hπ                int     21h            {terminate}π  @message:     db      'Sorry, but you need a VGA to see this!',10,13,24hπ  @VgaPresent:  {pop     es}π  {... After here is where your VGA code can execute}πend;  {OnlyVGA}ππVAR   n : byte;               {sprite number}π      hx,hy,i,j,k,np : integer;πBEGIN  {PROGRAM}π {Get text from command line and convert into a number}π Val(ParamStr(1), Population, Code);π if (Code <> 0)    {writeln('Bad number at position: ', Code);}π   OR (Population <1) OR (Population > maxsprites) thenπ   Population := maxsprites;    {default}π if ParamStr(1) = '?' thenπ   beginπ    writeln('Howard International, P.O. Box 34633, NKC, MO 64116 USA');π    writeln('1994 Freeware Sprite Game v1.2');π    writeln('Syntax:  spritegame.exe  [number]');π    writeln('         optional number is the total population of sprites (1 to 128)');π    halt;π   end;ππ {CharColor := Population;}π OnlyVGA;π SetMode($13);                  {320x200x256x1 plane}π Randomize;π vidscr := Ptr($A000,0);π New(virscr); cls(virscr); New(bgscr); cls(bgscr);π np := 128 div Population;π for i := 0 to Population-1 doπ  begin  {Define moire background pattern}π   case i mod 6 ofπ    0:beginπ       hx := 23;       hy := i*np;       n := 0;π      end;π    1:beginπ       hx := i*np;     hy := 23;         n := 0;π      end;π    2:beginπ       hx := i*np;     hy := 0;          n := 23;π      end;π    3:beginπ       hx := 23;       hy := 0;          n := i*np;π      end;π    4:beginπ       hx := 0;        hy := 23;         n := i*np;π      end;π    5:beginπ       hx:= 0;         hy:= i*np;        n := 23;π      end;π   end;π   for j := 0 to np-1 doπ    beginπ     k := j shr 1;π     SetPal(np*i+j+1, k+hx, k+hy, k+n);π    end;π  end;ππ for i := 1 to 127 do SetPal(127+i, i div 3, 20+i div 5, 20+i div 7);π for i := 0 to pxsize-1 do     {jh bug!  Reduce to legal screen limits}π   for j := 0 to pysize-1 doπ     bgscr^[j,i] := 128+ ABS(i*i - j*j) and 127;π(*π flip(bgscr, vidscr);               {copy background to video}π {SetPal(?,r,g,b)}                  {force a visible text palette entry}π writeln('Sprite Game v1.2 ');      {modify video}π flip(vidscr, bgscr);               {copy video to background}π*)π hx := xsize shr 1;π hy := ysize shr 1;π for n := 1 to Population doπ  beginπ   with sprite[n] doπ    beginπ     x := 20+ random(280 - xsize);π     y := 20+ random(160 - ysize);π     xspd := random(6) - 3;π     yspd := random(6) - 3;π     energy := random(10);         {punishes liberals}π     if xspd=0 thenπ       beginπ        xspd := 1;π        energy := random(20);      {average life expectancy}π       end;π     if yspd=0 thenπ       beginπ        yspd := 1;π        energy := random(40);      {rewards conservatives}π       end;π     New(buf);π     for i := 0 to xsize-1 doπ      for j := 0 to ysize-1 doπ       beginπ        k := (i-hx) * (i-hx) + (j-hy) * (j-hy);π        if (k< hx*hx) and (k> hx*hx div 16)π        then buf^[j,i] := k mod np  + np * (n-1)π        else buf^[j,i] := 0;       {CRT color "Black" is transparent}π       end;π    end; {with}π  end; {for}ππ  {jh Can store your own bitmap image in any sprite[n].buf^[j,i] such as: }π  for i := 0 to xsize-1 doπ    for j := 0 to ysize-1 doπ      beginπ        sprite[1].buf^[j,i] := j;           {first sprite.  Horizontal bars}π        sprite[Population].buf^[j,i] := i;  {last sprite.  Vertical bars}π      end;ππ  {jh Get characters from default font and attach to sprites}π  for i := 1 to CharRows doπ    for j := 1 to CharRows doπ      beginπ        for n := 1 to Population doπ          beginπ            {first hex digit for current sprite}π            if (CharSet[ord(HexDigits[n SHR 4]),i] shr (8-j) and 1 = 1) thenπ              sprite[n].buf^[i,j] := n       {CharColor}π            elseπ              sprite[n].buf^[i,j] := 0;      {transparent}π            {second hex digit for current sprite}π            if (CharSet[ord(HexDigits[n AND $F]),i] shr (8-j) and 1 =1) thenπ              sprite[n].buf^[i,j+CharRows] := n   {CharColor}π            elseπ              sprite[n].buf^[i,j+CharRows] := 0;  {transparent}π          end;π(* {mark last sprite 'Z'}π   sprite[Population].buf^[i,j] := CharSet[ord('Z'),i] shr (8-j) and 1; *)π      end;ππ  {jh Keep track of the last dead sprite and how old it was. }π  StartTimer;π  while not (KeyPressed or (dead=Population)) doπ  beginπ  flip(bgscr, virscr);π  retrace;π  dead := 0;                         {reset the sentinel}π  for n := 1 to Population doπ    with sprite[n] doπ    beginπ      if energy > 0 then PutSprite(sprite[n], virscr)     {show(n)}π      { else if energy < 0 then hide(n) }π      else inc(dead);π      inc(x,xspd);π      if (x<10) or (x > (310 - xsize)) thenπ      beginπ        xspd := -xspd;π        energy := energy - 1;π      end;π      inc(y,yspd);π      if (y<10) or (y > (190 - ysize)) thenπ      beginπ        yspd := -yspd;π        energy := energy - 1;π      end;π    end; {with}π  flip(virscr, vidscr);π  end; {while}ππ  StopTimer;π  survivor := 0;π  for n := 1 to Population doπ    begin                           {find last dead sprite with zero energy}π      if sprite[n].energy = 0 then survivor := n;π      Dispose(sprite[n].buf);π    end;π  Dispose(virscr);  Dispose(bgscr);π  SetMode($3);      {resume text video mode 3h= 80x25x16 color}π  writeln('Last dead sprite was # ', survivor, ' of ', Population);π  writeln('Time of death was ', trunc(StopClock));π  writeln('Life span was ', mins:2, ' Minute and ', secs:2, ' Seconds');πEND.   {PROGRAM}π                                                                                                                         127    08-24-9413:58ALL                      BAS VAN GAALEN           More STAR-ROUTINE        SWAG9408    
  4. Q╘≡    19     ╓   {πHowdy all!ππBy request here's the stars-routine, the final update. ;-)πLimits: cpu-speed and conv.-memory. No others...ππ}πprogram _stars;π{ Done by Sven van Heel and Bas van Gaalen, Holland, PD }πuses crt;πconstπ  f=6; nofstars=100; vidseg:word=$a000;π  bitmask:array[0..1,0..4,0..4] of byte=(π    ((0,0,1,0,0),(0,0,3,0,0),(1,3,6,3,1),(0,0,3,0,0),(0,0,1,0,0)),π    ((0,0,6,0,0),(0,0,3,0,0),(6,3,1,3,6),(0,0,3,0,0),(0,0,6,0,0)));πtype starstruc=recordπ  xp,yp:word; phase,col:byte; dur:shortint; active:boolean; end;πvar stars:array[1..nofstars] of starstruc;ππprocedure setpal(col,r,g,b : byte); assembler; asmπ  mov dx,03c8h; mov al,col; out dx,al; inc dx; mov al,rπ  out dx,al; mov al,g; out dx,al; mov al,b; out dx,al; end;ππprocedure retrace; assembler; asmπ  mov dx,3dah; @vert1: in al,dx; test al,8; jz @vert1π  @vert2: in al,dx; test al,8; jnz @vert2; end;ππvar i,x,y:word;πbeginπ  asm mov ax,13h; int 10h; end;π  for i:=1 to 10 do beginπ    setpal(i,f*i,0,0); setpal(21-i,f*i,0,0); setpal(20+i,0,0,0);π    setpal(30+i,0,f*i,0); setpal(51-i,0,f*i,0); setpal(50+i,0,0,0);π    setpal(60+i,0,0,f*i); setpal(81-i,0,0,f*i); setpal(80+i,0,0,0);π    setpal(90+i,f*i,f*i,0); setpal(111-i,f*i,f*i,0); setpal(110+i,0,0,0);π    setpal(120+i,0,f*i,f*i); setpal(141-i,0,f*i,f*i); setpal(140+i,0,0,0);π    setpal(150+i,f*i,f*i,f*i); setpal(171-i,f*i,f*i,f*i); setpal(170+i,0,0,0);π  end;π  randomize;π  for i:=1 to nofstars do with stars[i] do beginπ    xp:=0; yp:=0; col:=0; phase:=0;π    dur:=random(20);π    active:=false;π  end;π  repeatπ    retrace; retrace;π    {setpal(0,0,0,30);}π    for i:=1 to nofstars do with stars[i] do beginπ      dec(dur);π      if (not active) and (dur<0) then beginπ        active:=true; phase:=0; col:=30*random(6);π        xp:=random(315); yp:=random(195);π      end;π    end;π    for i:=1 to nofstars do with stars[i] doπ      if active then beginπ        for x:=0 to 4 do for y:=0 to 4 doπ          if bitmask[byte(phase>10),x,y]>0 thenπ            mem[vidseg:(yp+y)*320+xp+x]:=bitmask[byte(phase>10),x,y]+col+phase;π        inc(phase);π        if phase=20 then begin active:=false; dur:=random(20); end;π      end;π    setpal(0,0,0,0);π  until keypressed;π  textmode(lastmode);πend.π                                                                                      128    08-24-9417:50ALL                      ERIC COOLMAN             Another Fire Graphic     SWAG9408    ╔V·    67     ╓   {πAC>I got my hands on Jare's fire code and thought it was pretty cool,πAC>so I made my own fire program. Although it didn't turn out like IπAC>thought it would (like Jare's) what I have is (at least I think so)πAC>something that looks more realistic.ππThis is kinda funny... just the other day I was looking at Jare's fireπcode, and did an 80x50 textmode version of it in C.  I did a quick andπdirty conversion of it to Pascal so I could post it here for youπ(don't you feel special? <G>).  The pascal version came out a bitπslower then my C version, although they are very similar. I haven'tπfigured out why though... most times I try this, both come out closeπto the same speed.ππ(********************************************************************π Fire by Eric Coolman (aka. Digitar/SKP), Simple Minded Softwareπ Much like Jare's (VangelisTeam) fire, but uses 80x50x16 text modeπ rather than 320x200x256 (which was "tweaked" to look like 80x50π text mode).  Reference : FIRE.TXT by Phil Carlisle (aka Zoombapup,π CodeX) from PC Game Programmer's Encyclopedia (PCGPE10.ZIP) by Markπ Feldman and contributers (thanks for the great reads guys!).π Compiler : Turbo Pascal 6.0π Released to public domain, July 30, 1994.ππ NOTE: FirePalette will not get loaded if running under DESQviewπ       with "VIRTUALIZE TEXTMODE" on (which will stop any paletteπ       manipulation).  To fix, go into setup for the DOSBOX, andπ       under "VIRTUALIZE TEXT/GRAPHICS" mode, and set it to "N".π       Also for DV, set "WRITES DIRECT TO SCREEN" to "Y"es.π********************************************************************)π}ππProgram tFire;ππconstπ    MAXX = 80;π    MAXY = 50;π    { Our gradient firepalette (white/yellow/red/orange/slate/black) }π    FirePal : array[0..3*16-1] of byte =π      {       [ HUES ]       }π      {  RED    GREEN   BLUE }π      {  ===    =====   ==== }π      (                                               { Normal Color }π         0,     0,      0,                            { BLACK        }π         0,     5,      3,                            { BLUE         }π         0,     6,      7,                            { GREEN        }π         0,     7,      9,                            { CYAN         }π         0,     8,      11,                           { RED          }π         0,     9,      12,                           { MAGENTA      }π         63,    13,     0,                            { BROWN        }π         60,    4,      4,                            { LIGHTGRAY    }π         63,    58,     21,                           { DARKGRAY     }π         63,    59,     0,                            { LIGHTBLUE    }π         63,    60,     0,                            { LIGHTGREEN   }π         63,    60,     0,                            { LIGHTCYAN    }π         63,    61,     30,                           { LIGHTRED     }π         63,    55,     42,                           { LIGHTMAGENTA }π         63,    60,     55,                           { YELLOW       }π         63,    63,     63                            { WHITE        }π     );ππtypeπ     ColorArray = array [0..MAXX+1, 0..MAXY] of Byte;πvarπ    FireImage : ColorArray;π    CUR       : Word;                                { working color }π    x, y      : Byte;                             { general counters }ππ(*π Sets video mode.  If mode is 64d (40h), 8x8 ROM font will be loadedπ and 80x50 textmode will be activated.  Any other value will setπ mode normally.π*)πprocedure VidMode(mode : byte); assembler;πasmπ     cmp  mode, 40h                      { (64d) want 80x50/43 mode? }π     jnz  @normalsetπ     mov  ax,1112h                { set 8 point font as current font }π     mov  bl,00hπ     jmp  @MakeItSo                                            { ;-) }π   @normalset:π     mov  ah, 00hπ     mov  al, modeπ   @MakeItSo:π     int  10hπend;ππ{ grabs and dumps keypress...returns 1 if a key was hit, else 0 }πfunction KbGrab : boolean;πvarπ    WasHit : boolean;πbeginπ    WasHit := False;ππ    asmπ        mov ax, 0100hπ        int 16hπ        lahfπ        test ah, 40hπ        jnz @doneπ        inc WasHitπ        mov ax, 0000h                  { grab the key they hit .... }π        int 16hπ      @done:π    end;π    KbGrab := WasHit;πend;ππ(*********************************************************************π sets only color indexes normally used in textmode (16 of 'em).π Note the heavy use of ternary operator there... what that meansπ is - indexes 7 to 15 (dark gray to white) are actually indexesπ 55 to 63, and index 6 (dark brown) is actually 20d (14h) becauseπ it uses the secondary hues so that it doesn't look too much likeπ red.  The rest (0,1,2,4,5,7) are as expected.π*********************************************************************)πprocedure SetFirePal;πvarπ  i, j : Byte;πbeginπ   for i:= 0 to 16 do                               { for each index }π     beginπ       if i <= 7 then begin if i = 6 then j := 20 else j := i; endπ       else j := i+48;π       port[$3c8] := j;                             { Send the index }π       port[$3c9] := FirePal[i*3];                    { Send the red }π       port[$3c9] := FirePal[i*3+1];                { Send the green }π       port[$3c9] := FirePal[i*3+2];                 { Send the blue }π    end;πend;πππ(*********************************************************************π  +----+-----+----+ Table to left are screen ofs's surrounding CUR(0).π  |-81 | -80 |-79 | That we will take average of. 80 is for width ofπ  +----+-----+----+ screen in chars in textmode (also width of ourπ  | -1 | CUR | +1 | screen buffer).  The calculated average will beπ  +----+-----+----+ assigned to spot '-80' to move the fire upwards,π  |+79 | +80 |+81 | and decremented to fade it out (like a plasmaπ  +----+-----+----+ effect somewhat).π*********************************************************************)πprocedure DoFire;πbegin;π    { start at [1,1] or above because 0,0 doesn't have 8 surrounding }π    { stop x at 78 or less for the same reason (ending y doesn't     }π    { matter cause we are setting max y randomly anyways).           }π    { (starting y can be set to 8 to give room for a scroller).      }π     for y := 1 to MAXY doπ       for x := 1 to MAXX-1 doπ         beginπ          { get average of 8 surrounding colors              (-ofs-) }π          CUR := (  FireImage[x-1][y]         { direct to left  (-1) }π                  + FireImage[x+1][y]         { direct to right (+1) }π                  + FireImage[x][y-1]         { direct above   (-80) }π                  + FireImage[x][y+1]         { direct below   (+80) }π                  + FireImage[x-1][y-1]       { above to left  (-81) }π                  + FireImage[x+1][y+1]       { below to right (+81) }π                  + FireImage[x+1][y-1]       { above to right (-79) }π                  + FireImage[x-1][y+1]       { below to left  (+79) }π                ) shr 3;                      { divide by 8          }π         Dec(CUR);                            { make fire fade out   }π         { notice below is assigning the average CUR to (CUR-1 line) }π         { ... this keeps fire moving in upward direction.           }π         FireImage[x][y-1] := CUR;                       { set color }π         mem[$b800:y*160+(x shl 1)+1] := FireImage[x][y];π       end;ππ       { Randomly set last line of fire... This keeps the fire going }π      for x := 0 to 80 doπ         FireImage[x][49] := (random(255)+1);π      { second last line also to give fire some more height. }π      for x := 0 to 80 doπ         FireImage[x][48] := (random(255)+1);πend;ππbeginπ   VidMode($03);                     { 80x25 mode (to clear screen) }π   VidMode($40);                                       { 80x50 mode }ππ   SetFirePal;ππ  { change to hi-intense background so we have 16 bg colors to }π  { work with.                                                 }π  asmπ      mov ax, 1003h                                 { blinking attr }π      mov bx, 0000h            { 0=HiIntBackground, 1=Blinking Attr }π      int 10hπ  end;ππ  { clear fire image }π  fillchar(FireImage, sizeof(FireImage), 63);     { fill with white }ππ  for x := 0 to 80 do          { set up last line to start the fire }π    FireImage[x][49] := (random(255)+1);ππ  repeat DoFire; until KbGrab;ππ  VidMode($03);                                        { 80x25 mode }πend.π                                                         129    08-24-9417:53ALL                      DAVID DAHL               Transparent 3D Vectors   SWAG9408    ┬d    173    ╓   πProgram TrnsVect; { Transparent Vectors }π{$G+} { 286 Instructions Enabled }ππ{  Transparent 3D Vectors Example  }π{     Programmed by David Dahl     }π{  This program is PUBLIC DOMAIN   }ππUses CRT;πConst ViewerDist = 200;πType VGAArray = Array [0..199, 0..319] of Byte;π     VGAPtr   = ^VGAArray;π     PaletteRec  = Recordπ                         Red   : Byte;π                         Green : Byte;π                         Blue  : Byte;π                   End;π     PaletteType = Array [0..255] of PaletteRec;π     PalettePtr  = ^PaletteType;π     PolyRaster  = Recordπ                         X1 : Word;π                         X2 : Word;π                   End;π     PolyFill    = Array [0..199] of PolyRaster;π     PolyFillPtr = ^PolyFill;π     FacetPtr     = ^PolyFacet;π     PolyFacet    = Recordπ                          Color       : Byte;π                          X1, Y1, Z1,π                          X2, Y2, Z2,π                          X3, Y3, Z3,π                          X4, Y4, Z4  : Integer;π                          NextFacet   : FacetPtr;π                    End;π     PolyHPtr     = ^PolygonHead;π     PolygonHead  = Recordπ                          X, Y, Z    : Integer;π                          AX, AY, AZ : Integer;π                          FirstFacet : FacetPtr;π                    End;πVar  VGAMEM   : VGAPtr;π     WorkPage : VGAPtr;π     BkgPage  : VGAPtr;π     Palette  : PalettePtr;π     PolyList : PolyFillPtr;π{-[ Initialize 320 X 200 X 256 VGA ]---------------------------------------}πProcedure GoMode13h; Assembler;πASMπ   MOV AX, $0013π   INT $10πEnd;π{=[ Convex Polygon Drawing Routines ]======================================}π{-[ Clear Polygon Raster List ]--------------------------------------------}πProcedure ClearPolyList (Var ListIn : PolyFill);πBeginπ     FillChar (ListIn, SizeOf(ListIn), $FF);πEnd;π{-[ OR VariableIn with Value -- Modeled after FillChar ]-------------------}πProcedure ORChar (Var VariableIn;π                      Size       : Word;π                      Value      : Byte); Assembler;πASMπ   PUSH DSπ   MOV CX, Sizeπ   OR  CX, CXπ   JZ  @Doneπ   LDS SI, VariableInπ   MOV AL, Valueπ   @ORLoop:π      OR DS:[SI], ALπ      INC SIπ   LOOP @ORLoopπ   @Done:π   POP DSπEnd;π{-[ Draw Polygon From Raster List To Work Buffer ]-------------------------}πProcedure DrawPolyFromList (Var ListIn      : PolyFill;π                            Var FrameBuffer : VGAArray;π                                Color       : Byte);πVar YCount : Word;π    TempX1 : Word;π    TempX2 : Word;πBeginπ     For YCount := 0 to 199 doπ     Beginπ          TempX1 := ListIn[YCount].X1;π          TempX2 := ListIn[YCount].X2;π          If (TempX1 <= 319) AND (TempX2 <= 319)π          Thenπ              ORChar (FrameBuffer[YCount, TempX1],π                      TempX2 - TempX1 + 1, Color);π     End;πEnd;π{-[ Add An Element To The Raster List ]------------------------------------}πProcedure AddRasterToPoly (Var ListIn : PolyFill;π                               X, Y   : Integer);πBeginπ     { Clip X }π     If X < 0π     Thenπ         X := 0π     Elseπ         If X > 319π         Thenπ             X := 319;π    { If Y in bounds, add to list }π    If ((Y >= 0) AND (Y <= 199))π    Thenπ    Beginπ         If (ListIn[Y].X1 > 319)π         Thenπ         Beginπ             ListIn[Y].X1 := X;π             ListIn[Y].X2 := X;π         Endπ         Elseπ             If (X < ListIn[Y].X1)π             Thenπ                 ListIn[Y].X1 := Xπ             Elseπ                 If (X > ListIn[Y].X2)π                 Thenπ                     ListIn[Y].X2 := X;π    End;πEnd;π{=[ Polygon ]==============================================================}π{-[ Add A Facet To Current Polygon ]---------------------------------------}πProcedure AddFacet (Polygon          : PolyHPtr;π                    Color            : Byte;π                    X1In, Y1In, Z1In : Integer;π                    X2In, Y2In, Z2In : Integer;π                    X3In, Y3In, Z3In : Integer;π                    X4In, Y4In, Z4In : Integer);πVar CurrentFacet : FacetPtr;πBeginπ     If Polygon^.FirstFacet = Nilπ     Thenπ     Beginπ          New(Polygon^.FirstFacet);π          CurrentFacet := Polygon^.FirstFacet;π     Endπ     Elseπ     Beginπ          CurrentFacet := Polygon^.FirstFacet;π          While CurrentFacet^.NextFacet <> Nil doπ                CurrentFacet := CurrentFacet^.NextFacet;π          New(CurrentFacet^.NextFacet);π          CurrentFacet := CurrentFacet^.NextFacet;π     End;π     CurrentFacet^.Color := Color;π     CurrentFacet^.X1 := X1In;π     CurrentFacet^.X2 := X2In;π     CurrentFacet^.X3 := X3In;π     CurrentFacet^.X4 := X4In;π     CurrentFacet^.Y1 := Y1In;π     CurrentFacet^.Y2 := Y2In;π     CurrentFacet^.Y3 := Y3In;π     CurrentFacet^.Y4 := Y4In;π     CurrentFacet^.Z1 := Z1In;π     CurrentFacet^.Z2 := Z2In;π     CurrentFacet^.Z3 := Z3In;π     CurrentFacet^.Z4 := Z4In;π     CurrentFacet^.NextFacet := Nil;πEnd;π{-[ Initialize a New Polygon ]---------------------------------------------}πProcedure InitializePolygon (Var PolyHead               : PolyHPtr;π                                 XIn, YIn, ZIn          : Integer;π                                 RollIn, PitchIn, YawIn : Integer);πBeginπ     If PolyHead = Nilπ     Thenπ     Beginπ          New(PolyHead);π          PolyHead^.X := XIn;π          PolyHead^.Y := YIn;π          PolyHead^.Z := ZIn;π          PolyHead^.AX := RollIn;π          PolyHead^.AY := PitchIn;π          PolyHead^.AZ := YawIn;π          PolyHead^.FirstFacet := Nil;π     End;πEnd;π{-[ Dispose Polygon ]------------------------------------------------------}πProcedure DisposePolygon (Var PolyHead : PolyHPtr);πVar TempPtr : FacetPtr;π    TP2     : FacetPtr;πBeginπ     TempPtr := PolyHead^.FirstFacet;π     While TempPtr <> Nil doπ     Beginπ          TP2 := TempPtr^.NextFacet;π          Dispose (TempPtr);π          TempPtr := TP2;π     End;π     Dispose (PolyHead);π     PolyHead := Nil;πEnd;π{-[ Rotate Polygon About Axies ]-------------------------------------------}πProcedure RotatePolygon (Var PolyHead   : PolyHPtr;π                             DX, DY, DZ : Integer);πBeginπ     INC (PolyHead^.AX, DX);π     INC (PolyHead^.AY, DY);π     INC (PolyHead^.AZ, DZ);π     While (PolyHead^.AX > 360) doπ           DEC(PolyHead^.AX, 360);π     While (PolyHead^.AY > 360) doπ           DEC(PolyHead^.AY, 360);π     While (PolyHead^.AZ > 360) doπ           DEC(PolyHead^.AZ, 360);π     While (PolyHead^.AX < -360) doπ           INC(PolyHead^.AX, 360);π     While (PolyHead^.AY < -360) doπ           INC(PolyHead^.AY, 360);π     While (PolyHead^.AZ < -360) doπ           INC(PolyHead^.AZ, 360);πEnd;π{=[ Graphics Related Routines ]============================================}π{-[ Build Facet Edge ]-----------------------------------------------------}πProcedure DrawLine (X1In, Y1In,π                    X2In, Y2In  : Integer;π                    Color       : Byte);πVar dx, dy : Integer;π    ix, iy : Integer;π    X,  Y  : Integer;π    PX, PY : Integer;π    i      : Integer;π    incc   : Integer;π    plot   : Boolean;πBeginπ     dx := X1In - X2In;π     dy := Y1In - Y2In;π     ix := abs(dx);π     iy := abs(dy);π     X  := 0;π     Y  := 0;π     PX := X1In;π     PY := Y1In;π     AddRasterToPoly (PolyList^, PX, PY);π     If ix > iyπ     Thenπ         incc := ixπ     Elseπ         incc := iy;π     i := 0;π     While (i <= incc) doπ     Beginπ          Inc (X, ix);π          Inc (Y, iy);π          Plot := False;π          If X > inccπ          Thenπ          Beginπ               Plot := True;π               Dec (X, incc);π               If dx < 0π               Thenπ                   Inc(PX)π               Elseπ                   Dec(PX);π          End;π          If Y > inccπ          Thenπ          Beginπ               Plot := True;π               Dec (Y, incc);π               If dy < 0π               Thenπ                   Inc(PY)π               Elseπ                   Dec(PY);π          End;π          If Plotπ          Thenπ              AddRasterToPoly (PolyList^, PX, PY);π          Inc(i);π     End;πEnd;π{-[ Draw Polygon ]---------------------------------------------------------}πProcedure DrawPolygon3D (PolyHead : PolyHPtr;π                         Buffer   : VGAPtr);πVar CurrentFacet               : FacetPtr;π    CalcX1, CalcY1, CalcZ1,π    CalcX2, CalcY2, CalcZ2,π    CalcX3, CalcY3, CalcZ3,π    CalcX4, CalcY4, CalcZ4     : Integer;π    XPrime1, YPrime1, ZPrime1,π    XPrime2, YPrime2, ZPrime2,π    XPrime3, YPrime3, ZPrime3,π    XPrime4, YPrime4, ZPrime4  : Integer;π    Temp                       : Integer;π    CTX, STX,π    CTY, STY,π    CTZ, STZ  : Real;πBeginπ     CurrentFacet := PolyHead^.FirstFacet;π     While CurrentFacet <> Nil doπ       With CurrentFacet^ doπ       Beginπ            ClearPolyList (PolyList^);π            XPrime1 := X1; YPrime1 := Y1; ZPrime1 := Z1;π            XPrime2 := X2; YPrime2 := Y2; ZPrime2 := Z2;π            XPrime3 := X3; YPrime3 := Y3; ZPrime3 := Z3;π            XPrime4 := X4; YPrime4 := Y4; ZPrime4 := Z4;π            { Rotate Coords }π            CTX := COS(PolyHead^.AX * PI / 180);π            STX := SIN(PolyHead^.AX * PI / 180);π            CTY := COS(PolyHead^.AY * PI / 180);π            STY := SIN(PolyHead^.AY * PI / 180);π            CTZ := COS(PolyHead^.AZ * PI / 180);π            STZ := SIN(PolyHead^.AZ * PI / 180);π            Temp    := Round((YPrime1 * CTX) - (ZPrime1 * STX));π            ZPrime1 := Round((YPrime1 * STX) + (ZPrime1 * CTX));π            YPrime1 := Temp;π            Temp    := Round((XPrime1 * CTY) - (ZPrime1 * STY));π            ZPrime1 := Round((XPrime1 * STY) + (ZPrime1 * CTY));π            XPrime1 := Temp;π            Temp    := Round((XPrime1 * CTZ) - (YPrime1 * STZ));π            YPrime1 := Round((XPrime1 * STZ) + (YPrime1 * CTZ));π            XPrime1 := Temp;π            Temp    := Round((YPrime2 * CTX) - (ZPrime2 * STX));π            ZPrime2 := Round((YPrime2 * STX) + (ZPrime2 * CTX));π            YPrime2 := Temp;π            Temp    := Round((XPrime2 * CTY) - (ZPrime2 * STY));π            ZPrime2 := Round((XPrime2 * STY) + (ZPrime2 * CTY));π            XPrime2 := Temp;π            Temp    := Round((XPrime2 * CTZ) - (YPrime2 * STZ));π            YPrime2 := Round((XPrime2 * STZ) + (YPrime2 * CTZ));π            XPrime2 := Temp;π            Temp    := Round((YPrime3 * CTX) - (ZPrime3 * STX));π            ZPrime3 := Round((YPrime3 * STX) + (ZPrime3 * CTX));π            YPrime3 := Temp;π            Temp    := Round((XPrime3 * CTY) - (ZPrime3 * STY));π            ZPrime3 := Round((XPrime3 * STY) + (ZPrime3 * CTY));π            XPrime3 := Temp;π            Temp    := Round((XPrime3 * CTZ) - (YPrime3 * STZ));π            YPrime3 := Round((XPrime3 * STZ) + (YPrime3 * CTZ));π            XPrime3 := Temp;π            Temp    := Round((YPrime4 * CTX) - (ZPrime4 * STX));π            ZPrime4 := Round((YPrime4 * STX) + (ZPrime4 * CTX));π            YPrime4 := Temp;π            Temp    := Round((XPrime4 * CTY) - (ZPrime4 * STY));π            ZPrime4 := Round((XPrime4 * STY) + (ZPrime4 * CTY));π            XPrime4 := Temp;π            Temp    := Round((XPrime4 * CTZ) - (YPrime4 * STZ));π            YPrime4 := Round((XPrime4 * STZ) + (YPrime4 * CTZ));π            XPrime4 := Temp;π            { Translate Coords }π            XPrime1 := PolyHead^.X + XPrime1;π            YPrime1 := PolyHead^.Y + YPrime1;π            ZPrime1 := PolyHead^.Z + ZPrime1;π            XPrime2 := PolyHead^.X + XPrime2;π            YPrime2 := PolyHead^.Y + YPrime2;π            ZPrime2 := PolyHead^.Z + ZPrime2;π            XPrime3 := PolyHead^.X + XPrime3;π            YPrime3 := PolyHead^.Y + YPrime3;π            ZPrime3 := PolyHead^.Z + ZPrime3;π            XPrime4 := PolyHead^.X + XPrime4;π            YPrime4 := PolyHead^.Y + YPrime4;π            ZPrime4 := PolyHead^.Z + ZPrime4;π            { Translate 3D Vectorspace to 2D Framespace }π            CalcX1 := 160 + ((LongInt(XPrime1)*ViewerDist) DIVπ                             (ZPrime1+ViewerDist));π            CalcY1 := 100 + ((LongInt(YPrime1)*ViewerDist) DIVπ                             (ZPrime1+ViewerDist));π            CalcX2 := 160 + ((LongInt(XPrime2)*ViewerDist) DIVπ                             (ZPrime2+ViewerDist));π            CalcY2 := 100 + ((LongInt(YPrime2)*ViewerDist) DIVπ                             (ZPrime2+ViewerDist));π            CalcX3 := 160 + ((LongInt(XPrime3)*ViewerDist) DIVπ                             (ZPrime3+ViewerDist));π            CalcY3 := 100 + ((LongInt(YPrime3)*ViewerDist) DIVπ                             (ZPrime3+ViewerDist));π            CalcX4 := 160 + ((LongInt(XPrime4)*ViewerDist) DIVπ                             (ZPrime4+ViewerDist));π            CalcY4 := 100 + ((LongInt(YPrime4)*ViewerDist) DIVπ                             (ZPrime4+ViewerDist));π            { Draw Shape }π            DrawLine (CalcX1, CalcY1, CalcX2, CalcY2, Color);π            DrawLine (CalcX2, CalcY2, CalcX3, CalcY3, Color);π            DrawLine (CalcX3, CalcY3, CalcX4, CalcY4, Color);π            DrawLine (CalcX4, CalcY4, CalcX1, CalcY1, Color);π            DrawPolyFromList (PolyList^, WorkPage^, Color);π            CurrentFacet := CurrentFacet^.NextFacet;π       End;πEnd;π{-[ Build Background ]-----------------------------------------------------}πProcedure BuildBackground (Var BufferIn : VGAArray);πVar CounterX,π    CounterY  : Integer;πBeginπ     For CounterY := 0 to 199 doπ      For CounterX := 0 to 319 doπ          BufferIn[CounterY, CounterX] := 1 + ((CounterY MOD 5) * 5) +π                                               (CounterX MOD 5);πEnd;π{-[ Build Palette ]--------------------------------------------------------}πProcedure BuildPalette (Var PaletteOut : PaletteType);πConst BC = 16;πVar Counter1,π    Counter2  : Integer;πBeginπ     FillChar (PaletteOut, SizeOf(PaletteOut), 0);π     For Counter1 := 0 to 4 doπ     For Counter2 := 1 to 2 doπ     Beginπ          PaletteOut[1+(Counter1 * 5)+Counter2].Red   := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+Counter2].Green := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+Counter2].Blue  := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Red   := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Green := BC+(Counter2 * 5);π          PaletteOut[1+(Counter1 * 5)+4-Counter2].Blue  := BC+(Counter2 * 5);π     End;π     For Counter1 := 0 to 4 doπ     Beginπ          If PaletteOut[1+(5 * 1)+Counter1].Red < BC + 5π          Thenπ          Beginπ              PaletteOut[1+(5 * 1)+Counter1].Red   := BC + 5;π              PaletteOut[1+(5 * 1)+Counter1].Green := BC + 5;π              PaletteOut[1+(5 * 1)+Counter1].Blue  := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Red   := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Green := BC + 5;π              PaletteOut[1+(5 * 3)+Counter1].Blue  := BC + 5;π          End;π          PaletteOut[1+(5 * 2)+Counter1].Red   := BC + 10;π          PaletteOut[1+(5 * 2)+Counter1].Green := BC + 10;π          PaletteOut[1+(5 * 2)+Counter1].Blue  := BC + 10;π     End;π     For Counter1 := 0 to 24 doπ     Beginπ      PaletteOut[32+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[32+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[32+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[64+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[64+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[64+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Red   := ((PaletteOut[Counter1].Red* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Green := ((PaletteOut[Counter1].Green* 8)+π                                        (0  * 24)) DIV 32;π      PaletteOut[128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 8)+π                                        (26 * 24)) DIV 32;π      PaletteOut[32+64+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+64+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+64+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[32+128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Red   := ((PaletteOut[Counter1].Red* 6)+π                                        (0  * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Green := ((PaletteOut[Counter1].Green* 6)+π                                        (23 * 26)) DIV 32;π      PaletteOut[64+128+Counter1].Blue  := ((PaletteOut[Counter1].Blue* 6)+π                                        (23 * 26)) DIV 32;π     End;πEnd;π{-[ Move Background by Moving Palette ]------------------------------------}πProcedure MoveBackground (Var PaletteIn : PaletteType);πVar TempPal : Array[0..5] of PaletteRec;πBeginπ     {-- Move Background Colors --}π     Move (PaletteIn[1], TempPal[0], 5 * 3);π     Move (PaletteIn[1+5], PaletteIn[1], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[1 + (5 * 4)], 5 * 3);π     {-- Move See-Through Colors --}π     { Red }π     Move (PaletteIn[32], TempPal[0], 6 * 3);π     Move (PaletteIn[32+5], PaletteIn[32], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[32 + (5 * 4)], 6 * 3);π     { Green }π     Move (PaletteIn[64], TempPal[0], 6 * 3);π     Move (PaletteIn[64+5], PaletteIn[64], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[64 + (5 * 4)], 6 * 3);π     { Blue }π     Move (PaletteIn[128], TempPal[0], 6 * 3);π     Move (PaletteIn[128+5], PaletteIn[128], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[128 + (5 * 4)], 6 * 3);π     { Red + Green }π     Move (PaletteIn[(32 OR 64)], TempPal[0], 6 * 3);π     Move (PaletteIn[(32 OR 64)+5], PaletteIn[(32 OR 64)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(32 OR 64) + (5 * 4)], 6 * 3);π     { Red + Blue }π     Move (PaletteIn[(32 OR 128)], TempPal[0], 6 * 3);π     Move (PaletteIn[(32 OR 128)+5], PaletteIn[(32 OR 128)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(32 OR 128) + (5 * 4)], 6 * 3);π     { Green + Blue }π     Move (PaletteIn[(64 OR 128)], TempPal[0], 6 * 3);π     Move (PaletteIn[(64 OR 128)+5], PaletteIn[(64 OR 128)], ((5 * 4) * 3));π     Move (TempPal[0], PaletteIn[(64 OR 128) + (5 * 4)], 6 * 3);πEnd;π{-[ Set Palette ]----------------------------------------------------------}πProcedure SetPalette (Var PaletteIn : PaletteType); Assembler;πASMπ   PUSH DSπ   LDS SI, PaletteIn { Sets whole palette at once...       }π   MOV CX, 256 * 3   {  *NOT* good practice since many VGA }π   MOV DX, 03DAh     {  cards will show snow at the top of }π   @WaitNotVSync:    {  of the screen.  It's done here     }π     IN  AL, DX      {  'cause the background animation    }π     AND AL, 8       {  requires large ammounts of the     }π   JNZ @WaitNotVSync {  palette to be updated every new    }π   @WaitVSync:       {  frame.                             }π     IN  AL, DXπ     AND AL, 8π   JZ @WaitVSyncπ   XOR AX, AXπ   MOV DX, 03C8hπ   OUT DX, ALπ   INC DXπ   @PaletteLoop:π     LODSBπ     OUT DX, ALπ   LOOP @PaletteLoopπ   POP DSπEnd;π{=[ Main Program ]=========================================================}πVar Polygon1 : PolyHPtr;πBeginπ     VGAMEM := Ptr($A000, $0000);π     New (WorkPage);π     New (BkgPage);π     New (Palette);π     New (PolyList);π     ClearPolyList (PolyList^);π     GoMode13h;π     BuildBackground (BkgPage^);π     BuildPalette    (Palette^);π     SetPalette (Palette^);π     Polygon1 := Nil;π     InitializePolygon (Polygon1,  { Polygon List Head         }π                        0, 0, 60,  { X, Y, Z of polygon        }π                        0, 0, 0);  { Iniitial Roll, Pitch, Yaw }π     AddFacet (Polygon1,       { Polygon List Head        }π                32,            { Color                    }π               -40, -40,  50,  { One Corner of Polygon    }π                40, -40,  50,  { Second Corner of Polygon }π                40,  40,  50,  { Third Corner of Polygon  }π               -40,  40,  50); { Last Corner of Polygon   }π     AddFacet (Polygon1,π                64,π               -50, -40, -40,π               -50, -40,  40,π               -50,  40,  40,π               -50,  40, -40);π     AddFacet (Polygon1,π               128,π                40, -50, -40,π                40, -50,  40,π               -40, -50,  40,π               -40, -50, -40);π     Repeatπ           { Clear Workpage }π           WorkPage^ := BkgPage^;π           ClearPolyList (PolyList^);π           DrawPolygon3D (Polygon1,    { Polygon Definition }π                          WorkPage);   { Work buffer        }π           MoveBackground (Palette^);π           SetPalette     (Palette^);π           { Display Work Buffer }π           VGAMEM^ := WorkPage^;π           RotatePolygon (Polygon1,π                          5, 10, 1);π     Until Keypressed;π     DisposePolygon (Polygon1);π     Dispose (PolyList);π     Dispose (Palette);π     Dispose (BkgPage);π     Dispose (WorkPage);π     TextMode (C80);πEnd.π                                                                                      130    08-24-9417:53ALL                      GARTH KRUMINS            GRAPHICS ROUTINES        SWAG9408    5    12     ╓   {here are some assembler routines for the 320x200x256 mode.}ππusesπ crt;ππPROCEDURE InitVGA; ASSEMBLER;πasmπ   mov  ax, 13hπ   int  10hπend;ππPROCEDURE InitTEXT; ASSEMBLER;πasmπ   mov  ax, 03hπ   int  10hπend;ππPROCEDURE PlotPixel1(X, Y: Word; Color: Byte); ASSEMBLER;πasmπ   push esπ   push diπ   mov  ax, Yπ   mov  bx, axπ   shl  ax, 8π   shl  bx, 6π   add  ax, bxπ   add  ax, Xπ   mov  di, axπ   mov  ax, $A000π   mov  es, axπ   mov  al, Colorπ   mov  es:[di], alπ   pop  diπ   pop  esπend;ππPROCEDURE PlotPixel2(X, Y : word; Color : byte);πbeginπ if (X<320) then if (Y<200) then mem[$A000: Y*320+X] := color;πend;πππPROCEDURE SetColor (ColorNo, Red, Green, Blue : byte);πbeginπ     PORT[$3C8] := ColorNo;π     PORT[$3C9] := Red;π     PORT[$3C9] := Green;π     PORT[$3C9] := Blue;πend;πππvarπ LoopX : word;π LoopY, R, G, B, i : byte;π Ky : char;ππBeginπ Randomize;π InitVGA;π for LoopY := 0 to 199 doπ beginπ  for LoopX := 0 to 319 doπ   PlotPixel1(LoopX, LoopY, random(255)+1);π end;π B := 0;π repeatπ  G := random(63);π  for R := 0 to 63 doπ  beginπ   Setcolor(random(255)+1, R, G, B);π   inc(G, 1);π   if G=64 then G := 0;π  end;π  for G := 63 downto 0 doπ  R := random(63);π  beginπ   Setcolor(random(255)+1, R, G, B);π   dec(R, 1);π   if R=0 then R := 63;π  end;π  inc(B, random(10)-5);π  if B>63 then B := random(63);π until keypressed;π Ky := readkey;π InitTEXT;πend.πππ                            131    08-24-9417:54ALL                      RICH VERAA               Save/Restore Graphics    SWAG9408    =Σ3    11     ╓   ππProcedure GetImage (X1,Y1,X2,Y2:Integer;P:Pointer); assembler;πasmπ    mov  bx,320π    push dsπ    les  di,Pππ    mov  ax,0A000hπ    mov  ds,axπ    mov  ax,Y1π    mov  dx,320π    mul  dxπ    add  ax,X1π    mov  si,axππ    mov  ax,X2π    sub  ax,X1π    inc  axπ    mov  dx,axπ    stoswππ    mov  ax,Y2π    sub  ax,Y1π    inc  axπ    stoswπ    mov  cx,axππ  @@1:π    mov  cx,dxππ    shr  cx,1π    cldπ    rep  movswππ    test dx,1π    jz         @@2π    movsbπ  @@2:π    add  si,bxπ    sub  si,dxππ    dec  axπ    jnz  @@1ππ    pop  dsπend;ππProcedure PutImage (X1,Y1:Integer;P:Pointer); assembler;πasmπ    mov  bx,320π    push dsπ    lds  si,Pππ    mov  ax,0A000hπ    mov  es,axπ    mov  ax,Y1π    mov  dx,320π    mul  dxπ    add  ax,X1π    mov  di,axππ    lodswπ    mov  dx,axππ    lodswππ  @@1:π    mov  cx,dxππ    shr  cx,1π    cldπ    rep  movswππ    test dx,1π    jz         @@2π    movsbπ  @@2:π    add  di,bxπ    sub  di,dxππ    dec  axπ    jnz  @@1ππ    pop  dsπend;ππProcedure Init;πbeginπ  GetMem (Buf1,64000);π  GetMem(Buf2,64000);πend;ππbeginπ  init;π  dographicstuff;ππ  GetImage( 0,0,319,199,Buf1);  {store page 1}ππ  domoregraphicstuff;ππ  GetImage( 0,0,319,199,Buf2);  {store page 2}ππ  PutImage (0,0, Buf1);  {restore page 1}ππend.π                              132    08-24-9417:55ALL                      LUIS MEZQUITA            X3dunit                  SWAG9408    w¼è    78     ╓   unit x3dunit2;ππ{ mode-x 3D unit - xhlin-procedure by Sean Palmer }π{ Optimized by Luis Mezquita Raya                 }ππ{$g+}ππinterfaceππconst vidseg:word=$a000;π      divd:word=128;π      dist:word=200;π      minx:word=0;π      maxx:word=319;π      border:boolean=false;ππvar   ctab:array[byte] of integer;π      stab:array[byte] of integer;π      address:word;π      triangles:boolean;ππProcedure setborder(col:byte);πProcedure setpal(c,r,g,b:byte);πProcedure retrace;πProcedure setmodex;πProcedure setaddress(ad:word);πProcedure cls;πProcedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte);πFunction  cosinus(i:byte):integer;πFunction  sinus(i:byte):integer;ππimplementationππvar   xpos:array[0..199,0..1] of integer;ππProcedure setborder(col:byte); assembler;πasmπ        xor ch,chπ        mov cl,borderπ        jcxz @outπ        mov dx,3dahπ        in al,dxπ        mov dx,3c0hπ        mov al,11h+32π        out dx,alπ        mov al,colπ        out dx,alπ@out:πend;ππProcedure setpal(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;ππProcedure retrace; assembler;πasmπ        mov dx,3dah;π@vert1: in al,dxπ        test al,8π        jz @vert1π@vert2: in al,dxπ        test al,8π        jnz @vert2πend;ππProcedure setmodex; assembler;πasmπ        mov ax,13hπ        int 10hπ        mov dx,3c4hπ        mov ax,0604hπ        out dx,axπ        mov ax,0f02hπ        out dx,axπ        mov cx,320*200π        mov es,vidsegπ        xor ax,axπ        mov di,axπ        rep stoswπ        mov dx,3d4hπ        mov ax,0014hπ        out dx,axπ        mov ax,0e317hπ        out dx,axπend;ππProcedure setaddress(ad:word); assembler;πasmπ        mov dx,3d4hπ        mov al,0chπ        mov ah,[byte(ad)+1]π        out dx,axπ        mov al,0dhπ        mov ah,[byte(ad)]π        out dx,axπend;ππProcedure cls; assembler;πasmπ        mov es,vidsegπ        mov di,addressπ        mov cx,8000π        mov dx,3c4hπ        mov ax,0f02hπ        out dx,axπ        xor ax,axπ        rep stoswπend;ππ{$f-}ππProcedure polygon(x1,y1,x2,y2,x3,y3,x4,y4:integer; c:byte); assembler;πvar mny,mxy,y,m,mult,divi,top,s,π    stb,px1,py1,px2,py2:integer;π    dir:byte;πasm                                     { Procedure Polygon }π        mov ax,y1                       { Determine lowest & highest points }π        mov cx,axπ        mov bx,y2ππ        cmp ax,bx                       { if mny>y2 ==> mny:=y2 }π        jl @p2π        mov ax,bxππ@p2:    cmp cx,bx                       { if mxy<y2 ==> mxy:=y2 }π        jg @p3π        mov cx,bxππ@p3:    mov bx,y3π        cmp ax,bx                       { if mny>y3 ==> mny:=y3 }π        jl @p3Mπ        mov ax,bxππ@p3M:   cmp cx,bx                       { if mxy<y3 ==> mxy:=y3 }π        jg @p4π        mov cx,bxππ@p4:    mov bx,y4π        cmp ax,bx                       { if mny>y4 ==> mny:=y4 }π        jl @p4Mπ        mov ax,bxππ@p4M:   cmp cx,bx                       { if mxy<y4 ==> mxy:=y4 }π        jg @vertπ        mov cx,bxππ@vert:  cmp ax,0                        { Vertical range checking }π        jge @minin                      { if mny<0 ==> mny:=0 }π        xor ax,axπ@minin: cmp cx,200                      { if mxy>199 ==> mxy:=199 }π        jl @maxinπ        mov cx,199π@maxin: cmp cx,0                        { if mxy<0 ==> Exit }π        jl @pexitπ        cmp ax,199                      { if mny>199 ==> Exit }π        jg @pexitππ        mov mny,ax                      { ax=mny=lowest point }π        mov mxy,cx                      { cx=mxy=highest point }ππ        push x1                         { RangeChk(x1,y1,x2,y2) }π        push y1π        push x2π        push y2π        call @Rangeππ        push x2                         { RangeChk(x2,y2,x3,y3) }π        push y2π        push x3π        push y3π        call @Rangeππ        push x3                         { RangeChk(x3,y3,x4,y4) }π        push y3π        cmp Triangles,0π        jz @Poly4π        push x1π        push y1π        jmp @Lastππ@Poly4: push x4π        push y4π        call @Rangeππ        push x4                         { RangeChk(x4,y4,x1,y1) }π        push y4π        push x1π        push y1π@Last:  call @Rangeππ        mov ax,mny                      { Show a poly }π        mov di,ax                       { y:=mny }π        shl di,2π        lea bx,xposπ        add di,bx                       { di points to xpos[y,0] }π@Show:  mov y,ax                        { repeat ... }π        mov cx,[di]π        mov dx,[di+2]π        mov px1,cxπ        mov px2,dxπ        push axπ        push diπ        call @xhlin                     { xhlin(px1,px2,y,c) }π        pop diπ        pop axπ        add di,4                        { Next xpos }π        inc ax                          { inc(y) }π        cmp ax,mxy                      { ... until y>mxy; }π        jle @Showπ        jmp @pexitππ{ RangeChk }ππ@Range: pop di                          { Get return IP }π        pop py2                         { Get params }π        pop px2π        pop py1π        pop px1π        push di                         { Save return IP }ππ        mov ax,py1                      { dir:=byte(y1<y2) }π        cmp ax,py2π        mov ax,1π        jl @Rdwnπ        dec alπ@Rdwn:  mov dir,alππ        shl al,1π        push axπ        shl al,2π        sub ax,4π        mov stb,ax                      { stb:=8*dir-4 }π        pop axπ        dec ax                          { s:=2*dir-1 }π        mov s,ax                        { Check directions (-1= down, 1=up) }ππ        test AH,10000000b               { Calculate constants }π        mov dx,0π        jz @Rposiπ        dec dxπ@Rposi: mov bx,px2π        sub bx,px1π        imul bxπ        mov mult,ax                     { mult:=s*(x2-x1) }π        mov ax,py2π        mov bx,py1π        mov cx,axπ        sub ax,bxπ        mov divi,ax                     { divi:=y2-y1 }ππ        cmp bx,cx                       { ¿y1=y2? }ππ        pushf                           { Calculate pointer to xpos[y,dir] }π        mov y,bx                        { y:=y1 }π        mov di,bxπ        shl di,2π        lea bx,xposπ        add di,bxπ        mov cl,dirπ        mov ch,0π        shl cl,1π        add di,cx                       { di points to xpos[y,dir] }π        popfππ        je @Requ                        { if y1=y2 ==> @Requ }ππ        mov m,0                         { m:=0 }π        mov ax,py2π        add ax,sπ        mov top,ax                      { top:=y2+s }ππ@RLoop: mov ax,y                        { repeat ... }π        cmp ax,mny                      { if y<mny ==> @RNext }π        jl @RNextπ        cmp ax,mxy                      { if y>mxy ==> @RNext }π        jg @RNextππ        mov ax,m                        { Calculate int(m/divi)+x1 }π        test AH,10000000bπ        mov dx,0π        jz @RLposπ        dec dxπ@RLpos: mov bx,diviπ        idiv bxπ        add ax,px1π        call @HR                        { HorRangeChk(m div divi+x1) }ππ@RNext: mov ax,multπ        add m,ax                        { inc(m,mult) }π        add di,stb                      { Next xpos }π        mov ax,y                        { inc(y,s) }π        add ax,sπ        mov y,axπ        cmp ax,topπ        jne @RLoop                      { ... until y=top }π        jmp @Rexitππ@Requ:  mov ax,yπ        cmp ax,mny                      { if y<mny ==> Exit }π        jl @Rexitπ        cmp ax,mxy                      { if y>mxy ==> Exit }π        jg @Rexitπ        mov ax,px1π        call @HR                        { HorRangeChk(px1) }π@Rexit: jmp @exitππ{ HorRangeChk }ππ@HR:    mov bx,minx                     { bx:=minx }π        cmp ax,bxπ        jl @HRsavπ        mov bx,maxx                     { bx:=maxx }π        cmp ax,bxπ        jg @HRsavπ        mov bx,axπ@HRsav: mov [di],bx                     { xpos[y,dir]:=bx }π        jmp @exitπ{ xhlin }ππ@xhlin: mov es,vidsegπ        cldπ        mov ax,80π        mul yπ        mov di,ax                       { base of scan line }π        add di,addressππ        mov bx,px1                      { px1 = x begin coord }π        mov dx,px2                      { px2 = x end coord }π        cmp bx,dxπ        jb @skipπ        xchg bx,dx                      { switch coords if px1>px2 }ππ@skip:  mov cl,blπ        shr bx,2π        mov ch,dlπ        shr dx,2π        and cx,$0303π        sub dx,bx                       { width in Bytes }π        add di,bx                       { offset into video buffer }π        mov ax,$ff02π        shl ah,clπ        and ah,1111b                    { left edge mask }π        mov cl,chπ        mov bh,$f1π        rol bh,clπ        and bh,1111b                    { right edge mask }π        mov cx,dxπ        or cx,cxπ        jnz @leftπ        and ah,bh                       { combine left & right bitmasks }ππ@left:  mov dx,$03c4π        out dx,axπ        inc dxπ        mov al,cπ        stosbπ        jcxz @exitπ        dec cxπ        jcxz @rightπ        mov al,1111bπ        out dx,al                       { skipped if cx=0,1 }π        mov al,cπ        repz stosb                      { fill middle Bytes }ππ@right: mov al,bhπ        out dx,al                       { skipped if cx=0 }π        mov al,cπ        stosbππ@exit:  pop axπ        push csπ        push axπ        retπ@pexit:πend;ππ{$f+}ππFunction cosinus(i:byte):integer;πbeginπ cosinus:=ctab[i];πend;ππFunction sinus(i:byte):integer;πbeginπ sinus:=stab[i];πend;ππProcedure Initialize;πvar i:byte;πbeginπ triangles:=False;π for i:=0 to 255 do ctab[i]:=round(-cos(i*pi/128)*divd);π for i:=0 to 255 do stab[i]:=round(sin(i*pi/128)*divd);πend;ππbeginπ Initialize;πend.π                                                                                                                      133    08-24-9417:56ALL                      ANDREW GOLOVIN           X-mode Write Mode ExampleSWAG9408    äΦ¼ù    31     ╓   π{ Illustration on how VGA Write Mode 1 works }π{ by Andrew Golovin (2:5080/10@Fidonet)      }π{ Can be used at your own risk freely w/o    }π{ any charge                                 }π{============================================}π{ PREFACE:                                   }π{ This example illustrate posibility to save }π{ Bitmaps in unused VRam. And use VWM1 to    }π{ restore it by 4 pixels at one byte         }π{ Use arrows to move "bitmap" on screen.     }π{ This example _only_ illustrate this mode   }π{ Extremly needs optimization! Don't use it  }π{ as is. Just an idea.                       }ππUses CRT;πvarπ  OldMode: Byte;ππprocedure SetWriteMode(Wmode: Byte); assembler;πasmπ  Mov     DX,3cehπ  Mov     AL,5π  Out     DX,ALπ  Inc     DXπ  In      AL,DXπ  And     AL,11111100bπ  Or      AL,WModeπ  Out     DX,ALπend;ππprocedure Init320x200_X; assembler;πasmπ  Mov AH,0fh; Int 10h; Mov [OldMode],al; Mov AX,13h; Int 10h;π  Mov DX,3c4h; Mov AL,04h; Out DX,AL; Inc DX; In AL,DX; And AL,011110111b;π  Or AL,000000100b; Out DX,AL; Dec DX; Mov AX,0f02h; Out DX,AX;π  Mov AX,0a000h; Mov ES,AX; XOr DI,DI; Mov AX,0202h; Mov CX,8000h;π  ClD; RepNZ StoSW; Mov DX,3d4h; Mov AL,14h; Out DX,AL; Inc DX;π  In AL,DX; And AL,010111111b; Out DX,AL; Dec DX; Mov AL,017h;π  Out DX,AL; Inc DX; In AL,DX; Or AL,01000000b; Out DX,AL; Mov DX,3d4h;π  Mov AX,80; ShR AX,1; Mov AH,AL; Mov AL,13h; Out DX,AX; Retπend;ππProcedure PutPixel(x,y: Word; c: Byte);π  beginπ    asmπ      Mov    DX,3c4hπ      Mov    AL,02π      Out    DX,ALπ      Mov    AX,Yπ      ShL    AX,4π      Mov    DI,AXπ      ShL    AX,2π      Add    DI,AXπ      Mov    AX,Xπ      ShR    AX,2π      Add    DI,AXπ      Mov    AX,Xπ      And    AX,3π      Mov    CL,ALπ      Mov    AL,1π      ShL    AL,CLπ      Inc    DXπ      Out    DX,ALπ      Mov    AX,0a000hπ      Mov    ES,AXπ      Mov    AL,Cπ      StoSBπ    end;π  end;ππprocedure MaskBits(BitsToMask: Byte); assembler;π  asmπ    Mov     DX,3cehπ    Mov     AL,8π    Mov     AH,BitsToMaskπ    Out     DX,AXπ  end;ππProcedure MaskPlanes(PlaneToMask: Byte); assembler;πasmπ  Mov     DX,3c4hπ  Mov     AL,2π  Out     DX,ALπ  Inc     DXπ  Mov     AL,PlaneToMaskπ  Out     DX,ALπEnd;ππProcedure StoreBack(x,y,w,h: word; toAddr: word);π  varπ    curx,cury: Word;π  beginπ    SetWriteMode(1);π    MaskPlanes($f);π    MaskBits($ff);π    For CurY:=Y to Y+H doπ      Move(Mem[$a000:CurY*80+x],Mem[$a000:toAddr+(CurY-Y)*W],w);π    SetWriteMode(0);π  end;ππProcedure RestoreBack(x,y,w,h: word; fromAddr: Word);π  varπ    cury,curx: Word;π  beginπ    SetWriteMode(1);π    MaskPlanes($f);π    MaskBits($ff);π    For CurY:=Y to Y+H doπ      Move(Mem[$a000:fromAddr+(CurY-Y)*W],Mem[$a000:CurY*80+x],w);π    SetWriteMode(0);π  end;ππvarπ  x,y: Word;π  curx,cury: Word;π  c: Char;πBeginπ  Init320x200_x;π  For x:=0 to 319 doπ    For y:=0 to 199 doπ      PutPixel(x,y,(x +y) mod 16+16);π  StoreBack(0,0,3,12,16000);π  For x:=0 to 11 doπ    For y:=0 to 11 doπ      PutPixel(x,y,Random(255));π  StoreBack(0,0,3,12,16200);π  CurX:=0;CurY:=0;π  Repeatπ    Repeat Until KeyPressed;π    c:=ReadKey;π    If c=#0π       thenπ         beginπ           RestoreBack(CurX,CurY,3,12,16000);π           c:=ReadKey;π           Case c ofπ             #80: If CurY<187π                     thenπ                       Inc(CurY);π             #72: If CurY>0π                     Thenπ                       Dec(CurY);π             #75: If CurX>0π                     Thenπ                       Dec(CurX);π             #77: If CurX<77π                     Thenπ                       Inc(CurX);π           end;π           StoreBack(CurX,CurY,3,12,16000);π           RestoreBack(CurX,CurY,3,12,16200);π         end;π  Until c=#27;π  asm Mov al,OldMode; XOr AH,AH; Int 10h end;πEnd.ππ                                                                           134    08-25-9409:07ALL                      KIMMO K K FREDRIKSSON    Fastest Putpixel?        SWAG9408    Ö║3    22     ╓   (*πFrom: kfredrik@cc.Helsinki.FI (Kimmo K K Fredriksson)ππ:  > This routine, from off the net somewhere, is a little fasterπ:  > than simply writing to MEM (it replaces the multiply by aπ:  > shift).π: Wilbert van Leijen and I once wrote a similar thing like this as an InLineπ: macro, which turned out to be the true fastest code (ok, never say...)ππ: Procedure PutPixel18(c: Byte; x,y: Integer);π: Inline(π:   $B8/$00/$A0/      {  mov   AX,$A000   }π:   $8E/$C0/          {  mov   ES,AX      }π:   $5B/              {  pop   BX         }π:   $88/$DC/          {  mov   AH,BL      }π:   $5F/              {  pop   DI         }π:   $01/$C7/          {  add   DI,AX      }π:  {$IFOPT G+}π:   $C1/$E8/$02/      {  shr   AX,2       }π:  {$ELSE}π:   $D1/$E8/          {  shr   AX,1       }π:   $D1/$E8/          {  shr   AX,1       }π:  {$ENDIF}π:   $01/$C7/          {  add   DI,AX      }π:   $58/              {  pop   AX         }π:   $AA);             {  stosb            }ππ: I'd be real interested in seeing a PutPixel (remember: one pixel only, not aπ: line, that's another story) that is faster than this one...ππThis is fast indeed, but the last instruction should be replaced atπleast in 486 and Pentium CPUs with instruction mov es:[di],al, whichπis faster than stosb (and you may also want to re-arrange them).ππAlso, the shift and add sequence could be replaced by table look-up,πbut that wouldn't be so elegant, only faster. So if you wanna stickπwith arithmetic address calculation, you could use 32-bit instructions,πsomething like this:ππ mov es,[SegA000]π pop diπ pop bxπ pop axπ shl di,6π lea edi,[edi*4+edi]π mov es:[edi+ebx],alπ πIf I use 32-bit instructions, I usually zero data registers in theπinitialization part of my program, so I can use those registersπin the situations like above without the need to every time zeroπthe high bits.ππYou may also use fs or gs register instead of es, because you mayπalways keep it pointing to video RAM, instead of loading it everyπtime you do PutPixel.ππThis may go beyond the topic, but what the heck: usually I try toπuse the offset of the screen mem as the parameter of these kind ofπprocedures, because it removes the need of address calculation:π*)πPROCEDURE PutPixel( offset : Word; c : Byte );π  INLINE(π pop axπ pop diπ mov fs,[di],alπ);π(*πIt is still very easy to use the offset instead of the (x,y)πposition, if you want the next x-pix, add one to offset, ifπyou want the next y-pix, add 320 to offset.ππSorry, but I was too lazy to calc the hex values :-(ππAnd never say that you have the absolutely fastest code ;-)π*)π                                                                                                135    08-25-9409:08ALL                      YUAN LIU                 Virtual world plotting   SWAG9408    -G    38     ╓   {πFrom: yliu@morgan.ucs.mun.ca (Yuan Liu)ππ: I have a question for drawing a graphic.  I have a set of data.π: I want to read these data and plot them in the XY axes.  Does anyoneπ: know how to caculate the data to fit the X axis.  I am using TP 7.0.ππWhen converting from HP Pascal, which provides a nice subset of theπdevice-independent graphics kernal and allows plotting in the virtual worldπ(so the window and viewport can be set in the virtual world), I wroteπseveral procedures to simulate virtual world plotting.  The following isπpart of a unit Plotbase I created.ππThe function you needed is set_window; the boolean pagefit controlsπwhether you just want your plot to fit in the whole window or there's a concernπabout the isotropy of the plot.  I didn't bother to write a virtualπworld set_viewport as I can live without it.ππ}πUNIT PLOTBASE; {******************* Stored in 'PLOTBASE' ******************}π{*     Basic procedures for graphical manipulations.                      *}π{*     Created in 1983.  Updated 17/05/94 10:00 a.m.       By LIU Yuan    *}π{**************************************************************************}πinterface USES Graph;πprocedure set_window(left, right, up, down: extended; pagefit: boolean);π         {Sets a mapping of virtual window on the current viewport;π           use isotropic scaling if not pagefit.}πfunction vToX(x: extended): integer;πfunction vToY(y: extended): integer;π         {Map x, y in the virtual world onto real world}πfunction XtoV(X: integer): extended;πfunction YtoV(Y: integer): extended;π         {Maps X, Y in the real world onto virtual world}π           use isotropic scaling if not pagefit.πprocedure vMove(x, y: extended);π          {Moves the current position to (x,y) in the virtual world}πprocedure vMoveRel(Dx, Dy: extended);π{Moves the current position a relative distance in the virtual world}πprocedure vLine(x1, y1, x2, y2: extended);π          {Draws a line from (x1,y1) to (x2,y2) in the virtual world}πprocedure vLineTo(x, y: extended);π          {Draws a line from current position to (x,y) in the virtual world}πfunction str_width(str: string): extended; {string width in the virtual world}πfunction str_height(str: string): extended; {string height in the virtualπworld}πimplementation {************************** PLOTBASE *************************}π        var Text:         string[20];π            xasp, yasp, xbase, ybase: extended;π            {convert from virtual world to display}ππprocedure set_window(left, right, up, down: extended; pagefit: boolean);π         {Sets a mapping of virtual window on the current viewport;π           use isotropic scaling if not pagefit.π           Side effects: xasp, yasp, xbase, ybase.}πvar view: ViewPortType;πbegin xbase:=left; ybase:=down; right:=right-left; up:=up-down;π      GetViewSettings(view);π      right:=(view.x2-view.x1)/right;π      up:=(view.y2-view.y1)/up;π      if pagefit then begin xasp:=right; yasp:=up endπ      else if right<up then begin yasp:=right; xasp:=right; endπ                       else begin xasp:=up; yasp:=up endπend; {set_window}ππfunction vToX(x: extended): integer;begin vToX:=round((x-xbase)*xasp) end;π         {Maps x in the virtual world onto real world}πfunction vToY(y: extended): integer;begin vToY:=round((y-ybase)*yasp) end;π         {Maps x in the virtual world onto real world}ππfunction XtoV(X: integer): extended; begin XtoV:=X/xasp+xbase end; {XtoV}π         {Maps X in the real world onto virtual world}πfunction YtoV(Y: integer): extended; begin YtoV:=Y/yasp+ybase end; {YtoV}π         {Maps Y in the real world onto virtual world}ππprocedure vMove(x, y: extended);π          {Moves the current position to (x,y) in the virtual world}πbegin MoveTo(round((x-xbase)*xasp),round((y-ybase)*yasp)) end; {vMove}πprocedure vMoveRel(Dx, Dy: extended);π{Moves the current position a relative distance in the virtual world}πbegin MoveRel(round(Dx*xasp),round(Dy*yasp)) end; {vMoveRel}ππprocedure vLine(x1, y1, x2, y2: extended);π          {Draws a line from (x1,y1) to (x2,y2) in the virtual world}πbegin line(round((x1-xbase)*xasp),round((y1-ybase)*yasp),π           round((x2-xbase)*xasp),round((y2-ybase)*yasp)) end; {vLine}ππprocedure vLineTo(x, y: extended);π          {Draws a line from current position to (x,y) in the virtual world}πbegin LineTo(round((x-xbase)*xasp),round((y-ybase)*yasp)) end; {vLineTo}ππfunction str_width(str: string): extended; {string width in the virtual world}πbegin str_width:=TextWidth(str)/xasp end; {str_width}ππfunction str_height(str: string): extended; {string height in the virtualπworld}πbegin str_height:=TextHeight(str)/yasp end; {str_height}π                                                                136    08-25-9409:11ALL                      MIKE CHURCH              Stars AGAIN!!!!          SWAG9408    ëcè╛    31     ╓   {πOk...  Here goes.  You will have to figure out how to TSR this if youπwant...  But you can navigate in this one too!  TP v6.0π}ππprogram stars;π{$R-}π{$S-}    {dangerous, but it's pretty well debugged}π{$G+}πuses crt;πconst MaxStars=1000;         { OK for 486-33. Decrease for slower computers}π      xltsin:integer=0;π      xltcos:integer=round((1-(640/32767)*(640/32767))*32767);π      yltsin:integer=0;π      yltcos:integer=round((1-(640/32767)*(640/32767))*32767);π      zltsin:integer=0;π      zltcos:integer=round((1-(640/32767)*(640/32767))*32767);π                {rotation parameters, 16-bit.}π      speed:word=264;    {speed of movement thru starfield}πconst XWIDTH = 320;  { basic screen size stuff used for star animation.}πconst YWIDTH = 200;πconst XCENTER = ( XWIDTH div 2 );πconst YCENTER = ( YWIDTH div 2 );πtype STARtype=recordπ                x,y,z:integer; {The x, y and z coordinates}π                xz,yz:integer; { screen coords}π              end;πvar star:array[1..maxstars] of startype;π    i:integer;π    ch:char;π    rotx,roty,rotz:boolean;π    rotxv,rotyv,rotzv:integer;πprocedure setmode13;    {sets 320*200 256-colour mode}πassembler;πasmπ  mov ax,13hπ  int 10hπend;πprocedure settextmode;   {returns to text mode}πassembler;πasmπ  mov ax,03hπ  int 10hπend;πprocedure setpix(x,y:integer;c:byte);  {NO BOUNDARY CHECKING!}πbegin   {Sets a pixel in mode 13h}πasmπ  mov ax,0a000hπ  mov es,axπ  mov ax,yπ  mov bx,320π  mul bxπ  mov di,xπ  add di,axπ  mov al,cπ  mov es:[di],alπend;πend;πprocedure initstar(i:integer);  {initialise stars at random positions}πbeginπ  with star[i] doπ  beginπ    x := longint(-32767)+random(65535);π    y := longint(-32767)+random(65535);             {at rear}π    z := random(16000)+256;π    xz:=xcenter;π    yz:=ycenter;π  end;πend;πprocedure newstar(i:integer);   {create new star at either front or}πbegin                            {rear of starfield}π  with star[i] doπ  beginπ    x := longint(-32767)+random(65535);π    y := longint(-32767)+random(65535);π    if z<256 then z := random(1256)+14500     {kludgy, huh?}π      else z:=random(256)+256;π    xz:=xcenter;π    yz:=ycenter;π  end;πend;ππ{$L update.obj}πprocedure update(var star:startype;i:integer);external;πππππbeginπ   {gets ~100 frames/sec on a 486-33 with 500 stars,π       rotating on 1 axis, speed 256}π  clrscr;π  checkbreak:=false;                      { for speed?}π  randomize;π  for i:=1 to maxstars do initstar(i);    {initialise stars}π  setmode13;π  rotx:=true;roty:=true;rotz:=true;π  ch:=' ';π  repeatπ    for i:=1 to maxstars do update(star[i],i);  {update star positions}π    if keypressed thenπ    beginπ      ch:=readkey;                       { change parameters according to }π      if ch='+' then speed:=speed+32;    {  key pressed}π      if ch='-' then speed:=speed-32;π      if ch=#13 thenπ         beginπ              xltsin:=0;π              yltsin:=0;π              zltsin:=0;π              speed:=256;π         end;π      if ch=#80 then dec(xltsin,96);π      if ch=#72 then inc(xltsin,96);π      if ch=#77 then dec(yltsin,96);π      if ch=#75 then inc(yltsin,96);π      if ch=#81 thenπ         beginπ              dec(yltsin,96);π              if xltsin<0 then inc(zltsin,96);π              if xltsin>0 then dec(zltsin,96);π         end;π      if ch=#79 thenπ         beginπ              inc(yltsin,96);π              if xltsin<0 then dec(zltsin,96);π              if xltsin>0 then inc(zltsin,96);π         end;π      if ch=#71 then dec(zltsin,96);π      if ch=#73 then inc(zltsin,96);π      end;π    xltcos:=round((1-sqr(xltsin/32767))*32767);π    yltcos:=round((1-sqr(yltsin/32767))*32767);    { evaluate cos values}π    zltcos:=round((1-sqr(zltsin/32767))*32767);π  until ch=#27;       {hit ESC to exit}π  settextmode;π  writeln;πend.π                                                137    08-25-9409:11ALL                      BOB SCHOR                Storing 3D Graphics      SWAG9408    ╖Me∞    27     ╓   {πFrom: Bschor@vms.cis.pitt.eduππ> Now the problem. "Seek(F, I)" will only take ONE integer at a time!!π> Naturally I need two. I'm trying to run it so that at each virtualπ> "square" a user can define a different message, monster, etc. And theπ> file i'm writing to must be able to define between X & Y, [(1,2) forπ> example], or both of them togeter [E.G. Two steps to the right, two stepsπ> forward = (2,2)]. HOW DO I DO THIS???ππIf I understand the question correctly, you are asking how to map aπtwo-dimensional structure (a 2-D map of your world) into a 1-dimensionalπdata structure (a file).  Ah, my ancient Fortran knowledge does come inπuseful ...ππThe following works for arrays of any dimension, though you need toπhave the array size fixed.  Suppose you have dimensioned World into R rows,πC columns, and L layers (I'm doing 3-D, just to show how it can be done).πTo make it all very clear, I'll define the world as either a 3-D or linearπstructure, using the Pascal Variant Record type.π}ππCONSTπ rows = 30;π columns = 40;π layers = 5;π rooms = 6000; { rows * columns * layers }πTYPEπ rowtype = 1 .. rows;π columntype = 1 .. columns;π layertype = 1 .. layers;π roomnumbertype = 1 .. rooms;π roomtype = RECORDπ { you define as needed }π END;π worldtype = RECORDπ CASE (d3, d1) ofπ d3 : (spatial: ARRAY [layertype, rowtype, columntype] OF roomtype);π d1 : (linear : ARRAY [roomnumbertype] OF roomtype);π END;π{π     Basically, you determine an order you wish to store the data.  Supposeπyou say "Start with the first layer, the first row, the first column.πMarch across the columns, then move down a row and repeat across theπcolumns; when you finish a layer, move down to the next layer and repeat".ππ     Clearly Layer 1, Row 1, Column C maps to Room C.  Since each row hasπ"columns" columns, then the mapping of Layer 1, Row R, Column C is toπRoom (R-1)*columns + C.  The full mapping is --π}π  FUNCTION roomnumber (layer : layertype; row : rowtype;π   column : columntype) : roomnumbertype;ππ  BEGIN   { roomnumber }π   roomnumber := column + pred(row)*columns + pred(layer)*columns*rowsπ  END;ππ{     Note you can also map in the other direction:}ππ  FUNCTION layer (roomnumber : roomnumbertype) : layertype;ππ  BEGIN   { layer }π   layer := succ (pred(roomnumber) DIV (columns * rows))π  END;ππ  FUNCTION row (roomnumber : roomnumbertype) : rowtype;ππ  BEGIN   { row }π   row := succ ((pred(roomnumber) MOD (columns * rows)) DIV columns)π  END;ππ  FUNCTION column (roomnumber : roomnumbertype) : columntype;ππ  BEGIN   { column }π   column := succ (pred(roomnumber) MOD columns)π  END;ππ{π     Putting it all together, suppose you have a room, "room", with roomπnumber "roomnumber", that you want to put into the world.π}π VAR world : worldtype;π     room : roomtype;π     roomnumber : roomnumbertype;ππ WITH world DOπ  BEGINπ   spatial[layer(roomnumber), row(roomnumber), column(roomnumber)] := roomπ  END;π{π     The above fragment stores a room into the three-dimensional world.πOf course, if you know the room number (which we do), you can also simplyπ}ππ WITH world DO linear[roomnumber] := roomπ{π     For the original question, note that the "roomnumber" function givesπyou the record number for the Seek procedure (you may need to offset by 1,πdepending on how Seek is implemented ...).π}π