*************************************************
* Hawk Eye by Wally Beben / Thalamus (1988).	*
* Adapted by Mr.STYCKX / Nicolas Pomarède	*
*						*
* Original replay in $490 - $c9ee.		*
*						*
* Ripped : 20/09/98				*
* EaglePlayer / Delitracker port : 20/09/98	*
*	Volume					*
*	Balance					*
*	SubSong					*
*	EP_Voices				*
*	EP_StructInit (Analyzer)		*
*************************************************

	opt	o+

	output	ram:CUST.HawkEye


HAWK_TEST	=	0		; 0 => BUILD COMPLETE CUSTOM MODULE
					; 1 => BUILD SMALL CODE FOR TESTING

	section	Hawk,code_c



	incdir	"Include:"
	include	"misc/DeliPlayer.i"
	include	"misc/EaglePlayer.i"


	IFEQ	HAWK_TEST-0			; COMPLETE VERSION


	PLAYERHEADER PlayerTagArray

	dc.b '$VER: Hawk Eye Musics by Wally Beben custom player V1.0, '
	dc.b 'ripped and adapted by Mr.STYCKX (09/98)',0

	EVEN

PlayerTagArray
	dc.l	DTP_CustomPlayer,1		; CustomPlayer - Tag (important !!!)
	dc.l	DTP_Flags,PLYF_CUSTOM

	dc.l	DTP_PlayerVersion,1<<16+0	; v1.0
	dc.l	EP_PlayerVersion,1
	dc.l	DTP_PlayerName,PName
	dc.l	DTP_Creator,CName

	dc.l	DTP_InitPlayer,InitPlay		; alloc audio
	dc.l	DTP_EndPlayer,EndPlay		; free audio
	dc.l	DTP_InitSound,HAWK_init	; init custom data
	dc.l	DTP_EndSound,HAWK_end		; clear DMA

	dc.l	DTP_SubSongRange,HAWK_SubSongRange

	dc.l	DTP_Interrupt,HAWK_Play

	dc.l	DTP_Volume,HAWK_Volume
	dc.l	DTP_Balance,HAWK_Volume

	dc.l	EP_Voices,HAWK_SetVoices
	dc.l	EP_StructInit,HAWK_StructInit

	dc.l	EP_Flags,EPB_Voices!EPB_Analyzer!EPB_Volume!EPB_Balance

	dc.l	TAG_DONE


PName	dc.b	"Hawk Eye Custom v1.0",0
CName	dc.b	"Music by Wally Beben / Thalamus (1988).",$a
	dc.b	"Adapted by Mr.STYCKX (20/11/98)",0

	EVEN


HAWK_StructAnalyzer			; transmis à EaglePlayer pour gérer
	ds.l	UPS_SizeOF		; les analyzers



*-----------------------------------------------------------------------*
;
; Init Player

InitPlay
	move.l	dtg_AudioAlloc(a5),a0		; Function
	jmp	(a0)


*-----------------------------------------------------------------------*
;
; End Player

EndPlay
	move.l	dtg_AudioFree(a5),a0		; Function
	jmp	(a0)


*-----------------------------------------------------------------------*
;
; Init Custom Replay Routine

HAWK_init
	move.w	dtg_SndNum(a5),d0	; sub song nbr (1..6)
	bsr.s	HAWK_InitSong

	rts


*-----------------------------------------------------------------------*
;
; Clear Audio Reg.

HAWK_end
	move.w	#$f,$dff096
	clr.w	$dff0a8
	clr.w	$dff0b8
	clr.w	$dff0c8
	clr.w	$dff0d8

	rts


*-----------------------------------------------------------------------*
;
; Interrupt routine called every 1/50 s

HAWK_Play
	bsr.s	HAWK_InterVBL
	rts


*-----------------------------------------------------------------------*
;
; Returns min and max sub song

HAWK_SubSongRange
	moveq	#1,d0			; min
	moveq	#6,d1			; max

	rts


*-----------------------------------------------------------------------*
;
; Set Volume

