-- Trapezoid.mesa
-- j warnock September 6, 1979 10:36 AM
-- last changed: February 5, 1981 9:24 AM

DIRECTORY
BitBltDefs: FROM "BitBltDefs" USING[BITBLT, BBTable, BBoperation],
InlineDefs: FROM "InlineDefs" USING[HighHalf, LowHalf],
Real: FROM "Real" USING [Fix, FixC],
SegmentDefs: FROM "SegmentDefs" USING [GetMemoryConfig],
TrapezoidDefs: FROM "TrapezoidDefs" USING [TrapezoidBlock];

Trapezoid: PROGRAM
IMPORTS BitBltDefs, InlineDefs, Real, SegmentDefs
EXPORTS TrapezoidDefs =
BEGIN OPEN BitBltDefs, InlineDefs, Real, SegmentDefs, TrapezoidDefs;


TrapezoidBlt: PUBLIC PROCEDURE [t:POINTER TO TrapezoidBlock] =
BEGIN
BltLine: PROCEDURE [xl,xr:LONG INTEGER,y:CARDINAL] =
BEGIN
bbt.dlx←LOOPHOLE[InlineDefs.HighHalf[xl],CARDINAL];
bbt.dw←LOOPHOLE[InlineDefs.HighHalf[xr],CARDINAL]-
LOOPHOLE[InlineDefs.HighHalf[xl],CARDINAL]+1;
bbt.dty← y;
bbt.gray0←texture[y MOD 4];
BITBLT[bbt];
END;
xldel,xrdel,ydelta,xldelta,xrdelta,ytemp:REAL;
udxl,udxr,xlt,xmt,xrt:LONG INTEGER;
ys,yl:CARDINAL;
texture←t.texture;
bbt.function← t.function;
IF DStar THEN
BEGIN --D*
bbt.ptrs ← long;
bbt.dlbca ← t.xbase;
END
ELSE
BEGIN --Alto
bbt.ptrs ← short;
bbt.destalt ← HighHalf[t.xbase]#0;
bbt.unused ← HighHalf[t.xbase];
bbt.dbca ← LowHalf[t.xbase];
END;
bbt.dbmr← t.xwords;
xldel ← t.xeleft - t.xsleft;
xrdel ← t.xeright - t.xsright;
ys ← FixC[t.ystart];
--Check for simple BitBlt case (MN)
IF xldel=0 AND xrdel=0 THEN
BEGIN
bbt.dlx ← FixC[t.xsleft];
bbt.dw ← FixC[t.xsright] - bbt.dlx + 1;
bbt.dty ← ys;
bbt.dh ← MAX[1,FixC[t.yend] - bbt.dty + 1];
bbt.gray0 ← texture[ys MOD 4];
bbt.gray1 ← texture[(ys+1) MOD 4];
bbt.gray2 ← texture[(ys+2) MOD 4];
bbt.gray3 ← texture[(ys+3) MOD 4];
BITBLT[bbt];
RETURN;
END;
bbt.dh ← 1;
yl←LOOPHOLE[InlineDefs.HighHalf[Fix[t.yend*65536]-Fix[t.ystart*65536]]];
--Trapezoid starts and ends on same scanline
IF yl = 0 THEN
BEGIN
xlt← Fix[MIN[t.xsleft,t.xeleft]*65536];
xrt← Fix[MAX[t.xsright,t.xeright]*65536];
BltLine[xlt,xrt,ys];
RETURN;
END;
--Trapezoid is short but stradles the scanline
IF (ydelta←(t.yend-t.ystart)) < epsilon THEN
BEGIN
xlt← Fix[MIN[t.xsleft,t.xeleft]*65536];
xrt← Fix[MAX[t.xsright,t.xeright]*65536];
xmt←(xlt + (xrt-xlt)/2);
BltLine[xlt,xmt,ys];
ys←ys+1;
BltLine[xmt,xrt,ys];
RETURN;
END
ELSE
--Trapezoid has sufficient y-delta to compute slopes.
BEGIN
xldelta←((t.xeleft-t.xsleft)/ydelta);
xrdelta←((t.xeright-t.xsright)/ydelta);
END;
udxl←Fix[xldelta*65536];
udxr←Fix[xrdelta*65536];
xlt←Fix[t.xsleft*65536];
xrt←Fix[t.xsright*65536];
ytemp←ys+1-t.ystart;
IF udxl < 0 THEN xlt←xlt+Fix[(ytemp*xldelta)*65536];
IF udxr > 0 THEN xrt←xrt+Fix[(ytemp*xrdelta)*65536];
BltLine[xlt,xrt,ys];
ys←ys+1;
IF udxl < 0 THEN xlt←xlt+udxl ELSE xlt←xlt+Fix[(ytemp*xldelta)*65536];
IF udxr > 0 THEN xrt←xrt+udxr ELSE xrt←xrt+Fix[(ytemp*xrdelta)*65536];
THROUGH [1..yl)
DO
BltLine[xlt,xrt,ys];
xlt←xlt+udxl;
xrt←xrt+udxr;
ys←ys+1;
ENDLOOP;
--Pick up the partial line at the end.
IF (ytemp←t.yend-ys) >= 0 THEN
BEGIN
xlt←Fix[t.xeleft*65536];
xrt←Fix[t.xeright*65536];
IF udxl > 0 THEN xlt←xlt-Fix[(ytemp*xldelta)*65536];
IF udxr < 0 THEN xrt←xrt-Fix[(ytemp*xrdelta)*65536];
BltLine[xlt,xrt,ys]
END;
END;

one:REAL ← 1;
epsilon:REAL ← one/4000;
DStar: BOOLEAN ← SELECT GetMemoryConfig[].AltoType FROM
AltoI, AltoII, AltoIIXM => FALSE,
D0, Dorado => TRUE,
ENDCASE => FALSE;

texture:POINTER TO ARRAY [0..4) OF CARDINAL;
bb:ARRAY [0..SIZE[BitBltDefs.BBTable]] OF UNSPECIFIED;
bbt:POINTER TO BitBltDefs.BBTable ← @bb[LOOPHOLE[@bb,CARDINAL] MOD 2];
bbt↑ ← BitBltDefs.BBTable[
ptrs: ,
pad: 0,
sourcealt: FALSE,
destalt: FALSE,
sourcetype: gray,
function: paint,
unused: ,
dbca:NIL,
dbmr:0,
dlx: 0,-- destination left x
dty: 0,-- destination top y
dw: 0,
dh: 1,
sbca: NIL,
sbmr: 0,
slx: 0,
sty: 0,
gray0: 177777B,
gray1: 177777B,
gray2: 177777B,
gray3: 177777B,
slbca: NIL,
dlbca: NIL
];

END.