-- wiresCreate3.mesa

DIRECTORY SystemDefs:FROM"SystemDefs",
AltoFileDefs:FROM"AltoFileDefs",
DisplayDefs:FROM"DisplayDefs",
GraphicsDefs:FROM"GraphicsDefs",
SegmentDefs:FROM"SegmentDefs",
StreamDefs:FROM"StreamDefs",
StringDefs:FROM"StringDefs",
WiresDefs:FROM"WiresDefs",
PressDefs:FROM"PressDefs",
IODefs:FROM"IODefs";
WiresOutput:PROGRAM
IMPORTS GraphicsDefs, PressDefs, SystemDefs, IODefs, StreamDefs,
StringDefs,WiresDefs
EXPORTS WiresDefs =BEGIN OPEN WiresDefs;

Error:SIGNAL=CODE;
nullLoc: Location=[NULL,127,127];
outFileName: STRING←[40];

--/////////////GRAPHICS//////////////

maxX,maxY: INTEGER;
cornerX,cornerY: CARDINAL;
halfHeight:INTEGER=12000;
halfWidth:INTEGER=8000;
display:BOOLEAN←TRUE;
press:PressDefs.PressFileDescriptor;
Screen:POINTER TO GraphicsDefs.Bitmap;
OldDCB:CARDINAL;
DCBHead: POINTER TO CARDINAL= LOOPHOLE[420B];
MouseButtons: POINTER TO CARDINAL = LOOPHOLE[177030B];
KeyBoard1: POINTER TO CARDINAL = LOOPHOLE[177034B];
KeyBoard2: POINTER TO CARDINAL = LOOPHOLE[177035B];
MouseX: POINTER TO CARDINAL = LOOPHOLE[426B];
MouseY: POINTER TO CARDINAL = LOOPHOLE[427B];

PrintGeometry:PUBLIC PROCEDURE[name:STRING]= BEGIN
tScale: INTEGER←scale;
display←FALSE;
scale← MIN[15000/maxX, 22500/maxY];
cornerY←cornerX←2540;
PressDefs.InitPressFileDescriptor[@press,name];
PlotSegs[];
PressDefs.ClosePressFile[@press];
display←TRUE;
scale←tScale;
END;--print geom

scale:INTEGER;
debugPrint:PUBLIC BOOLEAN←FALSE;
first:PUBLIC BOOLEAN;

PutBox:PUBLIC PROCEDURE[color:Color,x,y,m,n:CARDINAL]=BEGIN
pressWidth: CARDINAL=20000;
pressheight: CARDINAL=25000;
x1,y1,w1,w2:INTEGER;
xul,yul,xlr,ylr: CARDINAL;
IF debugPrint THEN BEGIN
IODefs.WriteChar[SELECT color FROM g=>’g,r=>’r,b=>’b,ENDCASE=>’y];
IODefs.WriteNumber[x,[10,FALSE,TRUE,4]];
IODefs.WriteNumber[y,[10,FALSE,TRUE,4]];
IODefs.WriteNumber[m,[10,FALSE,TRUE,3]];
IODefs.WriteNumber[n,[10,FALSE,TRUE,3]];
IODefs.WriteChar[CR];
RETURN;
END;
IF (m<=1 AND n<=1) OR
m NOT IN [1..1000) OR n NOT IN [1..1000) THEN RETURN;
IF display THEN BEGIN DisplayBox[color,x,y,IF m>1 THEN m+1 ELSE 1,n];
RETURN; END;
IF silFile THEN BEGIN
feat:SilFeature;
t:[0..16)←SELECT color FROM r=>1, g=>3, b=>4, y=>2, ENDCASE=>0;
IF x>77777B THEN x←1;
IF y>77777B THEN y←1;
IF x>500 THEN x←500;
IF y>silYMax THEN y←silYMax-1;
xul←xOrg+scale*x;
xlr← xul+ (IF m>1 THEN scale*m ELSE 1);
ylr← yOrg-scale*y;
yul← ylr - (IF n>1 THEN scale*n ELSE 1);
feat←[macro:177777B,
xUL:[0,xul],
yUL:[0,yul],
xLR:[t,xlr],
yLR:[14,ylr]];
WriteSilFeature[feat];
RETURN;
END;
-- // Default: produce a PRESS file //
SELECT color FROM
r=>PressDefs.SetColor[@press,220,128,255];
g=>PressDefs.SetColor[@press,080,128,255];
b=>PressDefs.SetColor[@press,140,064,255];
y=>PressDefs.SetColor[@press,40,128,255];
none=>PressDefs.SetColor[@press,140,000,000];
ENDCASE;
x1←cornerX+scale*x;
y1←cornerY+scale*y;
w1←scale*(IF m>1 THEN m+1 ELSE 1);
w2←scale*n;
IF x1>pressWidth OR y1>pressheight THEN RETURN;
IF x1+w1>pressWidth THEN w1←pressWidth-x1;
IF y1+w2>pressheight THEN w2←pressheight-y1;
PressDefs.PutRectangle[@press,x1,y1,w1,w2];
END;--PutBox

