ChipmonkPatterns.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
by Ch. Jacobi October 22, 1984 12:22:09 pm PDT
last edited Christian Jacobi October 22, 1984 12:22:15 pm PDT
DIRECTORY
Basics,
CD,
CDColors,
CDIO,
CDMenus,
CDSequencer,
CDViewer,
Commander USING [CommandProc, Register],
Convert,
FS,
IO,
Rope,
TerminalIO,
UserProfile,
ViewerOps;
ChipmonkPatterns: CEDAR MONITOR
IMPORTS Basics, CD, CDColors, CDIO, CDMenus, CDSequencer, CDViewer, Commander, Convert, IO, FS, Rope, TerminalIO, UserProfile, ViewerOps =
BEGIN
Brick: TYPE = CDColors.Brick;
level: TYPE = [0..15];
LevelTable: TYPE = ARRAY level OF LIST OF CD.Level;
techList: LIST OF CD.Technology ← NIL;
levelTable: REF LevelTable = NEW[LevelTable←ALL[NIL]];
InitPatternsFromProfile: PROC [comm: CDSequencer.Command] =
--for this procedure comm is completely ignored and may be NIL
BEGIN
patNo: INT ← UserProfile.Number[key: "Chipndale.ChipmonkColorPatternNum", default: 0];
IF patNo#0 THEN {
ReadPatternFile[];
SetChipmonkPatterns[patNo]
}
END;
colPatNum: CARDINAL=8;
colPatRead: CARDINAL𡤀
colPatternTabs: ARRAY [0..colPatNum) OF ARRAY level OF CARDINAL;
colPatternBits: ARRAY [0..colPatNum) OF CARDINAL;
orLTab: ARRAY level OF CARDINAL ← [11B, 1, 4, 2, 76B, 8, 33B, 10, 9, 1, 10, 62B, 10, 8, 10, 10];
SetChipmonkPatterns: PROC [i: INT] =
BEGIN
done: BOOLFALSE;
IF i<0 THEN {
FOR j: NAT IN [0..colPatRead) DO
IF colPatternBits[j]=(-i) THEN {i←j; EXIT}
ENDLOOP
};
IF i>=2 AND i<colPatRead+2 THEN {
FOR j: [0..15] IN [0..15] DO
TeachColorCode[levelTable[j], colPatternTabs[i-2][j]]
ENDLOOP;
done ← TRUE
}
ELSE IF i=1 THEN {
FOR j: [0..15] IN [0..15] DO
TeachColorCode[levelTable[j], orLTab[j]];
ENDLOOP;
done ← TRUE
}
ELSE IF i=0 THEN TerminalIO.WriteRope["Resetting default not with this command\n"]
ELSE TerminalIO.WriteRope["pattern not found\n"];
IF done THEN {
TerminalIO.WriteRope["Pattern reset; ..don't forget the color map\n"];
RepaintViewers[];
};
END;
RepaintViewers: PROC [] =
BEGIN
FOR tList: LIST OF CD.Technology ← techList, tList.rest WHILE tList#NIL DO
FOR l: CDViewer.ViewerList ← CDViewer.ViewersOf[tList.first], l.rest WHILE l#NIL DO
IF l.first.column=color THEN ViewerOps.PaintViewer[l.first, client]
ENDLOOP;
ENDLOOP
END;
CMPatternCommand: Commander.CommandProc =
BEGIN
patNum: INT ← -1;
patFile: Rope.ROPENIL;
InitATechnology[CD.FetchTechnology[$nmos]];
InitATechnology[CD.FetchTechnology[$cmos]];
IF cmd#NIL THEN {
s: IO.STREAM ~ IO.RIS[cmd.commandLine];
DO
token: Rope.ROPEIO.GetTokenRope[s ! IO.EndOfStream => EXIT].token;
IF Rope.IsEmpty[token] THEN EXIT;
IF Rope.Fetch[token, 0] IN ['0..'9] THEN {
patNum ← Convert.IntFromRope[token ! Convert.Error => EXIT];
}
ELSE IF Rope.Fetch[token, 0]='* THEN {
InitPatternsFromProfile[NIL];
RETURN
}
ELSE patFile ← CDIO.MakeName[token, "CDColorPatterns"];
ENDLOOP;
};
IF colPatRead=0 OR NOT Rope.IsEmpty[patFile] THEN ReadPatternFile[patFile];
IF patNum<0 THEN {
TerminalIO.WriteRope["type color pattern; [ <="];
TerminalIO.WriteInt[colPatRead+1];
TerminalIO.WriteRope["]; (on default file often used: cmos: 3, nmos: 2) > "];
patNum ← TerminalIO.RequestInt["" ! TerminalIO.UserAbort => GOTO UserAbort];
};
SetChipmonkPatterns[patNum]
EXITS
UserAbort => {NULL};
END;
ReadPatternFile: PROC[fileName: Rope.ROPENIL] =
BEGIN
binfile: IO.STREAM;
k, i, lv: CARDINAL;
GetByte: PROC [] RETURNS[c: [0..255]] = INLINE {
c ← LOOPHOLE[IO.GetChar[binfile], [0..255]];
};
Get2Bytes: PROC [] RETURNS [c: CARDINAL] = INLINE {
h: [0..255] = GetByte[];
c ← h*256+GetByte[];
};
IF Rope.IsEmpty[fileName] THEN
fileName ← UserProfile.Token[
key: "Chipndale.ChipmonkColorPatterns",
default: "default.CDColorPatterns"
];
fileName ← CDIO.MakeName[fileName, "CDColorPatterns"];
binfile ← FS.StreamOpen[fileName ! FS.Error =>
IF error.group # bug THEN {
TerminalIO.WriteRope[fileName];
TerminalIO.WriteRope[" not opened: "];
TerminalIO.WriteRope[error.explanation];
TerminalIO.WriteLn[];
GOTO FileName
}];
k ← MIN[colPatNum, Get2Bytes[]];
colPatRead ← 0;
FOR i IN [0..k) DO
colPatternBits[i]←Get2Bytes[];
FOR lv IN level DO
colPatternTabs[i][lv]←Get2Bytes[];
ENDLOOP;
ENDLOOP;
colPatRead←k;
IO.Close[binfile];
EXITS
FileName => {NULL};
END;
TeachColorCode: PROC[levels: LIST OF CD.Level, code: CARDINAL] =
--sets value into the default Color- and GreyTable
BEGIN
FOR list: LIST OF CD.Level ← levels, list.rest WHILE list#NIL DO
CDColors.DefineColor[list.first, NEW[Brick←GetChipmonkColor[code]], bit4];
CDColors.DefineColor[list.first, NEW[Brick←GetChipmonkMaskGrey[code]], bit4, grey];
ENDLOOP
END;
GetChipmonkColor: PROC [c: CARDINAL] RETURNS [Brick] =
TRUSTED BEGIN
IF c>255 THEN { --two colors in alteration
combin: CARDINAL = Basics.BITAND[c, 255];
pat1: CARDINAL = combin+Basics.BITSHIFT[combin, 8];
pat2: CARDINAL = Basics.BITOR[Basics.BITSHIFT[pat1, 4], Basics.BITSHIFT[pat1, -4]];
RETURN [[pat1, pat2, pat1, pat2]]
}
ELSE {
pixCol: CARDINAL = Basics.BITAND[15, c];
halfcw: CARDINAL = Basics.BITOR[Basics.BITSHIFT[pixCol, 4], pixCol];
cw: CARDINAL = Basics.BITOR[Basics.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] ← Basics.BITAND[m[i], cw]
ENDLOOP;
RETURN [m]
}
}
END;
GetChipmonkMaskGrey: PROC [c: CARDINAL] RETURNS [Brick] =
TRUSTED BEGIN
pixCol: [0..16) = Basics.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;
InitATechnology: ENTRY PROC [tech: CD.Technology] =
BEGIN
Entry: PROC[key: ATOM, number: NAT] =
BEGIN
lev: CD.Level ← CD.FetchLevel[tech, key];
IF lev#CD.combined THEN levelTable[number] ← CONS[lev, levelTable[number]]
END;
IF tech=NIL THEN RETURN;
FOR tList: LIST OF CD.Technology ← techList, tList.rest WHILE tList#NIL DO
IF tList.first=tech THEN RETURN
ENDLOOP;
techList ← CONS[tech, techList];
Entry[$cut, 0];
Entry[$dif, 1]; Entry[$ndif, 1];
Entry[$pol, 2];
Entry[$met, 3];
Entry[$imp, 4]; Entry[$imp0, 4]; Entry[$impWeak, 4];
Entry[$ovg, 5];
Entry[$bur, 6];
Entry[$snerd, 7];
Entry[$cut2, 8];
Entry[$pdif, 9];
Entry[$pwelCont, 10];
Entry[$met2, 11];
Entry[$pwel, 12];
Entry[$nwel, 13];
Entry[$nwelCont, 14];
Entry[$NOcOL, 15];
END;
ColorPatterns: CDSequencer.CommandProc = {[] ← CMPatternCommand[NIL]};
Commander.Register[
key: "CDPatterns",
proc: CMPatternCommand,
doc: "Read chipndale color patterns"
];
InitATechnology[CD.FetchTechnology[$nmos]];
InitATechnology[CD.FetchTechnology[$cmos]];
InitPatternsFromProfile[NIL];
CDSequencer.ImplementCommand[$InitColorPatternsFromProfile, InitPatternsFromProfile,, doQueue];
CDSequencer.ImplementCommand[$ColorPatterns, ColorPatterns,, doQueue];
CDMenus.CreateEntry[$DisplayMenu, "type cm pattern", $ColorPatterns];
CDMenus.CreateEntry[$DisplayMenu, "profile cm pattern", $InitColorPatternsFromProfile];
END.