;...................................
;: (c) 1993 Rebellion Software Ltd :
;: Hand coded by R.C.Dibley - 1993 :
;:.................................:

;macros for use in eos format files which will allow simple modification of scales
;and axes, and for point and normal numbers to be pre-scaled without this being
;explicit in the source code.

;some values need initialising just in case
Xscale	set	1
Yscale	set	1
Zscale	set	1
Shrink	set	1
Xax	set	1
Yax	set	2
Zax	set	3
XoffSet	set	0
YoffSet	set	0
ZoffSet	set	0
maxrad	set	0
colfix	set	0
format	set	0
ncount	set	0
pcount	set	0
bcount	set	0
fatal	set	0
nlim	set	0
plim	set	0
psize	set	1	; initially long words - short when normals
polsum	set	0
.text			; because we now want all 3d data in the data segment
.long

.if !(^^defined macrosin)

macrosin set 1
;#==========================================#
; global values for controlling polygon attributes

NOSOURCE	= 1
NOCUE		= 2
COLPICK		= 4
SHADOW		= 8+2+1	; because need to disable light source and depth cueing

;#==========================================#

.macro	points	qty
	dc.l	\qty
	pcount	set	\qty
	plim	set	\qty
	psize	set	1
	noron	set	0	; so that radius will be used
.if pcount>512
	.print 'Limit of 512 points exceeded : ',/d pcount
	fatal	set	1
.endif
.endm

;#==========================================#

.macro	bounds	qty	; number of boundary polygons to allow
	dc.l	\qty
.endm

;#==========================================#

