**
**	Testplayer.s	(based of the DeliTracker Testplayer)
**
**	A sample player that visually reports EaglePlayer's actions
**	within external players.
**
**	Use the source as a skeleton model for your own players.
**	Refer to the sample sources for additional information.
**
**	Once assembled, load this player into EaglePlayer, and try
**	playing the file 'testmodule'.  It is only a textfile with
**	the word "TEST" at the beginning.  Notice now that
**	EaglePlayer's actions on the module are visible.  This should
**	aid you in your coding sequences.
**
**	Original source by Peter Kunath and Frank Riffel of Delirium.
**	Changed for EaglePlayer by Eagleeye of DEFECT
**
**	English, comments, and general banter by Kevin Dackiw, Eagleeye
**	and Buggs.
**
**	Have any problems/concerns/ideas?  Feel free to contact the
**	authors:
**
**	Author from DeliTracker:		Author from EaglePlayer:
**	------------------------		------------------------
**	Frank Riffel				Jan Blumenthal
**	Merkstr. 27				Erich-Mühsam-Str.33
**	8129 Wessobrunn				O-2510 Rostock 5
**	Germany					Germany
**
**	Or myself:
**
**	Kevin Dackiw
**	sikorsky@bode.ee.ualberta.ca (preferred)
**	kevind@ersys.edmonton.ab.ca
**
_LVOOldOpenLibrary	EQU -408		;exec library offsets
_LVOCloseLibrary	EQU -414

_LVOTextRequest		EQU -174		;offset for TextRequest in Req.

		incdir	"include:"
		include	"Misc/EaglePlayer.i"

		PLAYERHEADER Test_TagArray	; define start of header

	dc.b '$VER: TestPlayer V1.21 (15 April 93)',0
		even

Test_TagArray:
	dc.l	DTP_PlayerVersion,3			; define all the tags
	dc.l	DTP_PlayerName,Test_Name		; for the player
	dc.l	DTP_Creator,Test_Creator
	dc.l	DTP_Check2,Check			; omit any unused
	dc.l	DTP_Config,ConfigPlayer			; functions as
	dc.l	DTP_UserConfig,UserConfig		; needed!
	dc.l	DTP_SubSongRange,SubSongrange
	dc.l	DTP_InitPlayer,InitPlay
	dc.l	DTP_EndPlayer,EndPlay
	dc.l	DTP_InitSound,InitSnd
	dc.l	DTP_EndSound,EndSnd
	dc.l	DTP_StartInt,StartInt
	dc.l	DTP_StopInt,StopInt
	dc.l	DTP_Volume,Volume
	dc.l	DTP_Balance,Balance
	dc.l	DTP_Faster,Faster
	dc.l	DTP_Slower,Slower
	dc.l	DTP_PrevPatt,PrevPatt
	dc.l	DTP_NextPatt,NextPatt
	dc.l	DTP_PrevSong,PrevSubSong
	dc.l	DTP_NextSong,NextSubSong

	dc.l	EP_StructInit,StructInit		;Init & Get Analyzer
							;Structure
	dc.l	EP_StructEnd,StructEnd			;Free AnalyzerStructure
							;if nessesary

	dc.l	EP_Get_ModuleInfo,Get_ModuleInfo	;Get Infotaglist about
	dc.l	EP_Free_ModuleInfo,Free_ModuleInfo	;Module

	dc.l	EP_Voices,Voices			;Set Voices on/off
	dc.l	EP_SampleInit,SampleInit
	dc.l	EP_SampleEnd,SampleEnd
	dc.l	EP_Save,Save				;Save the Module

	dc.l	EP_ModuleChange,ModuleChange		;change Playroutine of
							;Modules with Player
							;in them
	dc.l	EP_ModuleRestore,ModuleRestore		;restore these Mods,
							;for Saving

	dc.l	EP_LoadPlConfig,LoadConfig		;Load & Save the
	dc.l	EP_SavePlConfig,SaveConfig		;Config of the Player

	dc.l	EP_GetPositionNr,GetPositionNr		;Positionnumber for
							;Next/PrevPattern
	dc.l	EP_SetSpeed,SetSpeed
