-- CGSampleImpl.mesa
-- Last edited by Ken Pier, May 12, 1982 6:41 pm
-- Last edited by Doug Wyatt, June 29, 1982 5:35 pm
-- Last edited by Paul Rovner, June 8, 1983 11:12 pm

DIRECTORY
Basics USING [BITAND, BITOR, BITXOR, LongMult, LongNumber],
CGSample USING [Mode, Pointer, Words];

CGSampleImpl: PROGRAM
IMPORTS Basics
EXPORTS CGSample = { OPEN CGSample;

Bytes: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF [0..377B]];

Masks: TYPE = ARRAY [0..16) OF WORD;
mask1array: Masks ← [
100000B, 040000B, 020000B, 010000B, 004000B, 002000B, 001000B, 000400B,
000200B, 000100B, 000040B, 000020B, 000010B, 000004B, 000002B, 000001B];
mask0array: Masks ← [
077777B, 137777B, 157777B, 167777B, 173777B, 175777B, 176777B, 177377B,
177577B, 177677B, 177737B, 177757B, 177767B, 177773B, 177775B, 177776B];
mask1: POINTER TO Masks ← @mask1array;
mask0: POINTER TO Masks ← @mask0array;

Sample8: PUBLIC PROC[p: Pointer, mode: Mode] = {
dAddr, sBase: LONG POINTER;
sLine: LONG POINTER TO Bytes;
map, bLine: LONG POINTER TO Words;
dWord, count, di, bi, bw, sly, sRast: CARDINAL;
sx, sy, sdx, sdy: Basics.LongNumber;

count ← p.count; IF count=0 THEN RETURN;
di ← p.di; dAddr ← p.dLine + di/16; dWord ← dAddr^; di ← di MOD 16;

-- Set up for source
sBase ← p.sBase; sRast ← p.sRast;
sx.li ← p.sx; sy.li ← p.sy; sdx.li ← p.sdx; sdy.li ← p.sdy;
sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
-- Set up for brick and map
bi ← p.bi; bw ← p.bw; bLine ← p.bLine; map ← p.map;
SELECT mode FROM
opaque => DO
-- Fetch source and brick values, and compare
IF map[sLine[sx.highbits]]<=bLine[bi] THEN dWord ← Basics.BITOR[dWord, mask1[di]]
ELSE dWord ← Basics.BITAND[dWord, mask0[di]];
-- Terminate loop?
IF (count ← count-1)=0 THEN EXIT;
-- Bump destination position
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
-- Bump brick position
IF (bi ← bi+1)=bw THEN bi ← 0;
-- Bump source position
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
transparent => DO
IF map[sLine[sx.highbits]]<=bLine[bi] THEN dWord ← Basics.BITOR[dWord, mask1[di]];
IF (count ← count-1)=0 THEN EXIT;
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
IF (bi ← bi+1)=bw THEN bi ← 0;
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
invert => DO
IF map[sLine[sx.highbits]]<=bLine[bi] THEN dWord ← Basics.BITXOR[dWord, mask1[di]];
IF (count ← count-1)=0 THEN EXIT;
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
IF (bi ← bi+1)=bw THEN bi ← 0;
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
ENDCASE;
dAddr^ ← dWord;
};

Sample0: PUBLIC PROC[p: Pointer, mode: Mode] = {
dAddr, sBase, sLine: LONG POINTER;
dWord, count, di, sly, sRast: CARDINAL;
sx, sy, sdx, sdy: Basics.LongNumber;

count ← p.count; IF count=0 THEN RETURN;
di ← p.di; dAddr ← p.dLine + di/16; dWord ← dAddr^; di ← di MOD 16;

-- Set up for source
sBase ← p.sBase; sRast ← p.sRast;
sx.li ← p.sx; sy.li ← p.sy; sdx.li ← p.sdx; sdy.li ← p.sdy;
sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];

SELECT mode FROM
opaque => DO
IF Basics.BITAND[(sLine+sx.highbits/16)^,mask1[sx.highbits MOD 16]]#0
THEN dWord ← Basics.BITOR[dWord, mask1[di]]
ELSE dWord ← Basics.BITAND[dWord, mask0[di]];
-- Terminate loop?
IF (count ← count-1)=0 THEN EXIT;
-- Bump destination position
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
-- Bump source position
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
transparent => DO
IF Basics.BITAND[(sLine+sx.highbits/16)^,mask1[sx.highbits MOD 16]]#0
THEN dWord ← Basics.BITOR[dWord, mask1[di]];
IF (count ← count-1)=0 THEN EXIT;
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
invert => DO
IF Basics.BITAND[(sLine+sx.highbits/16)^,mask1[sx.highbits MOD 16]]#0
THEN dWord ← Basics.BITXOR[dWord, mask1[di]];
IF (count ← count-1)=0 THEN EXIT;
IF (di ← di+1)=16 THEN { dAddr^ ← dWord; dWord ← (dAddr ← dAddr+1)^; di ← 0 };
sx.li ← sx.li + sdx.li; sy.li ← sy.li + sdy.li;
IF sy.highbits#sly THEN sLine ← sBase + Basics.LongMult[(sly ← sy.highbits), sRast];
ENDLOOP;
ENDCASE;
dAddr^ ← dWord;
};

}.