HAWK_Volume
	move.w	dtg_SndLBal(a5),d0	; Vol Left
	mulu	dtg_SndVol(a5),d0	; Vol Max
	lsr.w	#6,d0
	move.w	d0,HAWK_MasterVolA	; final Vol Left
	move.w	d0,HAWK_MasterVolD

	move.w	dtg_SndRBal(a5),d0
	mulu	dtg_SndVol(a5),d0
	lsr.w	#6,d0
	move.w	d0,HAWK_MasterVolB
	move.w	d0,HAWK_MasterVolC

	rts


*-----------------------------------------------------------------------*
;
; Set DMA Voices

HAWK_SetVoices
	move.w	d0,HAWK_DMA_EP	; bit=1 <=> voice is ON

	rts


*-----------------------------------------------------------------------*
;
; Returns address of the UPS structure to EaglePlayer

HAWK_StructInit
	lea	HAWK_StructAnalyzer(pc),a0

	rts



*-----------------------------------------------------------------------*


	ELSEIF				; TESTVERSION


;-------
; Small code to test the player under a debugger


	moveq	#1,d0
	bsr	HAWK_InitSong

	move.l	$6c.w,Jmp+2
	move.l	#Vbl,$6c.w
	rts


End
	move.w	#$f,$dff096
	move.l	Jmp+2(pc),$6c.w
	rts


Vbl
	btst	#5,$dff01f
	beq.s	Jmp

.wa	cmp.b	#70,$dff006
	blt.s	.wa

	move.w	#$f00,$dff180

	movem.l	d0-a6,-(a7)
	bsr	HAWK_InterVBL
	movem.l	(a7)+,d0-a6

	move.w	#$345,$dff180

Jmp	jmp	0.l




HAWK_StructAnalyzer			; transmis à EaglePlayer pour gérer
	ds.l	UPS_SizeOF		; les analyzers


	ENDC



;------------------------------------------------------------------------
; Données pour EaglePlayer / Delitracker

HAWK_DMA_EP	dc.w	%1111		; voix actives depuis EaglePlayer

HAWK_MasterVolA	dc.w	64		; 0 .. 64
HAWK_MasterVolB	dc.w	64
HAWK_MasterVolC	dc.w	64
HAWK_MasterVolD	dc.w	64

HAWK_OldPer1	dc.w	-1
HAWK_OldPer2	dc.w	-1
HAWK_OldPer3	dc.w	-1
HAWK_OldPer4	dc.w	-1





;-----------------------------------------------------------------------
; Hawk Eye Musics
; Original music Wally Beben / Thalamus
;
; HAWK_InitSong : D0 = 1 .. 6
; HAWK_InterVBL : called every VBL
;



;-----------------------------------------------------------------------
; Init song

HAWK_InitSong
	move.b	d0,HAWK_Data+$4a2-$490
	bra	HAWK_Patch



;-----------------------------------------------------------------------
; Routine appelée à chaque VBL

HAWK_InterVBL
	movem.l	D0-A6,-(SP)

	lea	HAWK_StructAnalyzer(pc),a0
	move.w	#-1,UPS_Enabled(a0)
	move.w	#UPSB_Adr!UPSB_Len!UPSB_Per!UPSB_Vol!UPSB_DMACon,UPS_Flags(a0)

	move.w	UPS_Voice1Per(a0),HAWK_OldPer1
	move.w	UPS_Voice2Per(a0),HAWK_OldPer2
	move.w	UPS_Voice3Per(a0),HAWK_OldPer3
	move.w	UPS_Voice4Per(a0),HAWK_OldPer4

	clr.w	UPS_Voice1Per(a0)
	clr.w	UPS_Voice2Per(a0)
	clr.w	UPS_Voice3Per(a0)
	clr.w	UPS_Voice4Per(a0)


	;-- Original VBL
	bsr	HAWK_Data+$494-$490


	;-- Set EaglePlayer Structures
	; La replay remet la période à chaque VBL,ce qui perturbe
	; les analyzers. On ne transmet donc une période que si elle est
	; différente de la VBL précédente.

	lea	HAWK_StructAnalyzer(pc),a0
	move.w	UPS_Voice1Per(a0),d0
	cmp.w	HAWK_OldPer1(pc),d0	; nouvelle fréquence
	bne.s	.2			; oui
	clr.w	UPS_Voice1Per(a0)	; non, on remet a 0

