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: 8];
IF NOT scale IN CDVPrivate.ScaleRange THEN scale ← 8;
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 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𡤋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.