<> <> <> DIRECTORY Buttons, CD, CDDraw, CDValue, CDVPrivate, PrincOpsUtils, UserProfile; CDVInit: CEDAR MONITOR IMPORTS Buttons, CDDraw, CDValue, CDVPrivate, PrincOpsUtils, UserProfile EXPORTS CDVPrivate = BEGIN MyGraphicRef: TYPE = CDVPrivate.MyGraphicRef; MyGraphicRec: TYPE = CDVPrivate.MyGraphicRec; linkBase: PUBLIC MyGraphicRef _ NIL; InitDesignRec: PROC [me: MyGraphicRef] = BEGIN FOR l: MyGraphicRef _ linkBase, l.link WHILE l#NIL DO IF me.actualDesign=l.actualDesign THEN { me.designRec _ l.designRec; RETURN }; ENDLOOP; me.designRec _ NEW[CDVPrivate.PrivatePerDesign]; CDVPrivate.SetCursorMode[me, cShadow]; END; NewAndLink: PUBLIC ENTRY PROC [design: CD.Design] RETURNS [MyGraphicRef] = BEGIN scale, grid: INT; me: MyGraphicRef ~ NEW[MyGraphicRec]; me.link _ linkBase; me.actualDesign _ design; <<----->> InitDesignRec[me]; <<--further initializations>> scale _ CDValue.FetchInt[boundTo: design, key: $CDxInitScale, propagation: global, ifNotFound: 6]; IF NOT scale IN CDVPrivate.ScaleRange THEN scale _ 6; grid _ CDValue.FetchInt[boundTo: design, key: $CDxInitGrid, propagation: global, ifNotFound: CD.lambda]; grid _ MIN[MAX[grid, 0], 256]; SetScale[me, scale, grid, [0,0]]; me.stoprequest _ NEW[BOOLEAN]; linkBase _ me; me.suppressOutsidePushedCell _ CDValue.FetchInt[design.technology, $CDxDrawMode, global]=1; RETURN [me] END; UnLink: PUBLIC ENTRY PROC [me: MyGraphicRef] = BEGIN IF linkBase=NIL THEN ERROR; IF me=linkBase THEN {linkBase_linkBase.link; RETURN}; FOR l: MyGraphicRef _ linkBase, l.link WHILE l#NIL DO IF l.link=me THEN {l.link_l.link.link; RETURN} ENDLOOP; ERROR END; SetScale: PUBLIC PROC [me: MyGraphicRef, scale: INTEGER, grid: CARDINAL, noff: CD.DesignPosition] = BEGIN <<--explanation of crazy scaling procedure for ScaleViewerToDesign>> <<--v * scale + offset :: ideal>> <<--v* s1/s2 + offset :: integer arithmetic>> <<--(v*s1 + s2/2) / s2 + offset :: correct round of screen point>> <<--( (v*s1 + s2/2) / s2) + grid/2) / grid * grid + offset :: introduce grid>> <<--(v*s1 + s2/2 + grid/2*s2 ) / s2 / grid * grid + offset >> <<--(v*s1 + s2/2 + grid/2*s2 ) / (s2*grid) * grid + offset>> <<>> scaleE: ARRAY CDVPrivate.ScaleRange OF INTEGER = [24, 16, 12, 8, 6, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; scaleF: ARRAY CDVPrivate.ScaleRange OF INTEGER = [1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]; scaleS: ARRAY CDVPrivate.ScaleRange OF INTEGER = [0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]; scale _ MIN[MAX[0, scale], CDVPrivate.scaleNum-1]; grid _ MAX[1, grid]; me.nscale _ scale; me.ngrid _ grid; me.sE _ scaleE[scale]; me.sF _ scaleF[scale]; me.sA _ me.sF; me.sShift _ scaleS[scale]; me.sB _ (grid/2)*me.sE+me.sE/2; me.sC _ me.sE*grid; me.sD _ grid; me.noff.x _ noff.x/me.ngrid*me.ngrid; me.noff.y _ noff.y/me.ngrid*me.ngrid END; <<-------------------------------->> CatchAny: PROC [b: BOOL] = { catchAny_b; IF catchAny THEN catchAnyWhichDeadlock_TRUE }; CatchAnyWhichDeadlock: PROC [b: BOOL] = { catchAnyWhichDeadlock_b; IF ~catchAnyWhichDeadlock THEN catchAny_FALSE }; catchAny: PUBLIC BOOL _ TRUE; catchAnyWhichDeadlock: PUBLIC BOOL _ TRUE; NoteProfileChange: UserProfile.ProfileChangedProc = <<-- PROC [reason: ProfileChangeReason]>> BEGIN catchAny _ UserProfile.Boolean["Chipndale.CatchLowLevelErrors", TRUE]; catchAnyWhichDeadlock _ catchAny OR UserProfile.Boolean["Chipndale.CatchErrorsWhichCauseDeadlock", TRUE] END; -------------------------------- ColorTable: TYPE = CDVPrivate.ColorTable; Brick: TYPE = CDVPrivate.Brick; whiteBrick: REF Brick = NEW[Brick_ALL[0]]; blackBrick: REF Brick = NEW[Brick_ALL[LAST[CARDINAL]]]; colorTableBW: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[blackBrick]]; colorTable4: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[blackBrick]]; colorTable8: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[blackBrick]]; greyTableBW: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[whiteBrick]]; greyTable4: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[whiteBrick]]; greyTable8: PUBLIC REF ColorTable _ NEW[ColorTable_ALL[whiteBrick]]; GetColorTable: PROC[bpp: CARDINAL] RETURNS [REF ColorTable] = BEGIN RETURN [IF bpp=1 THEN colorTableBW ELSE IF bpp=4 THEN colorTable4 ELSE IF bpp=8 THEN colorTable8 ELSE ERROR ]; END; TeachColor: PUBLIC PROC [lev: CD.Level, bpp: CARDINAL, brick: Brick] = BEGIN GetColorTable[bpp]^[lev] _ NEW[Brick_brick]; GetGreyTable[bpp]^[lev] _ whiteBrick; END; GetGreyTable: PROC[bpp: CARDINAL] RETURNS [REF ColorTable] = BEGIN RETURN [IF bpp=1 THEN greyTableBW ELSE IF bpp=4 THEN greyTable4 ELSE IF bpp=8 THEN greyTable8 ELSE ERROR ]; END; TeachGrey: PUBLIC PROC [lev: CD.Level, bpp: CARDINAL, brick: Brick] = BEGIN GetGreyTable[bpp]^[lev] _ NEW[Brick_brick]; END; TeachColorCode: PUBLIC PROC[lev: CD.Level, bpp: CARDINAL, code: CARDINAL] = <<--sets value into the default Color- and GreyTable >> BEGIN TeachColor[lev, bpp, GetChipmonkColor[code]]; TeachGrey[lev, bpp, GetChipmonkMaskGrey[code]]; END; GetChipmonkColor: PROC [c: CARDINAL] RETURNS [Brick] = TRUSTED BEGIN IF c>255 THEN { --two colors in alteration combin: CARDINAL = PrincOpsUtils.BITAND[255, c]; pat1: CARDINAL = combin+PrincOpsUtils.BITSHIFT[combin, 8]; pat2: CARDINAL = PrincOpsUtils.BITOR[PrincOpsUtils.BITSHIFT[pat1, 4], PrincOpsUtils.BITSHIFT[pat1, -4]]; RETURN [[pat1, pat2, pat1, pat2]] } ELSE { pixCol: CARDINAL = PrincOpsUtils.BITAND[15, c]; halfcw: CARDINAL = PrincOpsUtils.BITOR[PrincOpsUtils.BITSHIFT[pixCol, 4], pixCol]; cw: CARDINAL = PrincOpsUtils.BITOR[PrincOpsUtils.BITSHIFT[halfcw, 8], halfcw]; <<--pixCol replicated 4 times>> SELECT c-pixCol FROM 0 => RETURN[ALL[cw]]; -- every pixel set to pixCol ENDCASE => { m: Brick _ GetChipmonkMaskGrey[c]; FOR i: [0..4) IN [0..4) DO m[i] _ PrincOpsUtils.BITAND[m[i], cw] ENDLOOP; RETURN [m] } } END; GetChipmonkMaskGrey: PROC [c: CARDINAL] RETURNS [Brick] = TRUSTED BEGIN pixCol: [0..16) = PrincOpsUtils.BITAND[15, c]; RETURN [SELECT c-pixCol FROM 16 => [7400B, 7400B, 17B, 17B], <> <<-- .*..>> <<-- .*..>> <<-- ...*>> <<-- ...*>> 32 => [7417B, 170360B, 7417B, 170360B], <<-- .*.*>> <<-- *.*.>> <<-- .*.*>> <<-- *.*.>> 48 => [7400B, 7400B, 0, 0], <<-- .*..>> <<-- .*..>> <<-- ....>> <<-- ....>> 64 => [170377B, 177760B, 170377B, 177760B], <<-- *.**>> <<-- ***.>> <<-- *.**>> <<-- ***.>> ENDCASE => ALL[177777B] -- all bits --]; END; -------------------------------- InitShades: PROC [] = { CDVPrivate.TeachColor[CD.highLightShade, 1, [101H,0,0,0]]; CDVPrivate.TeachColor[CD.highLightShade, 4, [0,0F0FH,0,0]]; CDVPrivate.TeachColor[CD.highLightShade, 8, [0,255,0,255]]; CDVPrivate.TeachColor[CD.highLightError, 1, [101H,0,101H,0]]; CDVPrivate.TeachColor[CD.highLightError, 4, [0,0F0FH,0,0F0FH]]; CDVPrivate.TeachColor[CD.highLightError, 8, [0,255,255,255]]; }; StopDrawing: Buttons.ButtonProc = BEGIN FOR l: MyGraphicRef _ linkBase, l.link WHILE l#NIL DO IF l.ct#NIL THEN CDDraw.FlushCommands[l.ct] ENDLOOP; END; stop: Buttons.Button _ Buttons.Create[[name: "CD-stop"], StopDrawing]; InitShades[]; UserProfile.CallWhenProfileChanges[NoteProfileChange]; CDValue.StoreInt[boundTo: NIL, key: $CDxInitGrid, value: CD.lambda]; END.