*****************************************************************************
**                                                                         **
** Engine: NoiseConverter                                                  **
**                                                                         **
** Project: Eagleplayer 2.04                                               **
** Authors: Jan Blumenthal & Henryk Richter                                **
** Start  : 1993/01/09                                                     **
** $Header$                                                                **
**                                                                         **
*****************************************************************************
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program (See the included file COPYING);
** if not, write to the Free Software Foundation, Inc.,
** 675 Mass Ave, Cambridge, MA 02139, USA.
**
***************************************************************************** 


*******************************************************************************
******									*******
******			Engine by Eagleeye & Buggs of DEFECT		*******
******									*******
*******************************************************************************
Executable		= 1

ver		macro
		dc.b	"2.02"
		endm
StructVer	macro
		dc.w	2,02
		endm
date		macro
		dc.b	"13-Dec-96"
		endm
StructDate	macro
		dc.b	13,12
		dc.w	1996
		endm

*-----------------------------------------------------------------------------*
		incdir	include:
		include	"misc/eagleplayer.i"
		include	"misc/eagleplayerengine.i"
		include	"misc/eagleplayerconverter.i"
		include	"exec/exec_lib.i"
		include	"dos/dos_lib.i"
		include	"dos/dos.i"


 STRUCTURE CS_Converter,0
	APTR	CS_Next
	ULONG	CS_Segment
	LONG	CS_StructSize
	APTR	CS_Tags
	APTR	CS_Convertername
	ULONG	CS_Flags
	LABEL	CS_SizeOF

		rsreset
		rs.b	EPG_SizeOF
FirstConverter	rs.l	1
MemPuffer	rs.l	2
Converterloaded rs.w	1
ConverterTags	rs.l	1
PufferEnd	rs.b	0


*-----------------------------------------------------------------------------*
*-----				Start Programm				------*
*-----------------------------------------------------------------------------*
;UserStartPrg

		ifeq	executable
		bsr	FirstEagleInit
		lea	data,a0
		move.l	#datasize,d0
		cmp.l	#"XPKF",(a0)
		beq.s	.Ende
		bsr	ConvertModule
		bsr	ExitEngine
.Ende:		illegal
		endc

EUS_Structure:	moveq	#-1,d0				;EUS_Jump
		rts
		EUSN_Identifier				;EUS_Identifier
		dc.l	0				;EUS_Next
		dc.w	0				;EUS_Usernr
		dc.l	0				;EUS_EPBase
		dc.l	0				;EUS_FreeTable
		dc.l	0			;EUS_TaskAdr = NULL
		dc.l	0				;EUS_UnUsed1
		dc.l	0				;EUS_UnUsed2
		dc.l	0				;EUS_UnUsed3
		dc.l	TagListe			;EUS_Taglist
		dc.w	0				;EUS_Ticks
		dc.w	0				;EUS_TickCounter
		dc.l	0				;EUS_TickFlags
		dc.l	0				;EUS_MsgFlags
		dc.l	MyCreatorname			;EUS_PName
		dc.l	MyCreatorname			;EUS_Creator
		dc.l	MySpecialInfo			;EUS_AboutUPRG
		dc.w	37				;EUS_Kickstart
		dc.l	11				;EUS_EPVersion
		StructVer				;EUS_Version,EUS_Revision
		dc.l	MyMenuName			;EUS_Username
		dc.w	0				;EUS_WinX
		dc.w	0				;EUS_WinY
		dc.w	EUSB_Openwin			;EUS_Flags
		dc.w	0				;EUS_Special
		dc.w	0				;EUS_Special+2
		dc.l	0				;EUS_Special2
		dc.l	0				;EUS_Special3
		StructDate				;EUS_Creatordate
		dc.b	0				;EUS_Priority
		dc.b	EUTY_Converter			;EUS_type
		dc.w	0				;EUS_Reserved2
		dc.l	0				;EUS_Reserved3
		dc.l	0				;EUS_Reserved4
		dc.l	0				;EUS_Reserved5
		dc.l	0				;EUS_Reserved6

		ifne	(*-EUS_Structure)-EUS_SizeOF
		Aber Hallo
		endc

	dc.b	"$VER: Eagleplayer-Noiseconverter "
	ver
	dc.b	" ("
	date
	dc.b	")",0
	even

		ifeq	Executable
