*************************************************
* NeverWhere Demo Loader by Tronic / Crionics.	*
* Made with Gizwiz Delta Music Editor.		*
* Adapted by Mr.STYCKX / Nicolas Pomarède	*
*						*
* Original replay was PC Relative.		*
*						*
* Ripped : 6/11/94				*
* EaglePlayer / Delitracker port : 19/09/98	*
*	Volume					*
*	Balance					*
*	SubSong					*
*	EP_Voices				*
*	EP_StructInit (Analyzer)		*
*************************************************

	opt	o+

	output	ram:CUST.NeverWhere_Loader


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

	section	Never,code_c



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


	IFEQ	NEVER_TEST-0			; COMPLETE VERSION


	PLAYERHEADER PlayerTagArray

	dc.b '$VER: NeverWhere Loader Music by Tronic / Crionics 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,NEVER_init	; init custom data
	dc.l	DTP_EndSound,NEVER_end		; clear DMA

	dc.l	DTP_SubSongRange,NEVER_SubSongRange

	dc.l	DTP_Interrupt,NEVER_Play

	dc.l	DTP_Volume,NEVER_Volume
	dc.l	DTP_Balance,NEVER_Volume

	dc.l	EP_Voices,NEVER_SetVoices
	dc.l	EP_StructInit,NEVER_StructInit

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

	dc.l	TAG_DONE


PName	dc.b	"NeverWhere Loader Custom v1.0",0
CName	dc.b	"Music by Tronic / Crionics using Delta Editor by Gizwiz.",$a
	dc.b	"Adapted by Mr.STYCKX (19/11/98)",0

	EVEN


NEVER_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

NEVER_init
	move.w	dtg_SndNum(a5),d0	; sub song nbr (1..5)
	bsr.s	NEVER_InitSong

	rts


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

NEVER_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

NEVER_Play
	bsr.s	NEVER_InterVBL
	rts


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

NEVER_SubSongRange
	moveq	#1,d0			; min
	moveq	#1,d1			; max

	rts


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

NEVER_Volume
	move.w	dtg_SndLBal(a5),d0	; Vol Left
	mulu	dtg_SndVol(a5),d0	; Vol Max
	lsr.w	#6,d0
	move.w	d0,NEVER_MasterVolA	; final Vol Left
	move.w	d0,NEVER_MasterVolD

	move.w	dtg_SndRBal(a5),d0
	mulu	dtg_SndVol(a5),d0
	lsr.w	#6,d0
	move.w	d0,NEVER_MasterVolB
	move.w	d0,NEVER_MasterVolC

	rts


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

NEVER_SetVoices
	move.w	d0,NEVER_DMA_EP	; bit=1 <=> voice is ON

	rts


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

NEVER_StructInit
	lea	NEVER_StructAnalyzer(pc),a0

	rts



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


	ELSEIF				; TESTVERSION


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


	bsr	NEVER_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	NEVER_InterVBL
	movem.l	(a7)+,d0-a6

	move.w	#$345,$dff180

Jmp	jmp	0.l




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


	ENDC



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

NEVER_DMA_EP	dc.w	%1111		; voix actives depuis EaglePlayer

NEVER_MasterVolA	dc.w	64		; 0 .. 64
NEVER_MasterVolB	dc.w	64
NEVER_MasterVolC	dc.w	64
NEVER_MasterVolD	dc.w	64

NEVER_OldPer1	dc.w	-1
NEVER_OldPer2	dc.w	-1
NEVER_OldPer3	dc.w	-1
NEVER_OldPer4	dc.w	-1





;-----------------------------------------------------------------------
; NeverWhere Loader Music
; Original music by Tronic / Crionics.
;
; NEVER_InitSong : called once
; NEVER_InterVBL : called every VBL
;



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