.2	move.w	UPS_Voice2Per(a0),d0
	cmp.w	HAWK_OldPer2(pc),d0
	bne.s	.3
	clr.w	UPS_Voice2Per(a0)

.3	move.w	UPS_Voice3Per(a0),d0
	cmp.w	HAWK_OldPer3(pc),d0
	bne.s	.4
	clr.w	UPS_Voice3Per(a0)

.4	move.w	UPS_Voice4Per(a0),d0
	cmp.w	HAWK_OldPer4(pc),d0
	bne.s	.0
	clr.w	UPS_Voice4Per(a0)
.0



	clr.w	UPS_Enabled(a0)

	movem.l	(SP)+,D0-A6
	rts




HAWK_Patch
	tst.w	Patch_Done
	bne	.done			; do patch only once
	st	Patch_Done

	;-- Reloc Replay

	lea	HAWK_Data(pc),a0	; reloc from $490 to $130c
	lea	HAWK_Data+$130c-$490(pc),a1
	move.l	a0,d0
.loop	cmp.l	#$490,(a0)
	blt	.next
	cmp.l	#$c9ee,(a0)
	bgt.s	.next
	cmp.l	#$4cf9,(a0)
	beq.s	.next
	cmp.l	#$b028,(a0)
	beq.s	.next
	cmp.l	#$3b40,(a0)
	beq.s	.next
	cmp.l	#$1b40,(a0)
	beq.s	.next
	cmp.l	#$6700,(a0)
	beq.s	.next
	cmp.l	#$ba04,(a0)
	beq.s	.next
	cmp.l	#$51cc,(a0)
	beq.s	.next
	cmp.l	#$1169,(a0)
	beq.s	.next
	cmp.l	#$43f9,(a0)
	beq.s	.next
	cmp.l	#$650,(a0)
	beq.s	.next
	cmp.l	#$f00,(a0)
	beq.s	.next
	cmp.l	#$4040,(a0)
	beq.s	.next
	cmp.l	#$3434,(a0)
	beq.s	.next
	cmp.l	#$1414,(a0)
	beq.s	.next
	sub.l	#$490,(a0)
	add.l	d0,(a0)
	addq.w	#2,a0
.next	addq.w	#2,a0
	cmp.l	a1,a0
	blt	.loop


	;-- Patch Replay

	lea	HAWK_Data(pc),a0	; reloc from $490 to $130c

	lea	$804-$490(a0),a1
	lea	StopDMA(pc),a2
	bsr.s	DoJsr

	lea	$be2-$490(a0),a1
	lea	CopyRepeatLen(pc),a2
	bsr.s	DoJsr

	lea	$c2a-$490(a0),a1
	lea	CopyRepeatStart(pc),a2
	bsr.s	DoJsr

	lea	$e6c-$490(a0),a1
	lea	CopyLen(pc),a2
	bsr.s	DoJsr

	lea	$e8c-$490(a0),a1
	lea	CopyStart(pc),a2
	bsr.s	DoJsr

	lea	$ed8-$490(a0),a1
	lea	SetDMAPerVol(pc),a2
	bsr.s	DoJmp

.done	rts



DoJsr	move.w	#$4eb9,(a1)+
	move.l	a2,(a1)+
	rts

DoJmp	move.w	#$4ef9,(a1)+
	move.l	a2,(a1)+
	rts

DoBsr	move.w	#$6100,(a1)+
	sub.l	a1,a2
	move.w	a2,(a1)+
	rts


;-------

StopDMA
	move.w	d5,$dff096
	rts


