-- 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