[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]
{
> I'm hoping that some kind soul, possibly even the author, might be
> willing to repost this valuable source (that we can ALL learn off of),
> or lead me in the right direction to find it.
I don't know whether we have the same piece of code in mind, but I also read
that message and copied it. But I did some altering. If you would settle with
my (altered) source code, then here it is:
}
{===========================================================================}
{ }
{ Name TEXTMAP.TPU }
{ Description Unit used for texture mapping. }
{ Version 1.0 }
{ }
{ Author Alex Chalfin 1:108/180 (adapted by Kris Verbeeck) }
{ Last update 9th Sep, 1994 }
{ }
{===========================================================================}
UNIT TextMap;
{$N+}
{===[ Interface part ]======================================================}
INTERFACE
{---[ Units used in interface part ]----------------------------------------}
USES
VGA;
{---[ Global constants ]----------------------------------------------------}
CONST
_TOP = 1;
_BOTTOM = 2;
_LEFT = 3;
_RIGHT = 4;
{---[ Global Types ]--------------------------------------------------------}
TYPE
Corners = ARRAY[0..3] of Point2D;
Bitmap = RECORD
xs, ys : INTEGER;
image : POINTER;
END;
{---[ Global Variables ]----------------------------------------------------}
{ VAR
none }
{---[ Global Routines ]-----------------------------------------------------}
PROCEDURE TextureMap( fp, tp : Corners; b : Bitmap );
{ -- Maps the 4 point polygon bitmap 'fp' to another 4 point
polygon 'tp' }
{===[ Implementation part ]=================================================}
IMPLEMENTATION
{---[ Units used in implementation part ]-----------------------------------}
{ USES
none }
{---[ Local constants ]-----------------------------------------------------}
{ CONST
none }
{---[ Local Types ]---------------------------------------------------------}
{ TyPE
none; }
{---[ Local Variables ]-----------------------------------------------------}
VAR
LeftTable, RightTable : ARRAY[0..199, 0..2] of INTEGER;
Max_y, Min_y : INTEGER;
LineHeight : INTEGER;
PWidth, PHeight : INTEGER;
Px0, Py0 : INTEGER;
{---[ Local Routines ]------------------------------------------------------}
PROCEDURE Swap( VAR a, b : INTEGER);
VAR
aux : INTEGER;
BEGIN
aux := a;
a := b;
b := aux;
END;
PROCEDURE FindMaxMin( p : Corners ); {ASSEMBLER;}
VAR
i : INTEGER;
BEGIN
Min_y := 0;
Max_y := 32000;
FOR i := 0 TO 3 DO BEGIN
IF (p[i].y < Min_y) THEN
Min_y := p[i].y;
IF (p[i].y > Max_y) THEN
Max_y := p[i].y;
END;
(* ASM
mov Max_y,0000h
mov Min_y,7FFFh
les bx,p
add bx,2 { Point to first y-coord }
mov cx,0004h { Check 4 coords }
@Loop:
mov ax,es:[bx] { Get first y-coord }
cmp ax,Min_y
ja @NotLower
mov Min_y,ax
@NotLower:
cmp ax,Max_y
jb @NotHigher
mov Max_y,ax
@NotHigher:
add bx,4 { Point to next y-coord }
loop @Loop
END;*)
PROCEDURE ScanLeft( x1, x2, y1, lh, side : INTEGER );
VAR
y : INTEGER;
xAdd, Px, Py, PxAdd, PyAdd, x : SINGLE;
BEGIN
lh := lh + 1;
xAdd := (x2-x1)/lh;
CASE side OF
_TOP : BEGIN
Px := PWidth;
Py := 0;
PxAdd := -PWidth/lh;
PyAdd := 0;
END;
_RIGHT : BEGIN
Px := PWidth;
Py := PHeight;
PxAdd := 0;
PyAdd := -PHeight/lh;
END;
_BOTTOM : BEGIN
Px := 0;
Py := PHeight;
PxAdd := PWidth/lh;
PyAdd := 0;
END;
_LEFT : BEGIN
Px := 0;
Py := 0;
PxAdd := 0;
PyAdd := PHeight/lh;
END;
END;
x := x1;
FOR y := 0 TO lh DO BEGIN
LeftTable[y1+y, 0] := Round(x);
LeftTable[y1+y, 1] := Round(Px);
LeftTable[y1+y, 2] := Round(Py);
x := x + xAdd;
Px := Px + PxAdd;
Py := Py + PyAdd;
END;
END;
PROCEDURE ScanRight( x1, x2, y1, lh, side : INTEGER );
VAR
y : INTEGER;
xAdd, Px, Py, PxAdd, PyAdd, x : SINGLE;
BEGIN
lh := lh + 1;
xAdd := (x2-x1)/lh;
CASE side OF
_TOP : BEGIN
Px := 0;
Py := 0;
PxAdd := PWidth/lh;
PyAdd := 0;
END;
_RIGHT : BEGIN
Px := PWidth;
Py := 0;
PxAdd := 0;
PyAdd := PHeight/lh;
END;
_BOTTOM : BEGIN
Px := PWidth;
Py := PHeight;
PxAdd := 0;
PyAdd := -PHeight/lh;
END;
_LEFT : BEGIN
Px := 0;
Py := PHeight;
PxAdd := 0;
PyAdd := -PHeight/lh;
END;
END;
x := x1;
FOR y := 0 TO lh DO BEGIN
RightTable[y1+y, 0] := Round(x);
RightTable[y1+y, 1] := Round(Px);
RightTable[y1+y, 2] := Round(Py);
x := x + xAdd;
Px := Px + PxAdd;
Py := Py + PyAdd;
END;
END;
PROCEDURE ScanConvert( x1, y1, x2, y2, PLoc : INTEGER );
BEGIN
IF (y2 < y1) THEN BEGIN
Swap( x1, x2 );
Swap( y1, y2 );
LineHeight := y2 - y1;
ScanLeft( x1, x2, y1, LineHeight, PLoc );
END ELSE BEGIN
LineHeight := y2 - y1;
ScanRight( x1, x2, y1, LineHeight, PLoc );
END;
END;
PROCEDURE DoMapping( b : Bitmap );
VAR
lw, x, y, Px, Py : INTEGER;
Polyx1, Polyx2, Px1, Px2, Py1, Py2, PxA, PyA : SINGLE;
color : BYTE;
BEGIN
FOR y := Min_y TO Max_y DO BEGIN
Polyx1 := LeftTable[y,0];
Px1 := LeftTable[y,1];
Py1 := LeftTable[y,2];
Polyx2 := RightTable[y,0];
Px2 := RightTable[y,1];
Py2 := RightTable[y,2];
lw := Round(Polyx2-Polyx1);
lw := lw + 1;
PxA := (Px2-Px1)/lw;
PyA := (Py2-Py1)/lw;
FOR x := Round(Polyx1) TO Round(Polyx2) DO BEGIN
Px := Round(Px1);
Py := Round(Py1);
ASM
push ds
mov ax,Py0
add ax,Py
mul b.xs
add ax,Px0
add ax,Px
lds si,b.image
add si,ax
mov ax,y
mov bx,ax
shl ax,8
shl bx,6
add ax,bx
add ax,x
mov di,VSEG
mov es,di
mov di,ax
movsb
pop ds
END;
Px1 := Px1 + PxA;
Py1 := Py1 + PyA;
END;
END;
END;
{---[ Implementation of Global routines ]-----------------------------------}
PROCEDURE TextureMap( fp, tp : Corners; b : Bitmap );
BEGIN
FindMaxMin( tp );
PWidth := fp[1].x - fp[0].x;
PHeight := fp[2].y - fp[1].y;
Px0 := fp[0].x;
Py0 := fp[0].y;
ScanConvert( tp[0].x, tp[0].y, tp[1].x, tp[1].y, _TOP );
ScanConvert( tp[1].x, tp[1].y, tp[2].x, tp[2].y, _RIGHT );
ScanConvert( tp[2].x, tp[2].y, tp[3].x, tp[3].y, _BOTTOM );
ScanConvert( tp[3].x, tp[3].y, tp[0].x, tp[0].y, _LEFT );
DoMapping( b );
END;
{===[ Unit initialization part ]============================================}
{ none }
END.
[Back to EGAVGA SWAG index] [Back to Main SWAG index] [Original]