MakeSilFile:PUBLIC PROCEDURE[s:STRING]= BEGIN OPEN StreamDefs;
outputStream←NewWordStream[s,Write+Append];
outputStream.reset[outputStream];
outputStream.put[outputStream,34562B];
display←FALSE; silFile←TRUE;
PlotSegs[];
display←TRUE; silFile←FALSE;
outputStream.destroy[outputStream];
END;

silFile:PUBLIC BOOLEAN←FALSE;
silYMax:CARDINAL=750;
SilWord:TYPE=RECORD[a:[0..17B],b:[0..7777B]];
SilFeature:TYPE=RECORD[macro:CARDINAL,xUL,yUL,xLR,yLR:SilWord];
outputStream:StreamDefs.DiskHandle;

WriteSilFeature:PROCEDURE[feat:SilFeature]=BEGIN
outputStream.put[outputStream,feat.macro];
outputStream.put[outputStream,feat.xUL];
outputStream.put[outputStream,feat.yUL];
outputStream.put[outputStream,feat.xLR];
outputStream.put[outputStream,feat.yLR];
END;
--
--
Graphics Display Procedures
--
xOrg,yOrg: CARDINAL; --
origin of the image
dxMax:CARDINAL;
dyMax:CARDINAL; --
size of the display screen
smallDisplay:BOOLEAN←FALSE;

StartDisplay
:PUBLIC PROCEDURE= BEGIN --initialize the screen
GraphicsDefs.SetDefaultBitmap[dxMax,dyMax];
OldDCB← DCBHead↑;
Screen ← GraphicsDefs.TurnOnGraphics[];
END;

Display:PUBLIC PROCEDURE= BEGIN
GraphicsDefs.EraseArea[0,0,dxMax,dyMax];
IF scale<1 THEN Error;
PlotSegs[];
END;

ManipulateDisplay:PUBLIC PROCEDURE RETURNS[print:BOOLEAN]= BEGIN
DO SELECT TRUE FROM
BlueButton[] => Display[];
YellowButton[] => -- Reset the scale
BEGIN
scale← (MouseX↑-xOrg)/maxX;
GraphicsDefs.EraseArea[0,0,dxMax,dyMax];
PlotSegs[];
END;
RedButton[] =>
BEGIN
xOrg←MouseX↑;
yOrg←MouseY↑;
GraphicsDefs.EraseArea[0,0,dxMax,dyMax];
PlotSegs[];
END;
KeyBoard1↑= 177757B =>BEGIN print←TRUE; EXIT; END; --p was hit
KeyBoard2↑= 167777B =>BEGIN print←FALSE; EXIT; END; --q was hit
ENDCASE;
ENDLOOP;
TurnOffGraphics[];
DCBHead↑← OldDCB;
[]← IODefs.ReadChar[];
END;