CopyRepeatLen
	move.w	d7,-(sp)
	move.w	d1,d7			; d1 = 0..3
	mulu	#UPS_Modulo,d7
	lea	HAWK_StructAnalyzer(pc),a5
	add.w	d7,a5
;;	move.w	d0,UPS_Voice1Len(a5)	; don't set val (ugly analyzer...)
	lea	$dff0a4,a5
	move.w	(sp)+,d7
	rts


CopyRepeatStart
	move.w	d7,-(sp)
	move.w	d1,d7
	mulu	#UPS_Modulo,d7
	lea	HAWK_StructAnalyzer(pc),a5
	add.w	d7,a5
;;	move.l	d6,UPS_Voice1Adr(a5)

	clr.w	UPS_Voice1Repeat(a5)	; repeat ON
	tst.b	d0
	bne.s	.ok
	move.w	#1,UPS_Voice1Repeat(a5)	; repeat OFF
.ok

	lea	$dff0a0,a5
	move.w	(sp)+,d7
	rts


CopyLen
	move.w	d7,-(sp)
	moveq	#0,d7
	move.b	HAWK_Data+$1044-$490,d7		; current voice 0..3
	mulu	#UPS_Modulo,d7
	lea	HAWK_StructAnalyzer(pc),a5
	add.w	d7,a5
	move.w	d0,d7
	lsr.w	#1,d7
	move.w	d7,UPS_Voice1Len(a5)
	lea	$dff0a4,a5
	move.w	(sp)+,d7
	rts


CopyStart
	move.w	d7,-(sp)
	moveq	#0,d7
	move.b	HAWK_Data+$1044-$490,d7		; current voice 0..3
	mulu	#UPS_Modulo,d7
	lea	HAWK_StructAnalyzer(pc),a5
	add.w	d7,a5
	move.l	(a1,d4.w),UPS_Voice1Adr(a5)
	lea	$dff0a0,a5
	move.w	(sp)+,d7
	rts


SetDMAPerVol
	lea	HAWK_StructAnalyzer(pc),a3
	lea	HAWK_Data+$fb8-$490(pc),A0
	lea	$DFF0A6,A2
	move.w	(A0),(A2)
	move.w	(a0)+,UPS_Voice1Per(a3)
	move.w	(A0),$10(A2)
	move.w	(a0)+,UPS_Voice2Per(a3)
	move.w	(A0),$20(A2)
	move.w	(a0)+,UPS_Voice3Per(a3)
	move.w	(A0),$30(A2)
	move.w	(a0),UPS_Voice4Per(a3)

	move.b	HAWK_Data+$1050-$490(pc),D1
	not.b	D1
	and.w	#15,D1
	and.w	HAWK_DMA_EP(pc),d1	; garde les voix ON depuis EP
 	move.w	d1,UPS_DMACon(a3)
	or.w	#$8200,D1
	move.w	D1,$DFF096		; voix ON
	eor.w	#$820F,D1
	move.w	D1,$DFF096		; voix OFF

	lea	HAWK_Data+$1020-$490(pc),A1
	moveq	#0,D0
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice1Vol(A3)
	mulu	HAWK_MasterVolA(pc),d0
	lsr.w	#6,d0
	move.w	D0,2(A2)
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice2Vol(A3)
	mulu	HAWK_MasterVolB(pc),d0
	lsr.w	#6,d0
	move.w	D0,$12(A2)
	move.b	(A1)+,D0
	move.w	d0,UPS_Voice3Vol(A3)
	mulu	HAWK_MasterVolC(pc),d0
	lsr.w	#6,d0
	move.w	D0,$22(A2)
	move.b	(A1),D0
	move.w	d0,UPS_Voice4Vol(A3)
	mulu	HAWK_MasterVolD(pc),d0
	lsr.w	#6,d0
	move.w	D0,$32(A2)

	rts


Patch_Done	dc.w	0


;-----------------------------------------------------------------------
; Original MusicReplay


HAWK_Data				; 50526
	incbin	b:HawkEye/HawkEye.bin


;-----------------------------------------------------------------------
; END
	end
