
;
;	COMMON EQUATES
;

DEBUG_ON	EQU	0

PTRSIZE		EQU	(1*4)		; 1 LONG

INPUT6		EQU	G_ENDRAM-PTRSIZE
INPUT5		EQU	INPUT6-PTRSIZE
INPUT4		EQU	INPUT5-PTRSIZE
INPUT3		EQU	INPUT4-PTRSIZE
INPUT2		EQU	INPUT3-PTRSIZE
INPUT1		EQU	INPUT2-PTRSIZE
GPUSTACK	EQU	INPUT1

	NOLIST

	include "jaguar.inc"
	include "blit.inc"
	include "gpu.inc"
	include "macros.inc"

	LIST

	xdef	GetPlVars
;	xdef	CalcPlane
	xdef	GetABCD
	xdef	DoTriCalc
	xdef	g_coll
	XDEF	turtpak
	XDEF	xanglepak
	XDEF	gseek
	xdef	movet
	xdef	bsound

ALIGN	PHRASE
	
	ORG     G_RAM

;
;	GLOBAL REGISTER EQUATES
;

SEEKUP		equ	2
SEEKDOWN	equ	1
;
;	CODE SEGMENT
;

	DEBUG_INIT
; bsound: routine to trigger sound effect given:
; 	INPUT1	Patch index | voice index
;	INPUT2	Voice index
;	INPUT3	patch address (source)
;	INPUT4	voicetable address (dest)
;	INPUT5	turtle1, if 0, set volume max, pan center
;	INPUT6	turtle2
	taboff		EQU		80	; size of voice table entry
	STEREOFACTOR	EQU		1	; factor to exaggerate stereo
	STEREOLIMIT	EQU		$3f00	; limit of pan adjustment value
bsound:
	temp0		REGEQU		R28
	temp1		REGEQU		R27
	temp2		REGEQU		R26
	temp3		REGEQU		R25
	pindex		REGEQU		R24
	turt1		REGEQU		R0
	pslot		REGEQU		R3
	savetype	REGEQU		R4
	pan		REGEQU		R5
	volume		REGEQU		R6
	curvoice	REGEQU		R7
	savesize	REGEQU		R8
	tabsize		REGEQU		R9
	proj1		REGEQU		R10
	dist		REGEQU		R11
	vectx		REGEQU		R12
	vecty		REGEQU		R13
	vectz		REGEQU		R14
	turt2		REGEQU		R15
	vindex		REGEQU		R16
	paddr		REGEQU		R17
	vaddr		REGEQU		R18
	useaddr		REGEQU		R19
	offflag		REGEQU		R20
	equalflag	REGEQU		R21
	curpatch	REGEQU		R22

	movei	#INPUT1,temp0
	load	(temp0),pindex
	addq	#4,temp0
	move	pindex,vindex
	shrq	#16,pindex
	shlq	#16,vindex
	shrq	#16,vindex
	load	(temp0),useaddr
	addq	#4,temp0
	load	(temp0),paddr
	addq	#4,temp0
	load	(temp0),vaddr
	addq	#4,temp0
	load	(temp0),turt1
	addq	#4,temp0
	load	(temp0),turt2

	; get the offflag that tells whether or not we should turn off
	; the voice before modifying (flag will be set below if the
	; voices are different)
	move	useaddr,temp0
	addq	#20,temp0		; point to offflag
	loadw	(temp0),offflag
	
	movei	#taboff,tabsize
	move	useaddr,pslot
	move	vindex,temp2	; to calc entry in voicetable
	move	vindex,temp1	; to calc entry in usetable
	moveq	#4,temp0
	mult	tabsize,temp2
	shlq	#1,temp1	; make index offset of words
	neg	temp0
	add	temp1,pslot	; address of voice use table entry
	add	temp2,vaddr
	move	vaddr,curvoice	; curvoice pts to beginning of voice we are touching
	move	pindex,temp1
	mult	tabsize,temp1
	add	temp1,paddr
	load	(paddr),savetype	; save off synth type to be plugged in at the end
	move	paddr,curpatch

	load	(vaddr),temp3	; is current voice off?
	cmp	temp0,temp3	; if off, = -4
	jr	NE,stillon
	nop
	movei	#goahead,temp2
	moveq	#0,equalflag	; set flag to see if patches are the same to
				; assume that they are NOT
	jump	(temp2)
	moveq	#1,offflag
