// May 8, 1978  4:15 PM				*** overlay C ***


get "zpDefs.bcpl"

get "zpPressDf.bcpl"


// outgoing procedures:

external [
	PutsCurve
	PutsMove
	PutsLine
	PutsRoundTip
	PutObjectInELtable
	PutRectangleInELtable
	PutColorInELtable
	PutNewColorInELtable
	DPadd
	OutsideThePage
	PrintFpValues
	RectangleSpline
	]

// incoming procedures:

external [
	Puts			// SYSTEM
	DoubleAdd
	Gets
	WriteBlock
	MoveBlock

	FLD; FLDI; FST		// FLOAT
	FTR; FML; FDV
	FAD; FNEG; FSB; FCM; FSN
	FSTDP; FLDDP; DPAD

	typeForm		// ZPUTIL
	]

// incoming statics:

external [
	keys			// SYSTEM

	@showObjects		// ZPPRESS
	@previousColor
	@ELtable
	@ELtableLength
	@objectCount
	@rectangleCount
	@hueTable
	@saturationTable
	@brightnessTable
	@pageLeft
	@pageRight
	@pageBottom
	@pageTop
	]

// local statics

// local floating point registers

manifest [
	t0=0; t1=1; t2=2; t3=3; t4=4
	]




let PutsCurve(pressFile, lvObjectCount, xc, yc, xb, yb, xa, ya) be [PutsCurve
	let coefs=vec 12
	let p0=lv xc
	for i=0 to 5 do MoveBlock(coefs+2*i, p0!i, 2)
	Puts(pressFile, Dcurve)
	WriteBlock(pressFile, coefs, 12)
	@lvObjectCount=@lvObjectCount + DcurveDLcount
	]PutsCurve



and PutsLine(pressFile, lvObjectCount, x, y) be [PutsLine
	Puts(pressFile, Dline)
	Puts(pressFile, x)
	Puts(pressFile, y)
	@lvObjectCount=@lvObjectCount + DlineDLcount
	]PutsLine



and PutsMove(pressFile, lvObjectCount, x, y) be [PutsMove
	Puts(pressFile, Dmove)
	Puts(pressFile, x)
	Puts(pressFile, y)
	@lvObjectCount=@lvObjectCount + DmoveDLcount
	]PutsMove



and PutsRoundTip(pressFile, lvObjectWordCount, x0, y0, x1, y1) be [PutsRoundTip
	// circular approximation by cubic parametrization:
	// first piece (2nd quadrant, counter-clockwise)
	// x(t) = - cos(pi/2 t)
	// y(t) = sin(pi/2 t)
	// second piece (1rst quadrant, counter-clockwise)
	// x(t) = sin(pi/2 t) = - .4298 t↑3 - .1772 t↑2 + 1.6070 t
	// y(t) = cos(pi/2 t) = .4298 t↑3 - 1.4666 t↑2 + .0368 t + 1

	manifest [
		// floating point accumulators for coefficients
		Sa=18; nSa=19; Sb=20; nSb=21; Sc=22; nSc=23
		Ca=24; nCa=25; Cb=26; nCb=27; Cc=28; nCc=29
		// transformation coefficients
		k=30; h=31
		]
	// sin & cos coefficients
	FLDI(t1, 10000)
	FLDI(t0, 4298); FDV(t0, t1); FLD(Ca, t0); FLD(nSa, t0)
	FNEG(t0); FLD(Sa, t0); FLD(nCa, t0); 
	FLDI(t0, 1772); FDV(t0, t1); FLD(nSb, t0); FNEG(t0); FLD(Sb, t0)
	FLDI(t0, 16070); FDV(t0, t1); FLD(Sc, t0); FNEG(t0); FLD(nSc, t0)
	FLDI(t0, 14666); FDV(t0, t1); FLD(nCb, t0); FNEG(t0); FLD(Cb, t0)
	FLDI(t0, 368); FDV(t0, t1); FLD(Cc, t0); FNEG(t0); FLD(nCc, t0)
	// transformation coefficients
	//	k = x1 - (x1+x0)/2
	//	h = y1 - (y1+y0)/2
	FLDI(k, x1); FLDI(h, y1)
	FLDI(t0, 2)
	FLDI(t1, x0); FAD(t1, k); FDV(t1, t0); FSB(k, t1)
	FLDI(t1, y0); FAD(t1, h); FDV(t1, t0); FSB(h, t1)
	// compute cos & sin transformation for round end curves
	// transformation is:
	//	X ← k*x - h*y
	//	Y ← h*x + k*y
	let xa=vec 2; let xb=vec 2; let xc=vec 2
	let ya=vec 2; let yb=vec 2; let yc=vec 2
	// first piece ( x=-cos, y=sin)
	FLD(t0, nCa); FLD(t1, nSa); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xa)
	FLD(t0, nCb); FLD(t1, nSb); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xb)
	FLD(t0, nCc); FLD(t1, nSc); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xc)
	FLD(t0, nCa); FLD(t1, Sa); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, ya)
	FLD(t0, nCb); FLD(t1, Sb); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, yb)
	FLD(t0, nCc); FLD(t1, Sc); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, yc)
	PutsCurve(pressFile, lvObjectWordCount, xc, yc, xb, yb, xa, ya)
	// second piece (x=sin, y=cos)
	FLD(t0, Sa); FLD(t1, nCa); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xa)
	FLD(t0, Sb); FLD(t1, nCb); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xb)
	FLD(t0, Sc); FLD(t1, nCc); FML(t0, k); FML(t1, h); FAD(t0, t1); FST(t0, xc)
	FLD(t0, Sa); FLD(t1, Ca); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, ya)
	FLD(t0, Sb); FLD(t1, Cb); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, yb)
	FLD(t0, Sc); FLD(t1, Cc); FML(t0, h); FML(t1, k); FAD(t0, t1); FST(t0, yc)
	PutsCurve(pressFile, lvObjectWordCount, xc, yc, xb, yb, xa, ya)
	]PutsRoundTip