RedButton:PROCEDURE RETURNS[BOOLEAN]= BEGIN
IF (MouseButtons↑ MOD 8) < 4
THEN BEGIN
UNTIL (MouseButtons↑ MOD 8) > 3 DO ENDLOOP;
RETURN [TRUE];
END
ELSE RETURN [FALSE];
END;

BlueButton:PROCEDURE RETURNS[BOOLEAN]= BEGIN
IF (MouseButtons↑ MOD 4) < 2
THEN BEGIN
UNTIL (MouseButtons↑ MOD 4) > 1 DO ENDLOOP;
RETURN [TRUE];
END
ELSE RETURN [FALSE];
END;

YellowButton:PROCEDURE RETURNS[BOOLEAN]= BEGIN
IF (MouseButtons↑ MOD 2) = 0
THEN BEGIN
UNTIL (MouseButtons↑ MOD 2) # 0 DO ENDLOOP;
RETURN [TRUE];
END
ELSE RETURN [FALSE];
END;

TurnOffGraphics:PROCEDURE= BEGIN
DCBHead↑← 0;
SystemDefs.FreeSegment[Screen.bits- 4];
Screen.bits← NIL;
END;


DisplayBox:PROCEDURE[color:Color,x,y,m,n:CARDINAL]=BEGIN
x1,y1,x2,y2: CARDINAL;
x1←xOrg+scale*x;
y1←yOrg-scale*y;
x2←xOrg+scale*(x+m);
y2←yOrg-scale*(y+n);
IF INTEGER[x1]<0 OR INTEGER[x2]<0 OR INTEGER[y1]<0 OR INTEGER[y2]<0
THEN Error;
GraphicsDefs.SetGrayLevel[
SELECT color FROM
y=>14, --light grey
b=>11, --medium grey
g=>7, --dark grey
r=>3, --almost black
ENDCASE=>0 ];
GraphicsDefs.PutGray[x1,y1,x2,y2];
END;--DisplayBox

DoOutputs: PUBLIC PROCEDURE[name:STRING,limitX,limitY:INTEGER]=BEGIN
ch: CHARACTER;
dxMax←dyMax←IF smallDisplay THEN 256 ELSE 608;
maxX←limitX;
maxY←limitY;
xOrg← 8;
yOrg← dyMax-8;
scale← MIN[dxMax/(maxX+16),dyMax/(maxY+16)];
IF scale<1 THEN BEGIN Error; scale←1; END;
IODefs.WriteString["scale="];
IODefs.WriteNumber[scale,[10,FALSE,TRUE,6]];
IODefs.WriteLine[""];
IODefs.WriteString["Type a y to chance the display: "];
ch← IODefs.ReadChar[];
IF ch=’y OR ch =’Y THEN BEGIN
StartDisplay[];
Display[];
[] ← ManipulateDisplay[]; -- This guy sets up the graphic transformation.
END;
-- Note that it will always print.
outFileName.length←0;
StringDefs.AppendString[outFileName,name];
StringDefs.AppendString[outFileName,".press"];
PrintGeometry[outFileName];
outFileName.length←0;
StringDefs.AppendString[outFileName,name];
StringDefs.AppendString[outFileName,".sil"];
MakeSilFile[outFileName];
END;

END..

altoYMax:CARDINAL=1000;
SilFile:TYPE=RECORD[password:CARDINAL,data:ARRAY MANY OF SilFeature];
SilFeature:TYPE=RECORD[
macro:CARDINAL,
null:[4-bits], x:[12-bits],
null:[4-bits], yMax:[16 bits],
color:[4-bits], xMax:[12-bits],
font:[4-bits], y:[12-bits]]

password must be 34562B or 34563B
macro must be 177777B
Color:{xx,red,yellow,green,blue,xx,xx,xx,xx,orange,xx,xx,xx,xx,xx,xx}
y is measured down from the upper left corner!
font must be 14 (font<14 is a bcpl format string following, to be ignored)

Press colors: Red=0, Yellow=40, Green=80, Cyan=120, Blue=160,
Magenta=200, Red=240