-- cbitfns.mesa (used in Chipmonk) -- last modified by E. McCreight, December 20, 1982 10:24 AM DIRECTORY BitBltDefs, GeneralDisplayDefs, multiGraphicsDefs, InlineDefs, SystemDefs, SegmentDefs, ZoneAllocDefs; cbitfns: MONITOR IMPORTS BitBltDefs, InlineDefs, multiGraphicsDefs, SegmentDefs, SystemDefs, ZoneAllocDefs EXPORTS multiGraphicsDefs = BEGIN OPEN GeneralDisplayDefs,multiGraphicsDefs,InlineDefs; Machine: SegmentDefs.MachineType = SegmentDefs.GetMemoryConfig[].AltoType; DMachine: BOOLEAN = (Machine = D0) OR (Machine = Dorado); Dor: BOOLEAN = Machine = Dorado; Screen: BitmapPtr _ NIL; --data structures for D0 style color display colorData: TYPE = MACHINE DEPENDENT RECORD [ addr: [0..16), r,g,b,unused: BOOLEAN, data: [0..256) ]; colorEntry: TYPE = RECORD [ red,green,blue: colorData ]; colorTable: TYPE = RECORD --must be hexAligned [ front: ARRAY [0..2) OF UNSPECIFIED, entry: ARRAY [0..16) OF colorEntry, back: ARRAY [0..10) OF UNSPECIFIED, hexAlignPad: ARRAY [0..16) OF UNSPECIFIED ]; --data structures for D1 style color display from GeneralDisplayDefs --global variables ColorBitmap: POINTER TO POINTER = LOOPHOLE[414B]; ColorBitmapBank: POINTER TO CARDINAL = LOOPHOLE[415B]; ColorMap: POINTER TO POINTER = LOOPHOLE[416B]; ColorMapBank: POINTER TO CARDINAL = LOOPHOLE[417B]; ColorCtrlBlk: ColorControlBlock; AChanCtrlBlk: ChannelControlBlock; ColorMonitor: MonitorControlBlock; ColorTablePlace:CARDINAL=26250B; ColorTable: LONG POINTER TO colorTable _ LOOPHOLE[1200000B+ColorTablePlace]; ColorTable8: POINTER TO ATableImage; ColorWord: CARDINAL _ 0; freeBLTBlocks: BLTBlockPtr _ NIL; mdsz: MDSZone = ZoneAllocDefs.GetTheMDSZone[]; AllocateBLT: PUBLIC ENTRY PROC RETURNS[bb: BLTBlockPtr] = BEGIN IF freeBLTBlocks#NIL THEN {bb _ freeBLTBlocks; freeBLTBlocks _ freeBLTBlocks.next} ELSE BEGIN bb _ mdsz.NEW[BLTBlock]; IF LOOPHOLE[@bb.blk, CARDINAL] MOD 2 # 0 THEN -- even-word align bb _ LOOPHOLE[LOOPHOLE[bb, CARDINAL]+1, BLTBlockPtr]; bb.next _ NIL; bb.blk _ [ptrs: IF DMachine THEN long ELSE short, pad: 0, sourcealt: FALSE, sourcetype: gray, dbca: NIL, gray0: 177777B, gray1: 177777B, gray2: 177777B, gray3:177777B, sbca: NIL, unused: 0, sbmr: 0]; END; END; FreeBLT: PUBLIC ENTRY PROC [bb: BLTBlockPtr] = {bb.next _ freeBLTBlocks; freeBLTBlocks _ bb}; SetColorTable: PUBLIC PROC [new: POINTER TO ARRAY [0..0) OF CARDINAL, outputDevice: BitmapPtr _ NIL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; IF NOT Dor THEN BEGIN -- a Dolphin i: CARDINAL; ColorTable^.front _ ALL[0]; ColorTable^.back _ ALL[0]; FOR i IN [0..17B] DO ColorTable^.entry[i].red _ [i,TRUE,FALSE,FALSE,FALSE,new[i*3]]; ColorTable^.entry[i].green _ [i,FALSE,TRUE,FALSE,FALSE,new[i*3+1]]; ColorTable^.entry[i].blue _ [i,FALSE,FALSE,TRUE,FALSE,new[i*3+2]]; ENDLOOP; END ELSE BEGIN -- a Dorado i: CARDINAL; FOR i IN [0..1024) DO ColorTable8[i].zeroHigh _ ColorTable8[i].zeroLow _ 0; ENDLOOP; FOR i IN [0..16) DO ColorTable8[i*4] _ ColorTable8[i*4*16] _ [0,(255-new[i*3]) MOD 16,(255-new[i*3+2]),0,(255-new[i*3+1]),(255-new[i*3])/16]; ENDLOOP; pMonitorHead.Flags _ [0,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,TRUE]; END; END; halftoneWord: TYPE = MACHINE DEPENDENT RECORD [ unused: [0..7777B], val1,val2,val3,val4: BOOLEAN ]; GetColorGray: PUBLIC PROC [c: Color] RETURNS[GrayPattern] = BEGIN IF c>255 THEN BEGIN -- two colors, in alternation combin: CARDINAL = BITAND[255,c]; pat1: CARDINAL = combin + BITSHIFT[combin,8]; pat2: CARDINAL = BITOR[BITSHIFT[pat1,4],BITSHIFT[combin,-4]]; RETURN[[pat1,pat2,pat1,pat2,pat1,pat2,pat1]]; END ELSE BEGIN pixCol: CARDINAL = BITAND[c, 15]; halfcw: CARDINAL = BITOR[BITSHIFT[pixCol, 4], pixCol]; cw: CARDINAL = BITOR[BITSHIFT[halfcw, 8], halfcw]; -- pixCol replicated four times SELECT c-pixCol FROM 0 => RETURN[ALL[cw]]; -- every pixel set to pixCol ENDCASE => BEGIN m: GrayPattern _ GetMaskGray[c]; FOR i: GrayPatternIndex IN GrayPatternIndex DO m[i] _ BITAND[m[i], cw]; ENDLOOP; RETURN[m]; END; END; END; GetMaskGray: PUBLIC PROC [c: Color] RETURNS[GrayPattern] = BEGIN pixCol: [0..16) = BITAND[c, 15]; RETURN[SELECT c-pixCol FROM 16 => [7400B,7400B,17B,17B,7400B,7400B,17B], -- The pattern -- .*.. -- .*.. -- ...* -- ...* 32 => [7417B,170360B,7417B,170360B,7417B,170360B,7417B], -- The pattern -- .*.* -- *.*. -- .*.* -- *.*. 48 => [7400B,7400B,0,0,7400B,7400B,0], -- The pattern -- .*.. -- .*.. -- .... -- .... 64 => [170377B,177760B,170377B,177760B,170377B,177760B,170377B], -- The pattern -- *.** -- ***. -- *.** -- ***. ENDCASE => ALL[177777B] -- all bits --]; END; -- The following Set/Get routines seem to be no-ops for Chipmonk's 4-bits-per-point -- color display. SetRed: PUBLIC PROC[gray: [0..256),newVal: [0..256),outputDevice: BitmapPtr _ NIL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>BEGIN ColorTable8[gray*4].redHigh _ newVal/16; ColorTable8[gray*4].redLow _ newVal MOD 16; pMonitorHead.Flags _ [0,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,TRUE]; END; ENDCASE; END; SetGreen: PUBLIC PROC[gray: [0..256),newVal: [0..256),outputDevice: BitmapPtr _ NIL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>BEGIN ColorTable8[gray*4].green _ newVal; pMonitorHead.Flags _ [0,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,TRUE]; END; ENDCASE; END; SetBlue: PUBLIC PROC[gray: [0..256),newVal: [0..256),outputDevice: BitmapPtr _ NIL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>BEGIN ColorTable8[gray*4].blue _ newVal; pMonitorHead.Flags _ [0,FALSE,FALSE,FALSE,FALSE,TRUE,TRUE,TRUE]; END; ENDCASE; END; GetRed: PUBLIC PROC[gray: [0..256),outputDevice: BitmapPtr _ NIL] RETURNS [CARDINAL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>RETURN[ColorTable8[gray*4].redHigh*16+ColorTable8[gray*4].redLow]; ENDCASE=>RETURN[0]; END; GetGreen: PUBLIC PROC[gray: [0..256),outputDevice: BitmapPtr _ NIL] RETURNS [CARDINAL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>RETURN[ColorTable8[gray*4].green]; ENDCASE=>RETURN[0]; END; GetBlue: PUBLIC PROC[gray: [0..256),outputDevice: BitmapPtr _ NIL] RETURNS [CARDINAL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; SELECT outputDevice.nBitsPerPixel FROM 8=>RETURN[ColorTable8[gray*4].blue]; ENDCASE=>RETURN[0]; END; TurnOnColor: PUBLIC PROC [bitsPerPixel: CARDINAL _ 1,portraitMode: BOOLEAN _ TRUE,scalePercent: CARDINAL _ 100, initColor: Color] RETURNS [BitmapPtr] = BEGIN scaleFactor: CARDINAL _ scalePercent/10; IF Screen = NIL THEN --ought to be able to return a couple of screens... BEGIN Screen _ SystemDefs.AllocateHeapNode[SIZE[Bitmap]]; IF portraitMode THEN BEGIN Screen.nBits _ (640*10)/scaleFactor; Screen.nLines _ (481*10)/scaleFactor; END ELSE BEGIN Screen.nBits _ (481*10)/scaleFactor; Screen.nLines _ (640*10)/scaleFactor; END; END; Screen.nBitsPerPixel _ bitsPerPixel; Screen.portraitMode _ portraitMode; Screen.scaleFactor _ scaleFactor; Screen.nWords _ IF portraitMode THEN 2*bitsPerPixel*((Screen.nBits+31)/32) ELSE 2*bitsPerPixel*((Screen.nLines+31)/32) ; IF NOT Dor THEN BEGIN i:CARDINAL; temp:ARRAY[0..47] OF CARDINAL; FOR i IN [0..47] DO temp[i]_i*4; ENDLOOP; SetColorTable[LOOPHOLE[@temp]]; ColorBitmap^ _ LOOPHOLE[0]; --InlineDefs.LowHalf[longP]; ColorBitmapBank^ _ 4; --InlineDefs.HighHalf[longP]; ColorMap^ _ LOOPHOLE[ColorTablePlace]; ColorMapBank^ _ 5; Screen.bank _ 4; --1; Screen.bits_LOOPHOLE[ColorBitmap^]; EraseColorArea[0,0,Screen.nBits,Screen.nLines, initColor]; END ELSE BEGIN temp:ARRAY[0..47] OF CARDINAL; i: CARDINAL; FOR i IN [0..47] DO temp[i]_i*4; ENDLOOP; ColorTable8 _ SystemDefs.AllocateSegment[SIZE[ATableImage]]; Screen.bank _ 4; Screen.bits_LOOPHOLE[0]; ColorCtrlBlk _ [ ATable: ColorTable8, BTable: NIL,CTable: NIL,MiniMixer: NIL, VBlank: [VBtoVS: 3,VStoVS: 3],VStoVB: 20B,VisibleLines: 240, HRamMaxAddr: 379,HBlank: [HBLeadLength: 6,HSTrailAddr: 47B], HBTrailLength: 16B,PClock: [unused: 0,PClockMul: 130B,PClockDiv: 14B], reserved: 0 ]; AChanCtrlBlk _ [ NIL,Screen.nWords,MakeLongPointer[Screen.bits,Screen.bank], Screen.nLines/2,(Screen.nWords*16)/bitsPerPixel+377B, MarginOffset[Ramtek525], [unused: 0, b24BitsPerPixel: FALSE,AByPass: FALSE,BByPass: FALSE,A8B2: TRUE, Resolution: full,Size8: FALSE,Size4:TRUE,Size2: FALSE,Size1: FALSE ] ]; ColorMonitor _ [ 177456B,[0,FALSE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE], @AChanCtrlBlk,NIL,@ColorCtrlBlk ]; ReplaceColorArea[0,0,Screen.nBits,Screen.nLines, initColor]; pMonitorHead^ _ @ColorMonitor; SetColorTable[LOOPHOLE[@temp]]; END; RETURN[Screen]; END; KillGraphics:PUBLIC PROC[outputDevice:BitmapPtr_NIL] = BEGIN IF outputDevice = NIL THEN outputDevice _ Screen; IF outputDevice = NIL THEN RETURN; IF NOT Dor THEN BEGIN ColorBitmap^ _ LOOPHOLE[0]; --InlineDefs.LowHalf[longP]; ColorBitmapBank^ _ 0; --InlineDefs.HighHalf[longP]; ColorMap^ _ LOOPHOLE[0]; ColorMapBank^ _ 0; END ELSE pMonitorHead^_NIL; END; logTable: ARRAY [1..8] OF CARDINAL = [0,1,2,2,3,3,3,3]; SetColorFromSource: PUBLIC PROC [source: BitmapPtr, x,y: INTEGER, fn: BitBltDefs.BBoperation, sourceType: BitBltDefs.BBsourcetype _ block, gray: GrayPatternPtr _ NIL, dest: BitmapPtr _ NIL] = BEGIN BLT: BLTBlockPtr; x2,y2: INTEGER; sx,sy,dy: INTEGER _ 0; logBitsPerPixel: CARDINAL; IF dest = NIL THEN dest _ Screen; logBitsPerPixel _ logTable[dest.nBitsPerPixel]; x2 _ x+source.nBits-1; y2 _ y+source.nLines-1; IF x >= INTEGER[dest.nBits] OR y >= INTEGER[dest.nLines] THEN RETURN; IF x2 >= INTEGER[dest.nBits] THEN x2 _ dest.nBits - 1; IF y2 >= INTEGER[dest.nLines] THEN BEGIN dy _ y2-(INTEGER[dest.nLines]-1);y2 _ dest.nLines-1;END; IF x < 0 THEN BEGIN sx _ -x;x _ 0;END; IF y < 0 THEN BEGIN sy _ -y;y _ 0;END; IF NOT dest.portraitMode THEN BEGIN t: CARDINAL; t _ (INTEGER[dest.nLines]-1)-y;y _ x; x _ (INTEGER[dest.nLines]-1)-y2; y2 _ MIN[x2,y+INTEGER[source.nBits]-1];x2 _ MIN[t,x+INTEGER[source.nLines]-1]; sy _ sx;sx _ dy; END; BLT _ AllocateBLT[]; IF gray#NIL THEN LOOPHOLE[@BLT.blk.gray0, GrayPatternPtr]^ _ gray^; BLT.blk.sourcetype _ sourceType; BLT.blk.function _ fn; BLT.blk.dlbca _ MakeLongPointer[dest.bits,dest.bank]; BLT.blk.dbmr _ dest.nWords; BLT.blk.dlx _ InlineDefs.BITSHIFT[x,logBitsPerPixel]; BLT.blk.dty _ y; BLT.blk.dw _ InlineDefs.BITSHIFT[(x2+1-x),logBitsPerPixel]; BLT.blk.dh _ (y2+1-y); BLT.blk.slbca _ MakeLongPointer[source.bits,source.bank]; BLT.blk.sbmr _ source.nWords; BLT.blk.slx _ sx; BLT.blk.sty _ sy; BitBltDefs.BITBLT[@BLT.blk]; FreeBLT[BLT]; END; SetColorPoint: PUBLIC PROC [x, y: INTEGER, fn: BitBltDefs.BBoperation, c: Color _ 0, b: BitmapPtr _ NIL, cGray: GrayPatternPtr _ NIL] = BEGIN BLT: BLTBlockPtr; logBitsPerPixel: CARDINAL; IF b = NIL THEN b _ Screen; logBitsPerPixel _ logTable[b.nBitsPerPixel]; IF NOT x IN [0..INTEGER[b.nBits]) THEN RETURN; IF NOT y IN [0..INTEGER[b.nLines]) THEN RETURN; -- save your ass IF NOT b.portraitMode THEN BEGIN t: INTEGER _ (INTEGER[b.nLines]-1)-y;y _ x;x _ t;END; BLT _ AllocateBLT[]; LOOPHOLE[@BLT.blk.gray0, GrayPatternPtr]^ _ IF cGray#NIL THEN cGray^ ELSE GetColorGray[c]; BLT.blk.sourcetype _ gray; BLT.blk.dw _ Screen.nBitsPerPixel; BLT.blk.dh _ 1; BLT.blk.function _ fn; BLT.blk.dlbca _ MakeLongPointer[b.bits,b.bank]; BLT.blk.dbmr _ b.nWords; BLT.blk.dlx _ InlineDefs.BITSHIFT[x,logBitsPerPixel]; BLT.blk.dty _ y; BitBltDefs.BITBLT[@BLT.blk]; FreeBLT[BLT]; END; SetColorLine: PUBLIC PROC [x1,y1,x2,y2: INTEGER, fn: BitBltDefs.BBoperation, c: Color _ 0, b: BitmapPtr _ NIL, cGray: GrayPatternPtr _ NIL] = BEGIN fpOff:INTEGER = 20000B; BLT: BLTBlockPtr; logBitsPerPixel: CARDINAL; dx,dy,oi,nn,partl,pinc:INTEGER; li:LONG INTEGER; IF b = NIL THEN b _ Screen; logBitsPerPixel _ logTable[b.nBitsPerPixel]; IF NOT b.portraitMode THEN BEGIN t: INTEGER; t _ (INTEGER[b.nLines]-1)-y1;y1 _ x1; x1 _ (INTEGER[b.nLines]-1)-y2;y2 _ x2;x2 _ t; END; dx_x2-x1;dy_y2-y1; BLT _ AllocateBLT[]; LOOPHOLE[@BLT.blk.gray0, GrayPatternPtr]^ _ IF cGray#NIL THEN cGray^ ELSE GetColorGray[c]; BLT.blk.sourcetype _ gray; BLT.blk.function _ fn; BLT.blk.dlbca _ MakeLongPointer[b.bits,b.bank]; BLT.blk.dbmr _ b.nWords; BLT.blk.sty _ 0; --DORADO looks here IF ABS[dx]>ABS[dy] THEN BEGIN BLT.blk.dh _ 1; IF dx<0 THEN BEGIN t:INTEGER;t_x1;x1_x2;x2_t;t_y1;y1_y2; y2_t;dx_-dx;dy_-dy;END; oi_IF dy<0 THEN -1 ELSE IF dy=0 THEN 0 ELSE 1; li_ABS[dy]; li_li*fpOff; li_li/dx; pinc_InlineDefs.LowHalf[li]; partl_0; UNTIL x1>=x2 DO nn_0; UNTIL partl>fpOff OR nn>=dx DO nn_nn+1; partl_partl+pinc; ENDLOOP; --must worry about off-screen BLT.blk.dlx _ InlineDefs.BITSHIFT[x1,logBitsPerPixel]; BLT.blk.dw _ InlineDefs.BITSHIFT[nn,logBitsPerPixel]; BLT.blk.dty _ y1; partl_partl-fpOff; y1_y1+oi; x1_x1+nn; BitBltDefs.BITBLT[@BLT.blk]; ENDLOOP; END ELSE BEGIN BLT.blk.dw _ b.nBitsPerPixel; IF dy<0 THEN BEGIN t:INTEGER;t_x1;x1_x2;x2_t;t_y1;y1_y2; y2_t;dx_-dx;dy_-dy;END; oi_IF dx<0 THEN -1 ELSE IF dx=0 THEN 0 ELSE 1; li_ABS[dx]; li_li*fpOff; li_li/dy; pinc_InlineDefs.LowHalf[li]; partl_0; UNTIL y1>=y2 DO nn_0; UNTIL partl>fpOff OR nn>=dy DO nn_nn+1; partl_partl+pinc; ENDLOOP; --must worry about off-screen BLT.blk.dty _ y1; BLT.blk.dh _ nn; BLT.blk.dlx _ InlineDefs.BITSHIFT[x1,logBitsPerPixel]; partl_partl-fpOff; x1_x1+oi; y1_y1+nn; BitBltDefs.BITBLT[@BLT.blk]; ENDLOOP; END; FreeBLT[BLT]; END; SetupColorAreaBLT: PUBLIC PROC [BLT: BLTBlockPtr, x1,y1,x2,y2: INTEGER, fn: BitBltDefs.BBoperation, b: BitmapPtr _ NIL] = BEGIN logBitsPerPixel: CARDINAL; IF b = NIL THEN b _ Screen; logBitsPerPixel _ logTable[b.nBitsPerPixel]; x1 _ MAX[0,x1]; y1 _ MAX[0,y1]; x2 _ MIN [x2,INTEGER[b.nBits]-1]; y2 _ MIN[y2,INTEGER[b.nLines]-1]; IF NOT b.portraitMode THEN BEGIN -- rotate by 90 degrees t: INTEGER; t _ (INTEGER[b.nLines]-1)-y1; y1 _ x1; x1 _ (INTEGER[b.nLines]-1)-y2; y2 _ x2; x2 _ t; END; BLT.blk.sourcetype _ gray; BLT.blk.destalt_FALSE; BLT.blk.dlbca _ MakeLongPointer[b.bits,b.bank]; BLT.blk.dbmr _ b.nWords; BLT.blk.dlx _ InlineDefs.BITSHIFT[x1,logBitsPerPixel]; BLT.blk.dty _ y1; BLT.blk.dw _ InlineDefs.BITSHIFT[(x2+1-x1),logBitsPerPixel]; BLT.blk.dh _ (y2+1-y1); BLT.blk.sty _ 0; --DORADO looks here BLT.blk.function _ fn; END; END.