FirstEagleInit:	lea	EaglePuffer,a5
		move.l	a5,EUS_EPBase+EUS_Structure

		lea	MyIntuiname,a1
		move.l	4,a6
		moveq	#37,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,DTG_Intuitionbase(a5)

		lea	MyGFXname,a1
		moveq	#37,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,DTG_GFXbase(a5)

		lea	MyGadToolsname,a1
		moveq	#37,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,DTG_GadToolsbase(a5)

		lea	MyLocalename,a1
		moveq	#37,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,EPG_Localebase(a5)

		lea	MyDosname,a1
		moveq	#37,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,DTG_Dosbase(a5)

		lea	EP_List1,a0
		move.l	a0,EPG_ModulesList(a5)
		newlist a0
		lea	EP_List1,a0
		lea	EP_Entry1,a1
		move.l	#Name1,LN_Name(a1)
		addtail	a0,a1

		lea	EP_List1,a0
		lea	EP_Entry2,a1
		move.l	#Name2,LN_Name(a1)
		addtail	a0,a1

		lea	EP_List1,a0
		lea	EP_Entry3,a1
		move.l	#Name3,LN_Name(a1)
		addtail	a0,a1
		lea	Puffer,a5
		rts

MyIntuiname:	dc.b	"intuition.library",0
MyGFXname:	dc.b	"graphics.library",0
MyGadtoolsname:	dc.b	"gadtools.library",0
MyLocalename:	dc.b	"locale.library",0
MyDosname:	dc.b	"dos.library",0
Name1:		dc.b	"Module1",0
Name2:		dc.b	"Module2",0
Name3:		dc.b	"Module3",0

TestList:	dc.b	"MODLIST",10
		dc.b	"Modules:Agnostica",10
		dc.b	"'EP:Test' MP:01=1,02='8-Bit Amplifier',03='Animal'",10
		dc.b	'":Test3"'
TestListSize	= *-Testlist

		even
EaglePuffer	ds.b	EPG_SizeOf

EP_List1	ds.b	LH_Size
EP_Entry1	ds.b	LN_Size
EP_Entry2	ds.b	LN_Size
EP_Entry3	ds.b	LN_Size

		endc


*-----------------------------------------------------------------------------*
TagListe:	dc.l	EUT_ConvertModule,ConvertModule
		dc.l	EUT_ExitEngine,ExitEngine
		dc.l	EUT_SpecialinfoLNr,LNrE_SpecialInfo_NoiseConverter
		dc.l	0

*-----------------------------------------------------------------------------*
CopyEPBase:	movem.l	d0-a6,-(a7)
		move.l	EUS_Structure+EUS_EPBase(pc),a0
		move.l	a5,a1
		move.w	#EPG_SizeOf-1,d0
.CopyEP:	move.b	(a0)+,(a1)+
		dbf	d0,.CopyEP
		movem.l	(a7)+,d0-a6
		rts

*-----------------------------------------------------------------------------*
ExitEngine:	lea	Puffer(pc),a5
		bsr	CopyEPBase
		bsr	FreeConverter
		moveq	#0,d0
		rts

*-----------------------------------------------------------------------------*
FreeConverter:	movem.l	d0-a6,-(a7)
		lea	FirstConverter(a5),a3
		move.l	(a3),d0
.NextConverter:	tst.l	d0
		beq.s	.Return
		move.l	d0,a3
		move.l	CS_Segment(a3),d1
		beq.s	.NoSegment
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOUnLoadSeg(a6)
.NoSegment:	move.l	CS_StructSize(a3),d0
		move.l	a3,a1
		move.l	(a3),d3
		move.l	4,a6
		jsr	_LVOFreemem(a6)
		move.l	d3,d0
		bra.s	.NextConverter

.Return:	movem.l	(a7)+,d0-a6
		rts

*-----------------------------------------------------------------------------*
* Input: a0=Adr der Datei
*	 d0=Size der Datei
* Output:d0=ConvertSize oder NULL
*	 d1=Flags
*	 d2=MemSize
*	 a0=ConvertAdr
*	 a1=Formatname
*	 a2=SamplePtr (für Protrackerclones) oder NULL
*-----------------------------------------------------------------------------*
ConvertModule:	lea	Puffer(pc),a5
		bsr	CopyEPBase
		bsr	LadeConverter

		*-- Nun Schleife der Converter --*
		move.l	d0,d4
		move.l	a0,a4
		lea	FirstConverter(a5),a3