;	dc.l	EP_CheckModule,CheckModule
	dc.l	EP_EjectPlayer,EjectPlayer

	dc.l	EP_Date
	dc.b	10,7
	dc.w	1993

	dc.l	TAG_DONE				; signify end of tags

*-----------------------------------------------------------------------*
*---- Playername / creatorname and textstructure for our requesters ----*
*-----------------------------------------------------------------------*
Test_Name:	dc.b	'TestPlayer',0
Test_Creator:	dc.b	'Written by Delirium & Eagleeye for Testpurposes',0
Reqname		dc.b	'req.library',0

*---------------------- TextStructure für Req.Library --------------------*
	even
TextStruct:
	dc.l	0					; ^Text
	dc.l	0					; ^ParamList
	dc.l	0					; ^Window
	dc.l	0					; ^MiddleText
	dc.l	0					; ^PositiveText
	dc.l	OKTxt					; ^NegativeText
	dc.l	TitleTxt				; ^Title
	dc.w	$ffff					; KeyMask
	dc.w	0					; textcol
	dc.w	0					; detailcol
	dc.w	0					; blockcol
	dc.w	0					; versionnumber
	dc.w	0					; Timeout
	dc.l	0					; abortmask
	dc.l	0					; reserved

OKTxt:		dc.b	'  OK  ',0
TitleTxt:	dc.b	'TestPlayer-Information',0

InitPlayer.TXT:
	dc.b	10
	dc.b	'InitPlayer routine called.',10,10
	dc.b	'This routine is called every time a new module is loaded.',10
	dc.b	'The audiochannels should be allocated here, and any',10
	dc.b	'player specific initialization should be performed.',10
	dc.b	0

EndPlayer.TXT:
	dc.b	10
	dc.b	'EndPlayer routine called.',10,10
	dc.b	'This routine is called every time a module is killed',10
	dc.b	'(removed from memory).  Player specific cleanup routines',10
	dc.b	'are performed here, and the audiochannels should be',10
	dc.b	'released at this point.',10
	dc.b	0

InitSound.TXT:
	dc.b	10
	dc.b	'InitSound routine called.',10,10
	dc.b	'This routine handles the initialization of the module.',10
	dc.b	0

EndSound.TXT:
	dc.b	10
	dc.b	'EndSound routine called.',10,10
	dc.b	'This routine clears the audioregisters.',10
	dc.b	0

StartInt.TXT:
	dc.b	10
	dc.b	'StartSound routine called.',10,10
	dc.b	'This code must start the sound interrupts.',10
	dc.b	'If you use the internal DeliTracker routines, you must',10
	dc.b	'delete this entry from the TagArray.',10
	dc.b	0

StopInt.TXT
	dc.b	10
	dc.b	'StopSound routine called.',10,10
	dc.b	'This code must stop the sound interrupts.',10
	dc.b	'If you use the internal DeliTracker routines, you must',10
	dc.b	'omit this entry from the TagArray.',10
	dc.b	0

UserConfig.TXT:
	dc.b	10
	dc.b	'UserConfig routine called.',10,10
	dc.b	'This routine is for the use of advanced players.',10
	dc.b	'For example, if your player needs access to a directory',10
	dc.b	'of instruments, this routine could prompt the user with',10
	dc.b	'a requester for the path to the instruments.  Additionally',10
	dc.b	'the path could then be saved in a custom config file, such',10
	dc.b	'as s:<playername>.config.  Any future runs of the player',10
	dc.b	'would only then have to fetch the path from its config file.',10
	dc.b	'This custom config file must be accessed from the Config routine.',10
	dc.b	0

ConfigPlayer.TXT:
	dc.b	10
	dc.b	'ConfigPlayer routine called.',10,10
	dc.b	'This routine is entered after the player is loaded.',10
	dc.b	'At this point you may load a custom config file to fetch',10
	dc.b	'such things as a default instrument path, and the like.',10
	dc.b	0