NEVER_InitSong
	bsr	NEVER_Patch
	bra	NEVER_Data



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

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

	lea	NEVER_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),NEVER_OldPer1
	move.w	UPS_Voice2Per(a0),NEVER_OldPer2
	move.w	UPS_Voice3Per(a0),NEVER_OldPer3
	move.w	UPS_Voice4Per(a0),NEVER_OldPer4

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


	;-- Original VBL
	bsr	NEVER_Data+$17c


	;-- 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	NEVER_StructAnalyzer(pc),a0
	move.w	UPS_Voice1Per(a0),d0
	cmp.w	NEVER_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	NEVER_OldPer2(pc),d0
	bne.s	.3
	clr.w	UPS_Voice2Per(a0)

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

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



	clr.w	UPS_Enabled(a0)

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




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

	lea	NEVER_Data(pc),a0

	move.w	#$4e75,$6cc(a0)			; change bfe001 (filter)
	move.w	#$4e75,$6d6(a0)			; filter

	lea	$1ec(a0),a1
	lea	NEVER_CopyDMA(pc),a2
	move.w	#$4e71,(a1)+
	bsr.s	DoJsr

	lea	$2ce(a0),a1
	lea	NEVER_StopDMA(pc),a2
	move.w	#$4e71,(a1)+
	bsr.s	DoJsr

	lea	$228(a0),a1
	lea	CopyLen_1(pc),a2
	bsr.s	DoJsr

	lea	$23c(a0),a1
	lea	CopyAdr_1(pc),a2
	bsr.s	DoBsr

	lea	$330(a0),a1
	lea	CopyAdr_1(pc),a2
	bsr.s	DoBsr

	lea	$334(a0),a1
	lea	CopyLen_2(pc),a2
	bsr.s	DoJsr

	lea	$43e(a0),a1
	lea	CopyAdr_2(pc),a2
	bsr.s	DoBsr

	lea	$442(a0),a1
	lea	CopyLen_2(pc),a2
	bsr.s	DoJsr

	lea	$668(a0),a1
	lea	CopyPer(pc),a2
	bsr.s	DoBsr

	lea	$690(a0),a1
	lea	CopyVol(pc),a2
	bsr.s	DoBsr

.done	rts


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

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


;-------

NEVER_CopyDMA
	lea	NEVER_StructAnalyzer(pc),a0
	move.w	NEVER_DMA_EP(pc),d0
	and.w	(a5),d0
	move.w	d0,UPS_DMACon(a0)
	or.w	#$8000,d0
	move.w	d0,$dff096		; start voices
	rts

;-------

NEVER_StopDMA
	move.w	4(a0),$dff096
	rts


;------- Return correct UPS pointer in A0 for voice A1 + Master Vol in D7

GetUPS
	lea	NEVER_StructAnalyzer(pc),a0
	move.w	NEVER_MasterVolA(pc),d7
	cmp.l	#$dff0a0,a1
	beq.s	.ok
	move.w	NEVER_MasterVolB(pc),d7
	lea	UPS_Modulo(a0),a0
	cmp.l	#$dff0b0,a1
	beq.s	.ok
	move.w	NEVER_MasterVolC(pc),d7
	lea	UPS_Modulo(a0),a0
	cmp.l	#$dff0c0,a1
	beq.s	.ok
	move.w	NEVER_MasterVolD(pc),d7
	lea	UPS_Modulo(a0),a0

.ok	rts


;-------

CopyAdr_1
	pea	(a0)
	bsr.s	GetUPS
	move.l	a4,UPS_Voice1Adr(a0)
	move.l	a4,(a1)
	move.l	(sp)+,a0
	rts


CopyAdr_2
	pea	(a0)
	bsr.s	GetUPS
	move.l	d2,UPS_Voice1Adr(a0)
	move.l	d2,(a1)
	move.l	(sp)+,a0
	rts


CopyLen_1
	pea	(a0)
	bsr.s	GetUPS
	move.w	4(a2),UPS_Voice1Len(a0)
	move.w	4(a2),4(a1)
	move.l	(sp)+,a0
	rts


CopyLen_2
	pea	(a0)
	bsr.s	GetUPS
	move.w	(a2),UPS_Voice1Len(a0)
	move.w	(a2),4(a1)
	move.l	(sp)+,a0
	rts


CopyPer
	pea	(a0)
	bsr.s	GetUPS
	move.w	d0,UPS_Voice1Per(a0)
	move.w	d0,6(a1)
	move.l	(sp)+,a0
	rts


CopyVol
	pea	(a0)
	bsr	GetUPS
	move.w	d0,UPS_Voice1Vol(a0)

	mulu	d7,d0			; D7 = MasterVol
	lsr.w	#6,d0
	move.w	d0,8(a1)

	move.l	(sp)+,a0
	rts


Patch_Done	dc.w	0



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


NEVER_Data				; 6104
	incbin	b:NeverWhere/NeverWhere.bin


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