; three D animation system - display routine interface

.if 0
use_animation::

	movem.l	d0-d3/a0-a1,-(sp)

	bclr	#31,d1			; d1 contains data address with high bit set
	move.l	d1,a2			; target is to return new address of object data in a2
	move.l	(a2)+,d1		; read basic z limit
	cmp.l	d1,d3			; check for actual z beyond limit
	bpl.b	done			; returns pointing at a zero data area and hence drops out

	addq.l	#4,a2			; skip zero
	move.l	(a2)+,d1		; get z limit for animating
	cmp.l	d1,d3
	bpl.b	done			; returns pointing at a valid data set

	lea	16(a2),a2		; skip non-animated data

	move.l	(a2)+,d1		; get minimum animation depth
	cmp.l	d1,d3
	bmi.b	done			; if too close then use old style data

	lea	16(a2),a2		; skip non-animated data

	move.l	(a2)+,d0		; get type of animation (0 = whole, n = number of sub-parts)
	bne.b	multiple

;==================================================

single:	move.l	(a2)+,a0		; read address of data holder
	move.w	(a0),d1			; read frame number
	asl.w	#4,d1			; multiply by 16 to give offset
	adda.w	d1,a2			; apply offset to give correct data pointer
done:	movem.l	(sp)+,d0-d3/a0-a1
	rts

;==================================================

multiple:
	bra.b	.f1

.b1:	move.l	(a2)+,a0		; address of data holder - new one for each entry
	move.w	(a0),d1			; frame number
	move.l	(a2)+,a0		; target for points
	move.l	(a2)+,d2		; target for normals - hold in data register until required
	asl.w	#3,d1			; scale up to make offset
	adda.w	d1,a2
	move.l	(a2)+,a1
	bsr.b	animation_block	

	move.l	d2,a0			; target for normals
	move.l	(a2)+,a1		; source for normals
	bsr.b	animation_block


.b2:	tst.l	(a2)+
	bne	.b2			; cycle round until zero is found (= end of this part)

.f1:	dbra	d0,.b1			; loop round until all segments have been processed

	bra	done

;==================================================

animation_block:
	movem.l	d2/d3,-(sp)
	move.l	(a1)+,d3		; get count for move

.if programmer				; debugging aids - halt if overflow expected data
	bmi.b	err
	cmpi.l	#$80,d3
	bmi.b	pass
err:	bsr.b	fault
pass:
.endif

	move.l	d3,d2
	asl.l	d2
	add.l	d2,d3			; multiply by 3 - 3 points at a time !
	bra.b	.f1

.b1:	move.l	(a1)+,(a0)+
.f1:	dbra	d3,.b1

	movem.l	(sp)+,d2/d3
	rts

;==================================================

fault:	message	"Unexpectedly large animation block."

;==================================================
.endif
; animation number calculation subroutines

front_wheel_roll::
	movem.l	d0-d2,-(sp)

	tst.l	viewmove.w
	bne	.exit

	move.l	speed.w,d0		; get speed

	cmp.w	#$2000,d0		; first off, limit to $c00 - this may need changing
	bmi.b	.ok

	move.w	roll_rear.w,d0
;	subq.w	#4,d0
;	bpl.b	.na
;	addq.w	#5,d0
;.na:	move.w	d0,roll_rear.w
	bra	.exg


.ok:	tst.b	reverse.w		; now reverse if going backwards - just in case
	beq.b	.f1
	neg.w	d0
.f1:	add.w	roll_fraction.w,d0	; add to current stored value
	move.w	d0,roll_fraction.w	; keep track of fractional part, so that low speeds still move
	
;	swap	d0
;	rol.l	#6,d0		; shove down to make realistic (total down by 12 bits)
	asr.w	#8,d0			; scale down to lose fractional part

	move.w	#$5000,d1
.b1:	tst.w	d0			; now make sure value is positive, by adding sets of $5000
	bpl.b	.f2
	add.w	d1,d0
	bra	.b1

.f2:	move.w	d0,d2		; keeps previous value, so eventually ends up with x mod 10
.b2:	sub.w	d1,d0			; and then make sure its below $5000
	bpl	.b2
	add.w	d1,d0
	asr.w	d1			; and then loop round again until eventually we are trimming to the range 0-5
	bcc	.f2			; finally get x mod 5

	move.w	d0,roll_rear.w		; store this new value
	cmp.w	d0,d2
	beq.b	.nos

	add.w	#5<<8,roll_fraction.w
.exg:	move.w	wheelx.w,d2		; exchange items
	move.w	wheely.w,wheelx.w
	move.w	d2,wheely.w

.nos:	move.w	steer.w,d1		; allow 22.5 degree anims
	bpl.b	.nn
	neg.w	d1
.nn:	cmp.w	#8,d1
	bmi.b	.nc			; below this amount no change in either direction
	addq.w	#5,d0

;	cmp.w	#500,d1			; allow 45 degree anims
;	bmi.b	str			; 
;	addq.w	#5,d0

.str:	tst.w	steer.w			; allow right turns
	bmi.b	.nc
	add.w	#10,d0

.nc:	move.w	d0,roll_front.w
.exit:	movem.l	(sp)+,d0-d2
	rts

spark_cycle::				; modified to allow easy stop/start
	move.l	d0,-(sp)

	move.w	spark_count.w,d0	; get current step number
	beq.b	.nspk			; step zero is for stopped
	addq.w	#1,d0			; otherwise add 1
	cmpi.w	#6,d0			; check it hasn't over-run
	blt.b	.ok
	moveq	#0,d0			; stop if end is hit
.ok:	move.w	d0,spark_count.w	; replace number if changed

.nspk:	move.w	smoke_count.w,d0	; get current step number
	beq.b	.nsmo			; step zero is for stopped
	addq.w	#1,d0			; otherwise add 1
	and.w	#3,d0			; limit to range 0-3 (which makes it a once through loop)
.ok2:	move.w	d0,smoke_count.w	; replace number if changed

.nsmo:	move.w	grass_count.w,d0	; get current step number
	beq.b	.au			; this one auto starts if you go off track
	addq.w	#1,d0			; otherwise add 1
	and.w	#3,d0			; limit to range 0-3 (which makes it a once through loop)
	bne.b	.ok3
.au:	tst.b	off_track.w
	beq.b	.ok3
	moveq	#1,d0
.ok3:	tst.l	speed.w
	bne.b	.ok4
	moveq	#0,d0
.ok4:	move.w	d0,grass_count.w	; replace number if changed

.exit:	move.l	(sp)+,d0
	rts