and PutObjectInELtable(objectWordCount) = valof [
	if objectWordCount eq 0 then [
		typeForm(1, $+)
		resultis 0
		]
	PutNewColorInELtable()
	ELtable!ELtableLength=EnopLeft + EshowObject
	ELtable!(ELtableLength+1)=objectWordCount
	ELtableLength=ELtableLength+2
	typeForm(1, $**)
	objectCount=objectCount+1
	resultis objectWordCount
	// returns how many words are in the DL
	]



and PutRectangleInELtable(x, y, w, h) = valof [
	typeForm(1, $#)
	PutNewColorInELtable()
	ELtable!ELtableLength=EnopLeft + EsetX
	ELtable!(ELtableLength+1)=x
	ELtable!(ELtableLength+2)=EnopLeft + EsetY
	ELtable!(ELtableLength+3)=y
	ELtable!(ELtableLength+4)=EnopLeft + EshowRectangle
	ELtable!(ELtableLength+5)=w
	ELtable!(ELtableLength+6)=h
	ELtableLength=ELtableLength+7
	rectangleCount=rectangleCount+1
	resultis 0
	// nothing in the DL
	]



and PutColorInELtable(color) be [
	ELtable!ELtableLength=hueTable!color 		
	ELtable!(ELtableLength+1)=saturationTable!color
	ELtable!(ELtableLength+2)=brightnessTable!color
	if showObjects ne 0 then showObjects=showObjects+1
	ELtableLength=ELtableLength+3
	previousColor=color
	]



and PutNewColorInELtable() be [
	if showObjects ne 0 then [
		previousColor=previousColor+1
		if previousColor ge black then previousColor=cyan
		ELtable!ELtableLength=hueTable!previousColor
		ELtableLength=ELtableLength+1
		]
	]


and DPadd(dpvec, a) be [
	let v=vec 2
	v!0=0; v!1=a
	DoubleAdd(dpvec, v)
	]



and OutsideThePage(left, right, top, bottom) = valof [
	if left ls pageLeft then resultis "left"
	if right gr pageRight then resultis "right"
	if top gr pageTop then resultis "top"
	if bottom ls pageBottom then resultis "bottom"
	resultis 0
	]



and PrintFpValues(str, fp1, fp2, fp3, fp4, fp5, fp6, fp7, fp8; numargs n) be [
	typeForm(0, str)
	let fp=lv fp1
	for i=0 to n-2 do typeForm(-2, fp!i, 1, $|)
	typeForm(0, " continue ?*N")
	Gets(keys)
	]


and RectangleSpline(splinePointer) =
	(splinePointer>>SPLINE.type ne regSpline) & (splinePointer>>SPLINE.shape ne rBrush)