SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00029 GRAPHICS ROUTINES 1 05-28-9313:47ALL SWAG SUPPORT TEAM 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 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 ╓ {π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 ╓ {π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 ╓ {π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 ╓ {π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 ╓ {π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 ╓ {π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 ╓ {π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 ╓ {π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 routineIMPORT 29 ╓ {π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 ╓ 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 ╓ {π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 ╓ {π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 ╓ {π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.π