EjectPlayer.TXT:
	dc.b	10
	dc.b	'EjectPlayer routine called.',10,10
	dc.b	'This routine is entered before the player is deleting.',10
	dc.b	'At this point you may save a custom config file to fetch',10
	dc.b	'such things as a instrument path, and the like.',10
	dc.b	0

LoadConfig.TXT:
	dc.b	10
	dc.b	"Load PlayerConfig routine called.",10,10
	dc.b	"This routine loads the players preferences",10
	dc.b	"from ENV:Eagleplayer/<Filename> .",10
	dc.b	"You may e.g. load a config with the",10
	dc.b	"instrument path.",10
	dc.b	0

SaveConfig.TXT:
	dc.b	10
	dc.b	"Save PlayerConfig routine called.",10,10
	dc.b	"This routine saves the player preference of",10
	dc.b	"the selected player to ENVArc:EaglePlayer/<Filename>",10
	dc.b	"Usefull for Instruments path.",10
	dc.b	0

NextPattern.TXT:
	dc.b	10
	dc.b	'NextPattern routine called.',10,10
	dc.b	'This routine skips ahead one pattern in the module.',10
	dc.b	0

PrevPattern.TXT:
	dc.b	10
	dc.b	'PrevPattern routine called.',10,10
	dc.b	'This routine skips back one pattern in the module.',10
	dc.b	0

GetPositionNr.TXT:
	dc.b	10
	dc.b	"Get PositionsNr routine called.",10,10
	dc.b	"You have to give the actual Position in Module back",10
	dc.b 	`Useful to show on which Position you are ...`,10
	dc.b	0

NextSubSong.TXT:
	dc.b	10
	dc.b	'NextSubsong routine called.',10,10
	dc.b	'This routine jumps to the next subsong (if supported).',10
	dc.b	0

PrevSubSong.TXT:
	dc.b	10
	dc.b	'PrevSubsong routine called.',10,10
	dc.b	'This routine jumps to the previous subsong (if supported).',10
	dc.b	0

SpeedFaster.TXT:
	dc.b	10
	dc.b	'Faster Speed routine called.',10,10
	dc.b	'This routine increases the playspeed.',10
	dc.b	0

SpeedSlower.TXT:
	dc.b	10
	dc.b	'Slower Speed routine called.',10,10
	dc.b	'This routine decreases the playspeed.',10
	dc.b	0

SetSpeed.TXT:
	dc.b	10
	dc.b	"Set Speed routine called.",10,10
	dc.b	"Here you get & set the Speed in Eagleplayer which you"
	dc.b	"control comfortable by the slider on the left side",10
	dc.b	0

SubSongRange.TXT:
	dc.b	10
	dc.b	'SubSongRange routine called.',10,10
	dc.b	'This routine must determine the min & max subsong number.',10
	dc.b	0

Volume.TXT:
	dc.b	10
	dc.b	'Volume routine called.',10,10
	dc.b	'This routine controls the volume.',10
	dc.b	0

Balance.TXT:
	dc.b	10
	dc.b	'Balance routine called.',10,10
	dc.b	'This routine controls the balance.',10
	dc.b	0

Voices.TXT:
	dc.b	10
	dc.b	'Voices routine called.',10,10
	dc.b	`This Routine switches the 4 Voices of Amiga on/off`,10
	dc.b	0

Save.TXT:
	dc.b	10
	dc.b	"Save routine called,",10,10
	dc.b	"This routine saves the module.",10
	dc.b	0

SampleInit.TXT:
	dc.b	10
	dc.b	"SampleInit routine called,",10,10
	dc.b	"This routine handels the initialization",10
	dc.b	"of the Sample-Taglist.",10
	dc.b	0

SampleEnd.TXT:
	dc.b	10
	dc.b	"SampleEnd routine called.",10,10
	dc.b	"This routine has been called every time if a Samplewindow",10
	dc.b	"had been closed.",10
	dc.b	"The player will free the used memory of the",10
	dc.b	"Sample-Taglist.",10
	dc.b	0