.macro	bound	v01,v02,v03,v04,v05,v06,v07,v08,v09,v10,v11,v12,v13
.if (\v01!=(\#-1))
	.print 'Boundary has wrong number of points.'
	fatal	set	1
.endif
.if \v01>(plim-1)
	.print 'Boundary has a non-existent point (',/d \v01,').'
	fatal	set	1
.endif
	polypoint	\v01,\v02,\v03,\v04,\v05,\v06,\v07,\v08,\v09,\v10,\v11,\v12,\v13
.endm		; use polygon outputter - same format (after special bits)
;#==========================================#

.macro	setscale	value
	Xscale	set	\value
	Yscale	set	\value
	Zscale	set	\value
.endm

;#==========================================#

.macro	setshrink	value
	Shrink	set	\value
.endm

;#==========================================#

.macro	setoff		xof,yof,zof
.if	format	= 0
	XoffSet	set	-(\xof)
	YoffSet	set	-(\zof)
	ZoffSet	set	-(\yof)
.endif
.if	format	= 1
	XoffSet	set	\xof
	YoffSet	set	\yof
	ZoffSet	set	\zof
.endif
.if	format	= 3
	XoffSet	set	-(\zof)
	YoffSet	set	\yof
	ZoffSet	set	\xof
.endif
if	format	= 4		; format 4 is purely to rotate track pieces 180 degrees
	XoffSet	set	(\xof)
	YoffSet	set	-(\zof)
	ZoffSet	set	(\yof)
.endif	
.endm

;#==========================================#

.macro	stretch		axis,value
.iif	\axis=1,	Xscale	set	\value
.iif	\axis=2,	Yscale	set	\value
.iif	\axis=3,	Zscale	set	\value
.endm

;#==========================================#

.macro	type	val
	format	set	\val
.endm

;#==========================================#

.macro	point 	Co1,Co2,Co3

	pcount	set pcount-1
.if	format = 0
	.Xout	set	-(\Co1)
	.Yout	set	-(\Co3)
	.Zout	set	-(\Co2)
.endif
.if	format = 1
	.Xout	set	\Co1
	.Yout	set	\Co2
	.Zout	set	\Co3
.endif
.if	format = 3
	.Xout	set	-(\Co3)
	.Yout	set	\Co2
	.Zout	set	\Co1
.endif
.if	format = 4
	.Xout	set	(\Co1)
	.Yout	set	-(\Co3)
	.Zout	set	(\Co2)
.endif

	.Xout	set	(.Xout + XoffSet * Xscale)
	.Yout	set	(.Yout + YoffSet * Yscale)
	.Zout	set	(.Zout + ZoffSet * Zscale)

	.if (.Xout & $80000000) 
		.Xout	set	-(-.Xout/Shrink)
	.else
		.Xout	set	.Xout / Shrink
	.endif

	.if (.Yout & $80000000) 
		.Yout	set	-(-.Yout/Shrink)
	.else
		.Yout	set	.Yout / Shrink
	.endif

	.if (.Zout & $80000000) 
		.Zout	set	-(-.Zout/Shrink)
	.else
		.Zout	set	.Zout / Shrink
	.endif

.if psize = 1
	dc.l	.Xout
	dc.l	.Yout
	dc.l	.Zout
.else 
	dc.w	.Xout
	dc.w	.Yout
	dc.w	.Zout
.endif

	.radius	set	(.Xout * .Xout) + (.Zout * .Zout) 			; + (.Yout * .Yout) removed - assume 2d collision
.iif (.radius > maxrad) & (noron=0),  maxrad set .radius

.endm

;#==========================================#

.macro	endpoints
	.radius	set 0
	.step	set 65536
	root	.radius,.step
	maxrad	set	.radius
.if pcount!=0
	.print 'Point count is incorrect, should be ',/d plim-pcount
	fatal	set	1
.endif
.endm			;do nothing (currently)

;#==========================================#

.macro	root	rad,st
	.step	set	\st>>1
.iif	.step=0, exitm
	.radius set .radius + .step
	.diff	set (.radius * .radius) - maxrad
.iif	(.diff&$80000000)=0, .radius set .radius - .step
	.lim	set	.radius*2 + 1
.iif	(.diff&$80000000)>0,	.diff	set	-.diff
.iif	.diff > .lim,	root	.radius,.step
.endm

;#==========================================#

.macro	vnormals	qty
	dcb.l	3*(\qty),0
.endm

;#==========================================#

.macro	fnormals	qty
	setscale	1	; reset scale
	setshrink	1
	psize	set	0
	setoff		0,0,0
	ncount	set	\qty
	nlim	set	\qty
	noron	set	1
	dc.l	\qty		; output number to read
.if ncount>341
	.print 'Limit of 341 normals exceeded.'
	fatal	set	1
.endif
.endm

;#==========================================#

.macro	normal		Xv,Yv,Zv
	point	\Xv,\Yv,\Zv
	ncount	set ncount-1
.endm

;#==========================================#

.macro	polys	qty
	pcount	set	\qty
	polsum	set	pcount
	bcount	set	0
	dc.l	\qty
.endm

;#==========================================#

.macro	polypoint	v01,v02,v03,v04,v05,v06,v07,v08,v09,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19
.if	\?v01
	dc.w	\v01
.if \v01>(plim-1)
	.print 'Polygon has non-existent point (',/d \v01,').'
	fatal	set	1
.endif
	polypoint	\v02,\v03,\v04,\v05,\v06,\v07,\v08,\v09,\v10,\v11,\v12,\v13,\v14,\v15,\v16,\v17,\v18,\v19
.endif
.endm

;#==========================================#

.macro	poly	vertices,colour,normal,v01,v02,v03,v04,v05,v06,v07,v08,v09,v10,v11,v12,v13,v14,v15,v16,v17,v18,v19
.if	\vertices=0
	init.w	\vertices,\colour,\normal.l
	pcount	set	pcount-1
.else
.if (\vertices!=(\#-3))
	.print 'Polygon has wrong number of points, should be ',/d \#-3,'.'
	fatal	set	1
.endif
.if (\vertices>8)
	.print 'Polygon limit of 8 points exceeded.'
	fatal	set	1
.endif
.if \normal>(nlim-1)
	.print 'Polygon has non-existent normal (',/d \normal,').'
	fatal	set	1
.endif
	dc.w	\vertices,colfix,\colour,12*(\normal)
	polypoint	\v01,\v02,\v03,\v04,\v05,\v06,\v07,\v08,\v09,\v10,\v11,\v12,\v13,\v14,\v15,\v16,\v17,\v18,\v19
	pcount	set	pcount-1
.endif
.endm

;#==========================================#

.macro	endshape
;.assert ncount=0	; check no. normals
;.assert	pcount=0	; check for right no. polys
.if ncount!=0
	.print 'Incorrect number of normals found (difference=',/d ncount,').'
	fatal	set	1
.endif
.if pcount!=0
	.print 'Incorrect number of polygons found (difference=',/d pcount,').'
	fatal	set	1
.endif
.if (bcount!=0)&(bcount!=-1)
	.print 'BSP count shows unclosed segments.'
	fatal	set	1
.endif
.assert	fatal = 0
.iif fatal!=0, .end
.print '3D shape completed with ',/d plim,' points, ',/d nlim,' normals, ',/d polsum,' faces.'
.long
.endm		

;#==========================================#

.macro	fix	val
colfix	set	\val
.endm

.macro	unfix
colfix	set	0
.endm

;#==========================================#

.macro	bsp	point,normal,address
dc.w	\point^-1,12*(\normal)
dc.l	\address
bcount	set	bcount + 1
.endm

;#==========================================#

.macro	bsp_end
dc.w	$8000
bcount	set	bcount - 1
.endm

;#==========================================#

.macro	boundary	max,xhi,xlo,yhi,ylo,zhi,zlo
.endm

;#==========================================#


.endif