stillon:
	; must check priorities if we are to turn this voice on
	; load up the current voice's patch in the use table
	;	compare patch indexes, if != make sure offflag is set to 1
	;	(meaning go ahead and turn off the voice)
	;	use the index to get the priority
	;	use pindex to get it's priority
	; 	if pindex's priority >= to current priority, goahead
	;	else quit!
	movei	#setequal,temp2
	loadw	(pslot),temp1		; temp1 = last patch index
	cmp	temp1,pindex
	jump	EQ,(temp2)		; are the patches the same?
	move	pindex,temp2		; temp2 = new patch index
	moveq	#1,offflag		; patch differs, so make sure to turn
					; voice off
	moveq	#0,equalflag		; make sure that this is set
	addq	#16,useaddr		; point to the priority table address
	shlq	#1,temp1		; make offset of words
	load	(useaddr),useaddr	; useaddr = address of priority table
	shlq	#1,temp2		; make offset of words
	add	useaddr,temp1
	add	useaddr,temp2
	loadw	(temp1),temp1		; priority of last patch
	loadw	(temp2),temp2		; priority of new patch
	cmp	temp1,temp2		; is new priority >= last
	jr	PL,goahead
	nop
	movei	#sndend,temp0		; nope, the new patch is of lower
	jump	(temp0)			; priority so don't turn on the voice
	nop
setequal:	; the patches are equal
	; if we are trying to not modify (offflag = 0) then set equalflag
	; to indicate that we should restart the voice by writing the type
	; again
	cmpq	#0,offflag
	jr	NE,goahead
	nop
	movei	#nocopy,temp1
	jump	(temp1)
	moveq	#1,equalflag
goahead:
	; temp0 has -4 in it : MAKE SURE!
	storew	pindex,(pslot)		; save off current voice's patch index
;	move	pindex,temp1
;	mult	tabsize,temp1
	cmpq	#1,offflag
	jr	NE,nooff
;	add	temp1,paddr
	nop
	store	temp0,(curvoice)	; turn voice off first
nooff:
;	load	(paddr),savetype	; save off synth type to be plugged in at the end
	addq	#4,paddr
	addq	#4,vaddr
	moveq	#19-1,temp0
voicelp:
	load	(paddr),temp1
	store	temp1,(vaddr)
	addq	#4,paddr
	subq	#1,temp0
	jr	PL,voicelp
	addq	#4,vaddr
nocopy:
	cmpq	#0,turt1	; do we need to calc volume and pan
	jr	NE,.theworks
	nop
	movei	#sndend,temp0	; no, we just use what's in the voice
	jump	(temp0)
	store	savetype,(curvoice)
.theworks:
	; done with copy

	move	turt1,temp0
	move	turt2,temp1

	; creating a vector with the difference between turt2 and turt1's 
	; position

	addq	#16,temp0
	addq	#16,temp1	; point to zhead
	load	(temp0),temp2
	load	(temp1),vectx
	shlq	#16,temp2
	shlq	#16,vectx
	sharq	#16,temp2
	sharq	#16,vectx
	addq	#4,temp0
	sub	temp2,vectx
	addq	#4,temp1
	load	(temp0),temp2
	load	(temp1),vecty
	move	temp2,temp3
	move	vecty,vectz
	sharq	#16,temp2
	sharq	#16,vecty
	shlq	#16,temp3
	shlq	#16,vectz
	sharq	#16,temp3
	sharq	#16,vectz
	sub	temp2,vecty
	sub	temp3,vectz

	; do a dot product with xrite
	move	turt1,temp0	; already pointing to xrite
	load	(temp0),temp1
	addq	#4,temp0
	load	(temp0),temp3
	move	temp1,temp2
	sharq	#16,temp1
	sharq	#16,temp3
	imult	vectx,temp1
	imult	vecty,temp2
	move	temp1,proj1
	add	temp2,proj1
	imult	vectz,temp3
	add	temp3,proj1

	; now calculate distance of vector
	abs	vectx
	abs	vecty
	abs	vectz
	cmp	vectx,vecty
	jr	PL,snddoyz
	nop
	move	vectx,temp0
	move	vecty,vectx
	move	temp0,vecty