GetModuleInfo.TXT:
	dc.b	10
	dc.b	"Get_ModuleInfo routine called,",10,10
	dc.b	"This routine handels the initialization",10
	dc.b	"of the ModuleInfo-Taglist",10
	dc.b	0

FreeModuleInfo.TXT:
	dc.b	10
	dc.b	"Free ModuleInfo routine called.",10,10
	dc.b	`This Routine will be called if a Module was ejected,`,10
	dc.b	`so that the player could free allocated Memory for the`,10
	dc.b	`Taglist, if needed`,10
	dc.b	0

Check.TXT:
	dc.b	10
	dc.b	"Check routine called.",10,10
	dc.b	"This routine will has been called every time a module had",10
	dc.b	"been loaded. The player tests if it knows this",10
	dc.b	"module-format.",10
	dc.b	0
	
ModuleChange.TXT:
	dc.b	10
	dc.b	"Module Change routine called.",10,10
	dc.b	"This routine will be called every time a module with",10
	dc.b	"playroutine within itself has been loaded. The playroutine",10
	dc.b	`will change it to an Analyzer/Volume&Balanceset ...`,10
	dc.b	`compatible replayer`,10
	dc.b	0
	even

ModuleRestore.TXT:
	dc.b	10
	dc.b	"Module Restore routine called.",10,10
	dc.b	"This routine has been called every time a module with",10
	dc.b	"playroutine should be saved.",10
	dc.b	"The original replayercode will be restored.",10
	dc.b	0

StructInit.TXT:
	dc.b	10
	dc.b	"StructInit routine called.",10,10
	dc.b	"This routine returns a Pointer to an anylyzerstructure.",10
	dc.b	"This structure will be filled by the player.",10
	dc.b	0

StructEnd.TXT:
	dc.b	10
	dc.b	"StructEnd routine called.",10,10
	dc.b	"This routine has been called when player stops or the",10
	dc.b	"module will be killed. This routine deallocates",10
	dc.b	"the structure memory.",10
	dc.b	0

*-----------------------------------------------------------------------------*
*-- Check if the module is a TestPlayer-Module (THIS ROUTINE MUST EXIST!!!) --*
*-----------------------------------------------------------------------------*
		even
Check:		move.l	dtg_ChkData(a5),a0	; get module base from DT
		moveq	#0,d0				; clear register
		cmpi.l	#'TEST',(a0)			; supported type ?
		sne	d0				; no - signal false
		bne.s	.NotFound
		lea	Check.TXT(pc),a2
		bsr	DisplayMsg			; output
		moveq	#0,d0
.NotFound:	rts					; leave

*-----------------------------------------------------------------------*
*-------------------------- Initialize the player ----------------------*
*-----------------------------------------------------------------------*
InitPlay:	lea	InitPlayer.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		moveq	#0,d0				; no error
		rts

*-----------------------------------------------------------------------*
*---------------------------- Clean up the player ----------------------*
*-----------------------------------------------------------------------*
EndPlay:	lea	EndPlayer.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*--------------------------- Initialize the module ---------------------*
*-----------------------------------------------------------------------*
InitSnd:	lea	InitSound.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------------------- End sound -----------------------------*
*-----------------------------------------------------------------------*
EndSnd:		lea	EndSound.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------------------ Start interrupts -----------------------*
*-----------------------------------------------------------------------*
StartInt:	lea	StartInt.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------------------- Stop interrupts -----------------------*
*-----------------------------------------------------------------------*
StopInt:	lea	StopInt.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
;
; IMPORTANT NOTE:
;	There is a BIG difference between the »Config« and the
;	»UserConfig« Routine !!! The Config routine is immediately
;	called after that the Player is loaded. It is used to
;	configure player (e.g. load config file and set pathes)!
;	The UserConfig routine is only called if the User selects
;	the player in the PrefWindow and presses the Config Player
;	GADGET. This routine is thought as a method of getting
;	informations (playerspecific preferences) from the user
;	(e.g. pathes for instruments or maximum memory usage).
;	The difference between Config and InitPlayer is that
;	Config is called ONCE the player is loaded and that
;	InitPlayer is called every time a module is played.
;
*-----------------------------------------------------------------------*
*----- get/set playerspecific preferences (configuration routines) -----*
*-----------------------------------------------------------------------*
ConfigPlayer:	lea	ConfigPlayer.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

