-- ReplicateMain.mesa
-- a program to run within Chipmonk
-- modified by E. McCreight, February 23, 1982 11:36 AM
-- written by E. McCreight, September 23, 1981 6:57 PM
DIRECTORY
ChipUserInt,
ppddefs,
ppdefs,
RomMakerDefs;
ReplicateMain: PROGRAM
IMPORTS ChipUserInt, ppddefs, ppdefs, RomMakerDefs =
BEGIN OPEN ChipUserInt, ppddefs, ppdefs, RomMakerDefs;
-- C e l l - R e l a t e d a n d P r o c e d u r e s
Offset: PROCEDURE[p: Point ← [0, 0],
cell: listPtr ← NIL, cellSize: Point ← [0,0],
dir: Direction, rep: Point ← [0, 0],
midCell: listPtr ← NIL, midCellSize: Point ← [0,0],
midGap: Point ← [0, 0], includeTerminalMid: BOOLEAN ← TRUE]
RETURNS [Point] =
BEGIN
midRep: Point ← IF includeTerminalMid THEN rep ELSE
[x: rep.x-1, y: rep.y-1];
IF cell#NIL THEN cellSize ← CellSize[cell.ob];
midCellSize ← IF midCell#NIL THEN CellSize[midCell.ob, dir]
ELSE DirSize[midCellSize, dir];
RETURN[[x: p.x+rep.x*DirSize[cellSize, dir].x+
MidCellRep[midGap.x, midRep.x, cellSize.x]*
midCellSize.x,
y: p.y+rep.y*DirSize[cellSize, dir].y+
MidCellRep[midGap.y, midRep.y, cellSize.y]*
midCellSize.y]];
END;
CellsPerGap: PROCEDURE[gap, sizePerCell: locNum] RETURNS[INTEGER] =
{RETURN[(gap+sizePerCell-1)/sizePerCell] -- ceiling --};
MidCellRep: PROCEDURE[gap, nCells, sizePerCell: locNum] RETURNS[INTEGER] =
BEGIN
cellsPerGap: INTEGER ← CellsPerGap[gap, sizePerCell];
RETURN[IF cellsPerGap=0 THEN 0 ELSE nCells/cellsPerGap];
END;
PlaceList: PROCEDURE[to: listPtr ← NIL, lp: listPtr, cellSize: Point,
rep: Point ← [0,0], midCellSize: Point ← [0,0],
midGap: Point ← [0,0]] RETURNS[listPtr] =
BEGIN
cp: Point ← Offset[cellSize: cellSize, dir: diagonal, rep: rep,
midCellSize: midCellSize, midGap: midGap];
WHILE lp#NIL DO
to ← copyObject[lp: lp, mp: to, xoff: cp.x, yoff: cp.y];
lp ← lp.nxt;
ENDLOOP;
RETURN[to];
END;
-- M a i n P r o g r a m
BEGIN
ENABLE
BEGIN
Punt => GOTO Exit; -- for exits
UNWIND => ColorOn[];
END;
hRep, vRep, hSize, vSize: locNum;
selRect, boundary: Rect;
selList, selListTail, copyList: listPtr ← NIL;
useBoundingBox: BOOLEAN;
lpp: LONG POINTER TO listPtr;
ColorOff[];
hRep ← RequestInteger["Replicate selected items"L,
"How many times horizontally?"L];
vRep ← RequestInteger["Replicate selected items"L,
"How many times vertically?"L];
IF NOT (useBoundingBox ←
HeSaysYes["Should I take the pitch from the"L,
"bounding box of the selected items?"L]) THEN
BEGIN
IF HeSaysYes["OK, then should I take the pitch from the"L,
"gap between mark and cursor?"] THEN
{hSize ← xx-markPnt.x; vSize ← yy-markPnt.y}
ELSE {Explain["That's all I know how to do!"L]; GOTO Exit};
END;
lpp ← @masterList;
WHILE lpp↑#NIL DO
IF lpp↑.selected THEN
BEGIN
lp: listPtr ← lpp↑;
lpp↑ ← lp.nxt;
lp.nxt ← selList;
selRect ← IF selList=NIL THEN getRect[lp] ELSE
mergeRects[selRect, getRect[lp]];
selList ← lp;
IF selListTail=NIL THEN selListTail ← lp;
END
ELSE lpp ← @lpp↑.nxt;
ENDLOOP;
IF selList=NIL THEN
{Explain["No selections!"L]; GOTO Exit};
IF useBoundingBox THEN
{hSize ← selRect.x2-selRect.x1; vSize ← selRect.y2-selRect.y1};
FOR h: locNum IN [0..hRep) DO FOR v: locNum IN [0..vRep) DO
IF h#0 OR v#0 THEN
BEGIN
copyList ← PlaceList[to: copyList, lp: selList,
cellSize: [x: hSize, y: vSize], rep: [x: h, y: v]];
END;
ENDLOOP ENDLOOP;
selListTail.nxt ← copyList;
copyList ← NIL;
boundary ← getRect[selList];
WHILE selList#NIL DO
lp: listPtr ← selList;
selList ← lp.nxt;
lp.selected ← TRUE;
boundary ← mergeRects[boundary, getRect[lp]];
masterList ← insertList[masterList, lp];
ENDLOOP;
reDrawRect[boundary, 0, TRUE, TRUE, FALSE];
EXITS Exit => NULL;
END;
-- give back all the storage we allocated
ColorOn[];
anyChanges ← sinceIOchanges ← TRUE;
END. -- of ReplicateMain