CDVInit.mesa
by Christian Jacobi August 5, 1983 11:07 am
last edited by Christian Jacobi October 14, 1983 5:57 pm
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𡤋
IF catchAny THEN catchAnyWhichDeadlock←TRUE
};
CatchAnyWhichDeadlock: PROC [b: BOOL] = {
catchAnyWhichDeadlock𡤋
IF ~catchAnyWhichDeadlock THEN catchAny←FALSE
};
catchAny: PUBLIC BOOLTRUE;
catchAnyWhichDeadlock: PUBLIC BOOLTRUE;
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𡤋rick];
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𡤋rick];
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],
The pattern
-- .*..
-- .*..
-- ...*
-- ...*
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.