EjectPlayer:	lea	EjectPlayer.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

UserConfig:	lea	UserConfig.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		moveq	#0,d0				; no error
		rts

LoadConfig:	lea	LoadConfig.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		moveq	#0,d0				; no error
		rts

SaveConfig:	lea	SaveConfig.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		moveq	#0,d0				; no error
		rts


*-----------------------------------------------------------------------*
*----------------------------- Patterncontrol --------------------------*
*-----------------------------------------------------------------------*
NextPatt:	lea	NextPattern.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

PrevPatt:	lea	PrevPattern.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

GetPositionNr:	lea	GetPositionNr.TXT(pc),a2	; fetch text
		bsr	DisplayMsg			; output
		moveq	#1,d0				; PatternNr
		rts


*-----------------------------------------------------------------------*
*------------------------------ Subsongcontrol -------------------------*
*-----------------------------------------------------------------------*
SubSongRange:	lea	SubSongRange.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		moveq	#0,d0
		moveq	#2,d0
		rts

NextSubSong:	lea	NextSubSong.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

PrevSubSong:	lea	PrevSubSong.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------------------ Speedcontrol ---------------------------*
*-----------------------------------------------------------------------*
Faster:		lea	SpeedFaster.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

Slower:		lea	SpeedSlower.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

SetSpeed:	lea	SetSpeed.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

*-----------------------------------------------------------------------*
*--------------------------- ModuleInfocontrol -------------------------*
*-----------------------------------------------------------------------*
Get_ModuleInfo:	lea	GetModuleInfo.TXT(pc),a2	; fetch text
		bsr	DisplayMsg			; output
		sub.l	a0,a0
		rts

Free_ModuleInfo:lea	FreeModuleInfo.TXT(pc),a2	; fetch text
		bra	DisplayMsg			; output

*-----------------------------------------------------------------------*
*-------------------------- SampleInfo-Control -------------------------*
*-----------------------------------------------------------------------*
SampleInit:	lea	SampleInit.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		sub.l	a0,a0
		rts

SampleEnd:	lea	SampleEnd.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------ UserProgramm-Structure-Control ---------------------*
*-----------------------------------------------------------------------*
StructInit:	lea	StructInit.TXT(pc),a2		; fetch text
		bsr	DisplayMsg			; output
		sub.l	a0,a0
		rts

StructEnd:	lea	StructEnd.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

*-----------------------------------------------------------------------*
*------------------ UserProgramm-Structure-Control ---------------------*
*-----------------------------------------------------------------------*
ModuleChange:	lea	ModuleChange.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

ModuleRestore:	lea	ModuleRestore.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*------------------ Volume & Balance & Voice Control -------------------*
*-----------------------------------------------------------------------*
Volume:		lea	Volume.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

Balance:	lea	Balance.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output

Voices:		lea	Voices.TXT(pc),a2		; fetch text
		bra	DisplayMsg			; output


*-----------------------------------------------------------------------*
*-------------------------------- Save ---------------------------------*
*-----------------------------------------------------------------------*
Save:		lea	Save.TXT(pc),a2
		bra.w	DisplayMsg

*-----------------------------------------------------------------------*
*---------------------------- Subroutines ------------------------------*
*-----------------------------------------------------------------------*
DisplayMsg:	lea	reqname(pc),a1
		move.l	4.w,a6
		jsr	_LVOOldOpenLibrary(a6)		; open req.library
		tst.l	d0
		beq.s	DisplayEnd			; library open failed

		lea	TextStruct(pc),a0		; address of text structure
		move.l	a2,(a0)				; copy text pointer to block
		move.l	d0,a6				; get ReqBase address
		jsr	_LVOTextRequest(a6)		; print the message

		move.l	a6,a1
		move.l	4.w,a6
		jsr	_LVOCloseLibrary(a6)		; close req.library
DisplayEnd:	rts					; bye!