.Next:		move.l	(a3),d0
		beq.w	.Error
		move.l	d0,a3

		move.l	CS_Tags(a3),ConverterTags(a5)

.NextTag:	ifeq	Executable
		move.l	#CV_ConverterName,d0
		move.l	ConverterTags(a5),a6
		bsr	FindTag
		move.l	a6,a1
		endc

		move.l	#CV_Convert,d0
		move.l	ConverterTags(a5),a6
		bsr	FindTag
		tst.l	d2
		bne.w	.EPFound

		move.l	#DTP_Convert,d0
		move.l	ConverterTags(a5),a6
		bsr	FindTag
		tst.l	d2
		beq.s	.TestCVNext

		*--- Delitrackerconverter ---*
		clr.l	MemPuffer(a5)
		clr.l	MemPuffer+4(a5)
		move.l	#AllocListData,DTG_AllocListData(a5)
		move.l	#FreeListData,DTG_FreeListData(a5)
		move.l	a4,DTG_CHkData(a5)
		move.l	d4,DTG_ChkSize(a5)
		movem.l	d3-d7/a3-a6,-(a7)
		jsr	(a6)
		movem.l	(a7)+,d3-d7/a3-a6
		tst.l	d0
		bne.s	.TestCVNext
		move.l	MemPuffer(a5),a0
		move.l	MemPuffer+4(a5),d0
		move.l	d0,d2
		add.l	#SecurityMem,d2

		movem.l	d0-d2/a0/a2,-(a7)
		move.l	#DTP_Formatname,d0
		move.l	ConverterTags(a5),a6
		bsr	FindTag
		sub.l	a1,a1
		tst.l	d2
		beq.s	.NoName
		move.l	(a6),a1
.NoName:	movem.l	(a7)+,d0-d2/a0/a2
		sub.l	a2,a2
		moveq	#CVF_FreeOriginal,d1		;freigeben ?
		bra.s	.ok

.TestCVNext:	move.l	ConverterTags(a5),a6
		move.l	#CV_Next,d0
		bsr	FindTag
		beq.w	.Next
		move.l	a6,ConverterTags(a5)
		bra.w	.NextTag



		*--- Eagleplayerconverter ---*
.EPFound:	movem.l	d3-d7/a3-a6,-(a7)
		move.l	d4,d0
		move.l	a4,a0
		jsr	(a6)
		movem.l	(a7)+,d3-d7/a3-a6
.Ok		tst.l	d0
		beq.w	.TestCVNext
		rts

.Error:		moveq	#0,d0
		rts

*-----------------------------------------------------------------------------*
* Normalerweise wird hier der Memblock rangehängt. Lassen wir mal weg
* Input: d0=Memsize
*	 d1=Eigenschaften
* Output:d0=MemAdr oder NULL
*-----------------------------------------------------------------------------*
AllocListData:	movem.l	d1-a6,-(a7)
		move.l	d0,d4
		tst.l	MemPuffer(a5)
		bne.s	.Error
		add.l	#SecurityMem,d0
		lea	Puffer(pc),a5
		move.l	4,a6
		jsr	_LVOAllocMem(a6)
		move.l	d0,MemPuffer(a5)
		move.l	d4,MemPuffer+4(a5)
.Return:	movem.l	(a7)+,d1-a6
		tst.l	d0
		rts

.Error:		moveq	#0,d0
		bra.s	.Return
*-----------------------------------------------------------------------------*
* Der Memblock wird normalerweise in der Liste gesucht.
* Input: a0=Adresse des Memblocks
*-----------------------------------------------------------------------------*
FreeListData:	movem.l	d0-a6,-(a7)
		lea	Puffer(pc),a5
		cmp.l	MemPuffer(a5),a1
		bne.s	.Return
		move.l	MemPuffer+4(a5),d0
		beq.s	.Return
		add.l	#SecurityMem,d0
		move.l	4,a6
		jsr	_LVOFreeMem(a6)
.Return:	clr.l	MemPuffer(a5)
		clr.l	MemPuffer+4(a5)
		movem.l	(a7)+,d0-a6
		rts

