// May 3, 1978 11:35 AM *** RESIDENT - MAIN ***
//Edited by Lyle Ramshaw September 2, 1980 10:24 PM:
// Played with centering computation
//loading instructions are in Draw.ld; at one point, they were:
// BLDR/F/B/R 1100/N 725/W DRAW/S ↑
// ZPEDIT ZPUTIL ZPBLOCK SPLINE1 (or SPLINE2, SPLINE3, etc) MICROFLOAT ↑
// C/Q ZPINTER ZPDRAW ZPTEXT ZPMAKE ZPCONVERT ZPCOLOR ZPFONT ↑
// B/Q ZPINIT1 ZPINIT2 ZPFONTIO READUSERCMITEM ↑
// E/Q MICROFLOATMC READPRAM ↑
// B/P DRAWOV1/B ZPDISP ZPUPDATE ZPITEM ↑
// B/P DRAWOV2/B ZPDISP ZPIO ZPFONTIO ZPADJUST ZPARROWS ↑
// B/P DRAWOV3/B ZPDISP ZPFREEHAND ↑
// C/P DRAWOV4/B ZPPRESS ZPOBJECT1 ZPOBJECT2 ZPPIECE ZPPUTS ZPARROWS TIMECONVA TIMECONVB TIMEIO ↑
// C/P DRAWOV5/B ZPINTER ZPDRAW ZPTEXT ZPMAKE ZPCONVERT ZPCOLOR ZPFONT
// WARNING: THE OVERLAY PATTERN IS COMPLICATED
// There are TWO overlay base addresses:
// B: overlays 1, 2, 3
// -all overlays contain ZPDISP
// -the rest of overlay 3 (freehand) is used for STORAGE (sample buffer)
// C: overlays 4, 5
// -a copy of overlay 5 is also loaded with the initialization code
get "zpDefs.bcpl"
get "zpComDf.bcpl"
// outgoing procedure
external [
drawMain
drawFinish
grid
]
// incoming procedures:
external [
// *** RESIDENT ***
OpenFile // SYSTEM
Zero
obtainBlock // ZPBLOCK
putBlock
overlay
makeText // ZPTEXT
rewriteText
turnTextOn
turnTextOff
incTextBuffer
decTextBuffer
refreshTextBuffer
confirm // ZPUTIL
typeForm
getInteger
getLine
changeCursor // ZPINTER
makeTextCursor
getEventRegular
curveHitDetect
textHitDetect
paintSpline // ZPCOLOR
paintText
setColorMode
// *** "UNDERLAY" ***
drawJunta // ZPINIT
// *** OVERLAYS ***
createSpline // ZPUPDATE (overlay)
createCyclicSpline
redrawSpline
dashSpline
addNewKnot
backUp
startAgain
clearSelection
deleteSelection
addSplineSelection
addTextSelection
selectAll
prepareTransform
clearTransform
DTTitems // ZPITEM
unDTTitems
addItemTable
refreshDisplay // ZPDISP
menuDisplay
wipeDisplay
gridDisplay
frameDisplay
drawFreeHand // ZPFREEHAND (overlay)
getEventFreeHand
freeHandCursor
readPicture // ZPIO (overlay)
writePicture
writeStatistics
writeBitmap
changeTextMode
readHelp
readFont
writePressFile // ZPPRESS (overlay)
]
// outgoing statics:
external [
@posTextMode
@showGrid
@currentTextId
@colorOn
]
static[
@posTextMode=posTextCenter
@showGrid=0
@currentTextId=0
@colorOn=0
]
// incoming statics:
external [
fpSysDir // SYSTEM
@bitmap // ZPINIT
@bitmapSize
@Xmax
@Ymax
@gridSpacing
@fontFile
@dspFont
@font
@brush
@color
@maxSplineID
@maxTextID
@splineTable
@textTable
@deletionTable
@transformXYtable
@transformModeTable
@commandTable
@actionTable
@textOK
@textString
@textWidth
@textHeight
@help // ZPIO
]
// local statics:
static [
@command=CMmake
@freeHandMode=false
@getEvent
@pictureSaved=false
@videoOn=false
]
//*****************************************************************
// main editing loop
//*****************************************************************
let drawStart(loadVec, nil, cfa) be [drawStart
drawJunta(loadVec, cfa)
]drawStart
and drawFinish() be [drawFinish
@ lvDisplayHeader=0
for i=1 to 1000 do [ let t=nil ]
]drawFinish
and drawMain() be [drawMain
//initialize main loop
unless overlay(updateOverlay) then finish
getEvent=getEventRegular
freeHandMode=false
colorOn=false
refreshDisplay()
turnTextOff()
let p=nil
let h=vec HITPOINTblockSize
changeCursor(makeCursor)
[mainloop
if (command eq CMfreeHand) & not freeHandMode then setFreeHandMode()
let event=getEvent(h)
let eventSwitch=event<<EVENT.switch
let eventCode=event<<EVENT.code
let doCommand=command
unless eventSwitch then [
let commandEntry=commandTable!(eventCode)
doCommand=commandEntry<<COMMAND.com
if commandEntry<<COMMAND.end then
switchon (actionTable!command)<<ACTION.end into [
case EAnothing:
endcase
case EAmake:
createSpline()
endcase
case EAcyclic:
createCyclicSpline()
commandTable!escKey=CMmake+changeCommand
endcase
case EAstartAgain:
startAgain()
endcase
case EAtext:
currentTextId=0
endcase
case EAfreeHand:
if doCommand ne CMfreeHand then [
overlay(updateOverlay)
getEvent=getEventRegular
freeHandMode=false
]
endcase
]
if commandEntry<<COMMAND.change then
command=doCommand
]
let action=eventSwitch ?
(actionTable!doCommand)<<ACTION.switch,
(actionTable!doCommand)<<ACTION.begin
switchon action into [
case CAnothing:
loop
case BAmake:
changeCursor(makeCursor)
loop
case BAcyclic:
changeCursor(cyclicCursor)
commandTable!escKey=CMcyclic+changeCommand
loop
case SWaddKnot:
p=whichPoint(eventSwitch, h)
if p then addNewKnot(p>>HITPOINT.x, p>>HITPOINT.y)
loop
case CAbackUp:
backUp()
loop
case CAstartAgain:
startAgain()
loop
case BAdelete:
changeCursor(deleteCursor)
loop
case SWdelete:
apply(eventSwitch, h, prepareSplineDelete, prepareTextDelete)
DTTitems(deletionTable)
deletionTable!0=0
loop
case CAundelete:
unDTTitems()
loop
case CAchar:
incTextBuffer(eventCode)
loop
case CAdelChar:
decTextBuffer()
loop
case BAtext:
turnTextOn()
makeTextCursor()
loop
case SWtext:
unless textOK loop
p=whichPoint(eventSwitch, h)
if p then [
textPosition(p)
currentTextId=makeText(textString,
p>>HITPOINT.x, p>>HITPOINT.y, font, color)
]
loop
case BAselect:
changeCursor(selectCursor)
clearSelection()
loop
case BAselectAll:
selectAll()
loop
case SWselect:
apply(eventSwitch, h, addSplineSelection, addTextSelection)
loop
case CAdelSelection:
deleteSelection()
loop
case BAmTransf2:
case BAcTransf2:
case BAmTransf4:
case BAcTransf4:
case BAmTransf6:
case BAcTransf6:
changeCursor(transfCursor0+action-BAmTransf2)
transformXYtable>>XYTABLE.mode=transformModeTable!(action-BAmTransf2)
clearTransform()
loop
case SWtransform:
p=whichPoint(eventSwitch, h)
if p then prepareTransform(p>>HITPOINT.x, p>>HITPOINT.y)
loop
case CAshowGrid:
showGrid=not showGrid
gridDisplay(gridSpacing)
loop
case CAquit:
if confirm("*NQuit ? ") then [
camera>>CAMERA.insideMode=altoOnly
finish
]
loop
case CAplot:
plot()
loop
case CAread:
case CAwrite:
case CAtextMode:
case CAstatistics:
splineIO(action)
loop
case CAbitmap:
frameDisplay(0)
splineIO(CAbitmap)
frameDisplay(1)
loop
case CAreadFont:
splineIO(CAreadFont)
updateFontStuff()
loop
case CAbrush:
brush<<BRUSH.shape=event-menuCode-1
case CAthickness:
if action eq CAthickness then
brush<<BRUSH.thickness=event-(menuCode+symbolCount+1)
menuDisplay()
if freeHandMode then freeHandCursor()
loop
case CAfont: [
let menuNumber=event-menuCode
let newFont=(menuNumber le symbolCount) ? menuNumber-symbolCount+1,
menuNumber-2*symbolCount+3
if newFont eq dspFont %
fontFile>>FONTFILE.length↑newFont ne 0 then [
font=newFont
updateFontStuff()
]
loop
]
case BAredraw:
changeCursor(brushCursor)
loop
case SWredraw:
apply(eventSwitch, h, redrawSpline, rewriteText)
loop
case BAdash:
changeCursor(dashCursor)
loop
case SWdash:
apply(eventSwitch, h, dashSpline, 0)
loop
case BApaint:
setColorMode(event-menuCode)
endcase
case SWpaint:
apply(eventSwitch, h, paintSpline, paintText)
endcase
case CAcolorOnOff:
colorOn=not colorOn
case CArefresh:
refreshDisplay()
loop
case BAfreeHand:
setFreeHandMode()
loop
case SWfreeHand:
drawFreeHand()
loop
case CAvideo:
camera>>CAMERA.insideMode= videoOn ? altoOnly, altoAndCamera
videoOn= not videoOn
loop
case CAhelp:
helpMode()
loop
case CAmoreHelp:
if help then getHelp()
loop
default:
loop
]
]mainloop repeat
]drawMain
and updateFontStuff() be [updateFontStuff
menuDisplay()
refreshTextBuffer()
if command eq CMtext then makeTextCursor()
]updateFontStuff
and setFreeHandMode() be [setFreeHandMode
overlay(freeHandOverlay)
getEvent=getEventFreeHand
freeHandMode=true
freeHandCursor()
]setFreeHandMode
//*****************************************************************
// deletion
//*****************************************************************
and prepareSplineDelete(id) = addItemTable(deletionTable, id)
and prepareTextDelete(id) = addItemTable(deletionTable, id+textFlag)
//*****************************************************************
// x y stuff
//*****************************************************************
and whichPoint(eventSwitch, h) = valof [whichPoint
// h is a HITPOINT vector
// resultis is 0, or h (modified)
switchon eventSwitch into [
case 1:
resultis h
case 2:
test curveHitDetect(h) % textHitDetect(h)
ifso resultis h
ifnot resultis 0
case 3:
h>>HITPOINT.x=grid(h>>HITPOINT.x)
h>>HITPOINT.y=grid(h>>HITPOINT.y)
resultis h
default:
resultis 0
]
]whichPoint
and textPosition(p) be [textPosition
// p is a HITPOINT vector
let tw2, th2=(textWidth+1)/2, textHeight/2
p>>HITPOINT.x=p>>HITPOINT.x +1 - selecton posTextMode into [
case posTextCenter: tw2;
case posTextTop: tw2;
case posTextBottom: tw2;
case posTextLeft: 0;
case posTextRight: textWidth
]
p>>HITPOINT.y=p>>HITPOINT.y + selecton posTextMode into [
case posTextCenter: th2;
case posTextTop: 0;
case posTextBottom: textHeight;
case posTextLeft: th2;
case posTextRight: th2
]
]textPosition
and grid(z) = valof [grid
let g=(z/gridSpacing)*gridSpacing
if (z-g) ge (gridSpacing rshift 1) then g=g+gridSpacing
resultis g
]grid
and apply(eventSwitch, h, splineOperation, textOperation) be [apply
// h is a HITPOINT vector
unless eventSwitch return
test eventSwitch le 3
//apply to hit items
ifso test textOperation & textHitDetect(h)
ifso textOperation(h>>HITPOINT.id)
ifnot if splineOperation & curveHitDetect(h) then
splineOperation(h>>HITPOINT.id, h)
//NOTICE: the 2nd argument (h) is used only by addSplineSelection
// and by paintSpline
ifnot [
// apply to area
let left=h>>HITPOINT.x1
let top=h>>HITPOINT.y1
let right=h>>HITPOINT.x2
let bottom=h>>HITPOINT.y2
if left gr right then [ right=left; left=h>>HITPOINT.x2 ]
if bottom gr top then [ top=bottom; bottom=h>>HITPOINT.y1 ]
if splineOperation & splineTable!0 then
for id=1 to maxSplineID do [
let splinePointer=splineTable!id
unless splinePointer loop
if (left le splinePointer>>SPLINE.left) &
(right ge splinePointer>>SPLINE.right) &
(top ge splinePointer>>SPLINE.top) &
(bottom le splinePointer>>SPLINE.bottom) then
splineOperation(id)
]
if textOperation & textTable!0 then
for id=1 to maxTextID do [
let textPointer=textTable!id
unless textPointer loop
if (left le textPointer>>TEXT.left) &
(right ge textPointer>>TEXT.right) &
(top ge textPointer>>TEXT.top) &
(bottom le textPointer>>TEXT.bottom) then
textOperation(id)
]
]
]apply
//*****************************************************************
// help stuff (ioOverlay)
//*****************************************************************
and helpMode() be [helpMode
let savedPictureFile="DRAW-SAVE.DRAW"
test help
ifso [
// return from help mode
wipeDisplay()
help=0
if pictureSaved & overlay(ioOverlay) then [
readPicture(OpenFile(savedPictureFile, ksTypeReadOnly))
pictureSaved=0
]
]
ifnot [
// get into help mode
help=1
if (splineTable!0 % textTable!0) & overlay(ioOverlay) then [
typeForm(0, "Saving your picture away! ")
writePicture(OpenFile(savedPictureFile, ksTypeWriteOnly))
pictureSaved=true
]
getHelp()
]
resetOverlay()
]helpMode
and getHelp() be [getHelp
overlay(updateOverlay)
wipeDisplay()
if overlay(ioOverlay) then readHelp()
resetOverlay()
]getHelp
//*****************************************************************
// various I/O functions (ioOverlay)
//*****************************************************************
and splineIO(CAfileIO) be [splineIO
unless overlay(ioOverlay) return
switchon CAfileIO into [
case CAread:
readPicture(); endcase
case CAwrite:
writePicture(); endcase
case CAtextMode:
changeTextMode()
if command eq CMtext then makeTextCursor()
endcase
case CAstatistics:
// special command
writeStatistics(); endcase
case CAbitmap:
// special command
writeBitmap(); endcase
case CAreadFont:
readFont(); endcase
]
resetOverlay()
]splineIO
and resetOverlay() = overlay(freeHandMode ? freeHandOverlay, updateOverlay)
//*****************************************************************
// PRESS I/O (pressOverlay, on top of BOTH residentOverlay & updateOverlay)
//*****************************************************************
and plot() be [plot
clearSelection()
// first partial refresh
refreshDisplay(true)
if overlay(pressOverlay) then [
writePressFile()
overlay(residentOverlay)
resetOverlay()
// then full refresh
refreshDisplay()
]
]plot