-- CGBrickBLTImpl.mesa
-- Last changed by Ken Pier,              30-Mar-82 14:46:36

DIRECTORY
  CGBrickBLT,
  CGBandFormat,
  BitBlt;

CGBrickBLTImpl: PROGRAM
IMPORTS  BitBlt
EXPORTS CGBrickBLT = {
OPEN BB: BitBlt, BFormat: CGBandFormat, CGBrickBLT;

--InitializeBrickBLT is called with a client BBTableSpace.
--Procedure makes bbtable and fills in constant values for blitting
--scanline buffer into band buffer. Clients will pass this bbtable
--to other routines for filling and blitting.

bitsPerWord: CARDINAL = 16;

InitializeBrickBLT: PUBLIC PROC [ptr: POINTER TO BB.BBTableSpace] RETURNS [bbptr: BB.BBptr] = {

  bbf: BB.BitBltFlags = [
    direction: forward,
    disjoint: TRUE,
    disjointItems: FALSE,
    gray: FALSE,
    srcFunc: null,
    dstFunc: null,
    reserved: 0];
    
  nullBitAddress: BB.BitAddress ← [word: NIL, reserved: 0, bit: 0];
    
  bbptr ← BB.AlignedBBTable[ptr];
  bbptr↑ ← [
    dst: nullBitAddress,
    dstBpl: 0,
    src: nullBitAddress,
    srcDesc: [srcBpl[0]],
    width: 0,
    height: 1,
    flags: bbf,
    reserved: 0];
  
  };--InitializeBrickBLT

BrickBLT:PUBLIC PROC [bbptr: BB.BBptr, tBrick: BFormat.TBrickRef,
		destLine: LONG POINTER, hx, hy: CARDINAL,
	        xmin,xmax: CARDINAL,
		lineBuffer: LONG POINTER] = {
  w, wmax: CARDINAL;
  L: CARDINAL ← tBrick.L;
  brickIndex: CARDINAL ← L*hy;
--put a line from the tBrick into the line buffer
  bbptr↑ ← [
    dst: [word: lineBuffer, reserved: , bit: 0],
    dstBpl: 0,
    src: [word: @tBrick.brick+(brickIndex/bitsPerWord)+1, reserved: , bit: brickIndex MOD bitsPerWord],
    srcDesc: [srcBpl[0]],
    width: L,
    height: 1];
    BB.BITBLT[bbptr];
    
  --now replicate the brick line of length L to form a scan line,
  --doubling the replication length each time thru the loop
    bbptr.src ←  [word: lineBuffer, bit: 0];
    wmax ← hx+xmax-xmin; --max number of bits needed
    w ← L; --start with L bits in lineBuffer
    UNTIL w >= wmax/2 DO
      bbptr.dst ← [word: lineBuffer+(w/bitsPerWord), reserved: , bit: w MOD bitsPerWord];
      bbptr.width ← w;
      BB.BITBLT[bbptr];
      w ← w+w;
      ENDLOOP;
    bbptr.dst ← [word: lineBuffer+(w/bitsPerWord), reserved: , bit: w MOD bitsPerWord];
    bbptr.width ← wmax-w;
    BB.BITBLT[bbptr];
    
  --now BLT the lineBuffer into the bitmap
  bbptr.dst.word ← destLine+xmin/16;
  bbptr.dst.bit ← xmin MOD 16;
  bbptr.src.word ← lineBuffer+hx/bitsPerWord;
  bbptr.src.bit ← hx MOD bitsPerWord;
  bbptr.width ← xmax-xmin;
  BB.BITBLT[bbptr];

  };--BrickBLT

}.--CGBrickBLTImpl



LOG

--created 2/3/82 by Pier
--changed BrickBLT to use BITBLT to build scanlines