*-----------------------------------------------------------------------------*
LadeConverter:	movem.l	d0-a6,-(a7)
		tst.w	ConverterLoaded(a5)
		bne.w	.NoEngineDir

	if	Executable
		move.l	EUS_Structure+EUS_EPBase(pc),a4
		move.l	EPG_EngineDirArrayPtr(a4),d1
		beq.s	.NoConfigDir
	else
		move.l	#Enginedir,d1
	endc
		move.l	DTG_Dosbase(a5),a6
		moveq	#-2,d2
		jsr	_LVOLock(a6)
		move.l	d0,d1
		beq.s	.NoConfigDir
		jsr	_LVOCurrentDir(a6)
		move.l	d0,d1

		*--- NoiseConverterDir setzen ---*
.NoConfigDir:	move.l	d1,-(a7)
		lea	NoiseConverters(pc),a0
		move.l	a0,d1
		move.l	DTG_Dosbase(a5),a6
		moveq	#-2,d2
		jsr	_LVOLock(a6)
		move.l	d0,d6
		beq.s	.FreeEngineDir
		move.l	d6,d1
		jsr	_LVOCurrentDir(a6)
		move.l	d0,-(a7)

		moveq	#DOS_FIB,d1
		moveq	#0,d2
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOAllocDosObject(a6)
		move.l	d0,a4
		tst.l	d0
		beq.w	.FreeNoiseDir

		bsr	LadeNunConverter

		moveq	#DOS_FIB,d1
		move.l	a4,d2
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOFreeDosObject(a6)


.FreeNoiseDir:	move.l	(a7)+,d1
		beq.s	.NoNoiseDLock
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOCurrentDir(a6)
.NoNoiseDLock:	move.l	d6,d1
		beq.s	.FreeEngineDir
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOUnLock(a6)

.FreeEngineDir:	move.l	(a7)+,d1
		tst.l	d1
		beq.s	.NoEngineDir
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOCurrentDir(a6)
		move.l	d0,d1
		jsr	_LVOUnlock(a6)

.NoEngineDir:	move.w	#1,ConverterLoaded(a5)
		movem.l	(a7)+,d0-a6
		rts

*-----------------------------------------------------------------------------*
* Input: a4=FIB
*	 d6=Handle
LadeNunConverter:
		movem.l	d0-a6,-(a7)

		move.l	a4,d2
		move.l	d6,d1			;Error beim Lock holen
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOExamine(a6)
		tst.l	d0
		beq.w	.Return


		lea	FirstConverter(a5),a2
.ExNext:	move.l	d6,d1			*Handle
		move.l	a4,d2
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOExNext(a6)
		tst.l	d0
		beq.w	.Return

		moveq	#CS_SizeOF,d0
		move.l	4,a6
		move.l	#$10000,d1
		jsr	_LVOAllocMem(a6)
		move.l	d0,a3
		tst.l	d0
		beq.w	.Error
		move.l	#CS_SizeOF,CS_StructSize(a3)

		*--- Namen kopieren ---*
		lea	fib_filename(a4),a0
		move.l	a0,d1
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOLoadSeg(a6)
		move.l	d0,CS_Segment(a3)
		tst.l	d0
		beq.w	.Error

		*---- Testen, ob Segment erlaube ist --*
		addq.l	#1,d0
		asl.l	#2,d0
		move.l	d0,a0

		*--- Eagleplayerconverter ---*
		cmp.l	#$70ff4e75,(a0)
		bne.w	.Error
		cmp.l	#"EP_C",8(a0)
		bne.s	.TestDeli
		cmp.l	#"ONVE",12(a0)
		bne.s	.TestDeli
		cmp.l	#"RTER",16(a0)
		bne.s	.TestDeli
		cmp.l	#"MODU",20(a0)
		bne.s	.TestDeli
		cmp.l	#"LE"<<16,24(a0)
		bne.s	.TestDeli
		move.l	4(a0),CS_Tags(a3)
		move.l	CS_Tags(a3),a6
		move.l	#CV_Convertername,d0
		bsr	FindTag
		move.l	a6,CS_Convertername(a3)
		bra.s	.Ok


		*--- Delitracker Genie ---*
.TestDeli:	cmp.l	#"DELI",4(a0)
		bne.w	.FreeSegment
		cmp.l	#"RIUM",8(a0)
		bne.s	.FreeSegment
		move.l	12(a0),CS_Tags(a3)

		move.l	CS_Tags(a3),a6
		move.l	#DTP_Playername,d0
		bsr	FindTag
		move.l	a6,CS_Convertername(a3)

		*--- Nun für beide Convertertypen fortfahren ---*