snddoyz:
	cmp	vecty,vectz
	jr	PL,snddodist
	nop
	move	vecty,temp0
	move	vectz,vecty
	move	temp0,vectz
snddodist:
	move	vectz,dist
	sharq	#2,vectx
	sharq	#2,vecty
	add	vectx,dist
	add	vecty,dist
	; done calculating distance

	abs	proj1
	jr	CC,sndpdiv
	div	dist,proj1		; this should not be 16.16
	neg	proj1
sndpdiv:
	; exaggerate the stereo
	movei	#STEREOLIMIT,temp1
	shlq	#STEREOFACTOR,proj1

	cmp	proj1,temp1
	jr	PL,panneg
	nop
	move	temp1,proj1
panneg:
	neg	temp1
	cmp	temp1,proj1
	jr	PL,panok
	nop
	move	temp1,proj1
panok:
	movei	#$3fff,pan

	; DONE with pan
	; now deal with volume!
	movei	#$FFF,temp0		; really 0x5FFF
;	movei	#$E00,temp0		; really 0x7000
	add	proj1,pan		; should never disturb the upper word
	cmp	dist,temp0
	jr	PL,okdist
	nop
	move	temp0,dist
okdist:
	movei	#$7fff,volume
	shlq	#3,dist			; ensured that dist will never be
					; bigger than 0x7000
	sub	dist,volume
	move	curpatch,temp1
;	move	curvoice,temp1
	; point to volume
	addq	#24,temp1
	load	(temp1),temp2		; need to preserve the upper word
	move	temp2,temp0		; temp0 has patch volume in lower word
	move	curvoice,temp1
	shrq	#16,temp2
	addq	#24,temp1
	mult	temp0,volume		; multiply by factor
	shlq	#16,temp2	; got rid of bottom word
	shrq	#15,volume		; normalize to 15 bits

	; plug in volume without disturbing the upper word
	; now or in the volume
	or	volume,temp2
	store	temp2,(temp1)
	addq	#31,temp1
	addq	#21,temp1	; point to pan value

	; plug in the pan value without disturbing the upper word

	load	(temp1),temp2
	shrq	#16,temp2
	shlq	#16,temp2	; clear out lower word
	or	pan,temp2
	store	temp2,(temp1)	; save off pan value

;	cmpq	#1,equalflag
;	jr	EQ,sndend
;	nop
	store	savetype,(curvoice)

sndend:
	movei	#G_CTRL,temp2		; GPU control/status register
	load	(temp2),temp0
	bclr	#0,temp0		; clear GPUGO bit
	bset	#1,temp0		; set CPU interrupt bit
	store	temp0,(temp2)		; stop the GPU

	REGUNDEF	curpatch
	REGUNDEF	pan
	REGUNDEF	volume
	REGUNDEF	tabsize
	REGUNDEF	savetype
	REGUNDEF	temp0
	REGUNDEF	temp1
	REGUNDEF	temp2
	REGUNDEF	temp3
	REGUNDEF	vaddr
	REGUNDEF	paddr
	REGUNDEF	vindex
	REGUNDEF	pindex
	REGUNDEF	turt1
	REGUNDEF	turt2
	REGUNDEF	proj1
	REGUNDEF	dist
	REGUNDEF	vectx
	REGUNDEF	vecty
	REGUNDEF	vectz
	REGUNDEF	offflag
	REGUNDEF	equalflag
