{ 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.