.OK:		move.l	CS_Tags(a3),a6
		move.l	#CV_RequestConverter,d0
		bsr	FindTag
		move.l	a6,d1
		cmp.l	#ConverterVersion,d1
		bhi.s	.FreeSegment

		move.l	CS_Tags(a3),a6
		move.l	#EP_Eaglebase,d0
		bsr	FindTag
		tst.l	d2
		beq.s	.NoEagleBase
		move.l	a5,(a6)

.NoEagleBase:	move.l	CS_Tags(a3),a6
		move.l	#DTP_Delibase,d0
		bsr	FindTag
		tst.l	d2
		beq.s	.NoDeliBase
		move.l	a5,(a6)
.NoDeliBase:	move.l	CS_Tags(a3),a6
		move.l	#CV_Eaglebase,d0
		bsr	FindTag
		tst.l	d2
		beq.s	.NoEagle2Base
		move.l	EUS_Structure+EUS_EPBase(pc),(a6)
.NoEagle2base:

		*-- in Liste einfügen --*
		move.l	(a2),d0
		move.l	a3,(a2)
		move.l	d0,(a3)
		move.l	a3,a2
		bra.w	.ExNext


.FreeSegment:	move.l	CS_Segment(a3),d1
		beq.s	.Error
		move.l	DTG_Dosbase(a5),a6
		jsr	_LVOUnLoadSeg(a6)
		clr.l	CS_Segment(a3)
.Error:		move.l	a3,a1
		move.l	CS_StructSize(a3),d0
		beq.s	.NoFree
		move.l	4,a6
		jsr	_LVOFreeMem(a6)
.NoFree		bra.w	.ExNext

.Return:	movem.l	(a7)+,d0-a6
		rts

*-----------------------------------------------------------------------------*
FindTag:
FindTag2:	move.l	d3,-(a7)
		move.l	a7,d3

	*--------- Recursive FindTag-Routine ----------*
FindTag3:	moveq	#0,d2
		cmp.l	a6,d2
		beq.s	.Empty
		move.l	(a6)+,d2			;Tag rauslesen
		bne.s	.NoEmpty
.Empty:		cmp.l	d3,a7				;ak. Stack vergleichen
		beq.s	.TagNoFound
		move.l	(a7)+,a6
		bra.b	.NoMore
.NoEmpty:	cmp.l	d2,d0
		beq.s	.TagFound

	*----- Tag-Skip gefunden ???? -----*
		cmp.l	#Tag_Skip,d2
		bne.s	.NoSkip
		addq.l	#8,a6				;Diesen und nächsten
		addq.l	#4,a6				;Tag überspringen
		bra.s	.NoMore

	*------ Tag-More gefunden ???? -----*
.NoSkip:	cmp.l	#Tag_More,d2
		bne.s	.NoMore

		move.l	a6,-(a7)		;Adr der Tagliste sichern
		move.l	(a6),a6			;Neue Tagliste setzen
		bra.b	FindTag3
.NoMore:	addq.l	#4,a6
		bra.s	FindTag3
.TagFound:	move.l	(a6),a6
		move.l	a6,d2
.TagNoFound:	move.l	d3,a7
		move.l	(a7)+,d3
		tst.l	d2
		bne.s	.NoNull
		sub.l	a6,a6
.NoNull:	tst.l	d2
		rts


*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
*----------------------------------------------------------------------------*
Puffer		ds.b	PufferEnd

	*----------------- Informationstexte ---------------------*
NoiseConverters:dc.b	"NoiseConverters",0
MyMenuName:	dc.b	"Noiseconverter",0
MyCreatorname:	dc.b	"Eagleeye of DEFECT",0
MySpecialInfo:	dc.b	"This engine converts rare soundformate into "
		dc.b	"common formats for instance Protracker.",0
		ifeq	Executable
Enginedir	dc.b	"EP:Engines",0
		endc

		even
		ifeq	Executable
data:		incdir	modules:
		*incbin	Mod.Agnostica.exam		;Example
		incbin	Mod.Agnostica.exa2		;Example
		*incbin	S+S.Oriental			;Converter


		incdir	"Modules:Trackerclones/"	;Deli-Wizard
		*incbin	"HCD.Blue_Vibrations"
		*incbin	"HCD.South Of Sense"
		*incbin	"KURT.Heavy_Metal"



datasize	= *-data
		endc


