
/************************************************************************/
/* play_c (tom_tracker!)						*/
/* 21/01/90								*/
/* replay de soundtracker en C, doit etre linker avec le fichier	*/
/* normalreplay.s							*/
/* Fenetre avec pw2.5, info sur la arp.library par Commodore Revue	*/
/************************************************************************/


#include <exec/types.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <graphics/gfxbase.h>
#include <hardware/custom.h>
#include <hardware/intbits.h>
#include "intuition/intuition.h"
#include <workbench/startup.h>
#include <stdio.h>
#include <hardware/cia.h>
#include <devices/input.h>
#include "ppdata.h"

extern	struct	CIA	far ciab;
extern	struct	WBStartup *WBenchMsg;

#define	OK	1
#define	NOK	0
#define reg register
#define	FREQU_PAL	1773447/125
#define FREQU_NTSC	1789773/125

int	num_musique=0;

/* Types de replay routine */
typedef enum{
	UNDEF,
	 NOISETRACKER,
	STK,
	JAMCRACK,
	FUTURE,
	STARTREKKER,
	SOUNDMON,
	DELTA,
	SIDMON,
	MARKII,
	FRED,
	TFMX,
	PACKED,
	PP
}type_replay;

#include	<libraries/reqbase.h>

#ifdef	LATTICE
#include	<proto/all.h>
#endif

#define SIZE_INFO	2000

#define OFF_STAR        0x438
#define OFF_JAM         0x0
#define	OFF_STK		0x438
#define	OFF_SOUND	0x1a
#define	OFF_DELTA	0x51c
#define OFF_PACKED	0x1f6

extern   void interrupt_music();

extern	void	pp_init(),pp_music(),pp_end();
extern	void	fc_init(),fc_music(),fc_end();
extern	void	st_init(),st_music(),st_end();
extern	void	sm_init(),sm_music(),sm_end();
extern	void	mt_init(),mt_music(),mt_end();
extern	void	dlt_init(),dlt_music(),dlt_end();
extern	void	sid_init(),sid_music(),sid_end();
extern	void	mkii_init(),mkii_music(),mkii_end();
extern	void	fred_init(),fred_music(),fred_end();
extern	void	tfmx_init(),tfmx_music(),tfmx_end();
extern	void	pack_init(),pack_music(),pack_end();

void	(*old_end)();

typedef	struct{
	type_replay type_replay;
	void	(*p_start)();
	void	(*p_music)();
	void	(*p_end)();
	int     offset;
        char    *p_ident;
	char	*p_name;

}routine_replay;

/* IMPORTANT NOTE: since 0 is the end of string charactere, if you want */
/* to find a pattern conataining 0, you must use the sequence: '/',0	*/
/* if you want to put '/', just do '/','/'				*/

char	sidmon[]={'A',0xfa,0x0f,0xfa,0};
char	markii[]={0x48,0xe7,'/',0,0xf0,0x41,0xfa,0x03,0x5e,0};
char	fred[]=  {0x4e,0xfa,'/',0,0x4e,0x4e,0xfa,'/',0,0xcc,0};

routine_replay	tab_replay[]={

 {NOISETRACKER,	mt_init,  mt_music,  mt_end, OFF_STK,  "M.K.", "NOISETRACKER"},
 {STARTREKKER,	st_init,  st_music,  st_end, OFF_STAR, "EXO4", "STARTREKKER"},
 {NOISETRACKER,	st_init,  st_music,  st_end, OFF_STK,  "FLT4", "NOISTRACKE"},
 {JAMCRACK,	pp_init,  pp_music,  pp_end, OFF_JAM,  "BeEp", "JAMCRACKER"},
 {FUTURE,	fc_init,  fc_music,  fc_end, 0,        "FC12", "FUTURE_COMPOSER"},
 {SOUNDMON,	sm_init,  sm_music,  sm_end, OFF_SOUND,"V.2",  "SOUDMON"},
 {DELTA,	dlt_init, dlt_music, dlt_end,OFF_DELTA,"TA1A", "DELTA"},
 {SIDMON,	sid_init, sid_music, sid_end,0,	       sidmon, "SIDMON"},
 {MARKII,	mkii_init,mkii_music,mkii_end,0,       markii, "MARKII"},
 {MARKII,	mkii_init,mkii_music,mkii_end,0,       markii, "MARKII"},
 {FRED,		fred_init,fred_music,fred_end,0,       fred,   "FRED!!!"},
 {TFMX,		tfmx_init,tfmx_music,tfmx_end,0,       "TFMX", "TFMX"},
 {PACKED,	pack_init,pack_music,pack_end,OFF_PACKED,"PATT","PACKED NOISETRACKER"},
 {PP,		NULL,	  NULL,      NULL,   0,        "PP20", "PP"},
 {PP,		NULL,	  NULL,      NULL,   0,        "PP11", "PP"},
 {UNDEF,	NULL,	  NULL,      NULL,   NULL,     NULL,   0}
};


USHORT	quit_flag = FALSE;
USHORT	flag_out;
int	type_replay=UNDEF;
int	num_replay=0;
struct  Interrupt *my_interrupt=NULL;
struct	Library *myCiaPointer;

int	flg_fast=FALSE;

/* Pointeur sur les donnes soundtrack */
int	*adr_data=NULL;
int	*adr_data2=NULL;

int	size_file,size_read,size_file2;
int	my_data;

struct Interrupt myhandler;		/* input handler */
struct Interrupt handlerstuff;

void	read_file_nt();  
void	read_file_tfmx();  
int	setup();
void	stop();
void	main_loop();

char	*portname="Multi replay";

struct	MsgPort *port = NULL;
struct	IOStdReq *inputreq = NULL;
UBYTE	inputopen = FALSE;

struct	my_data{
	struct	Task	*task;
	int		sigbit;
};

struct my_data	my_info;
struct Window *OpenWindow();
struct Window *wG;	/* we fetch the RastPort pointer from here */
struct IntuitionBase *IntuitionBase=0;
struct GfxBase  *GfxBase=0;
struct ReqBase	*ReqBase;
int		frequ=0;


struct FileRequester	MyFileReqStruct;
char fname[FCHARS];
char directoryname[DSIZE];
char	answerarray[DSIZE+FCHARS];

struct NewWindow IcoWindow = {
	10,200,	/* window XY origin relative to TopLeft of screen */
	50,30,/* window width and height */
	0,1,	/* detail and block pens */
	MOUSEBUTTONS+CLOSEWINDOW,/* IDCMP flags */
	WINDOWDRAG+ACTIVATE+NOCAREREFRESH,	/* other window flags */
	NULL,	/* first gadget in gadget list */
	NULL,	/* custom CHECKMARK imagery */
	"Ico",	/* window title */
	NULL,	/* custom screen pointer */
	NULL,	/* custom bitmap */
	5,5,	/* minimum width and height */
	-1,-1,	/* maximum width and height */
	WBENCHSCREEN	/* destination screen type */
};


void	My_FreeMem(p_adr_data,size)
char	**p_adr_data;
int	size;
{
/*
	printf("FreeMem de %lx taille:%d\n",*p_adr_data,size);
*/
	if(*p_adr_data!=NULL){
		FreeMem(*p_adr_data,size);
		*p_adr_data=NULL;
	}
}
char	*My_AllocMem(size,req,p_res)
int	size;
int     req;
char	**p_res;
{
	char *p_ret;
	if(*p_res!=NULL){

		printf("ERREUR!allocmem sur qq chose de deja allouer!\n");

		My_FreeMem(p_res,size);
	}
	p_ret=(char *)AllocMem(size,req);
/*
	printf("AllocMem de %lx taille:%d\n",p_ret,size);
*/
	return(p_ret);
}

/* This is for the event handler */
void quit(object)
APTR object;
{
	quit_flag = TRUE;
	flag_out=TRUE;
/*
	stop(&my_interrupt);
*/
}
/* This is for the event handler */
void new(object)
APTR object;
{
	flag_out=TRUE;
}
void info();
void ico();

/* This is for the event handler */
void fast(object)
APTR object;
{
	int  frequ2;
	if(flg_fast==TRUE){
		frequ2=frequ;
		flg_fast=FALSE;
	}else{
		frequ2=frequ/4;
		flg_fast=TRUE;
	}
	ciab.ciatalo=(UBYTE)(frequ2 & 0xff);
	ciab.ciatahi=(UBYTE)((frequ2>>8) & 0xff);
}


/* get the PowerWindows 2.0 code */
#include "window.h"
#include "requ_window.h"


/**********************************************************/
/* Cette routine initialise le CIA a la frequence desiree */
/**********************************************************/

int SetCIAInt()
{
	int code_ret;

	if( (GfxBase->DisplayFlags & PAL) !=0){
		sprintf(RequIText8.IText,"PAL");
		frequ=FREQU_PAL;
	}else if( (GfxBase->DisplayFlags & NTSC) !=0){
		sprintf(RequIText8.IText,"NTSC");
		frequ=FREQU_NTSC;
	}	
	myCiaPointer=(struct Library *)OpenResource("ciab.resource");
	if(myCiaPointer==NULL){
		printf("Erreur ouverture ciab!\n");
		code_ret=FALSE;
	}else{
		code_ret=TRUE;;
	}
	return(code_ret);
}

/*******************************************************/
/* Affiche une fenetre et attemd que lon clique dessus */
/* et affiche aussi le texte intuition passe en param  */
/*******************************************************/

void   show_window(p_newwindow,p_IText)
struct NewWindow *p_newwindow;
struct IntuiText *p_IText;
{	
	struct Window *p_wG;

	NewWindowStructure1.LeftEdge=wG->LeftEdge;
	NewWindowStructure1.TopEdge=wG->TopEdge;
	CloseWindow(wG);
	if( (p_wG = OpenWindow(p_newwindow)) !=0){
		if(p_IText!=NULL){
			PrintIText(p_wG->RPort,p_IText,0,0);
		}
		WaitPort(p_wG->UserPort);
		p_newwindow->LeftEdge=p_wG->LeftEdge;
		p_newwindow->TopEdge =p_wG->TopEdge;
		CloseWindow(p_wG);
	}else{
		printf("Ouverture deuxieme fenetre NOK!\n");
	}
	wG = OpenWindow(&NewWindowStructure1);	/* open the window */
	if ( wG == NULL )
	{
		printf ("open window2 failed GROSSE ERREUR!\n");
		exit(0);
	}
}
/* This is for the event handler */
void info(object)
APTR object;
{
	show_window(&RequNewWindowStructure1,&RequIText2);
}

/* This is for the event handler */
void ico(object)
APTR object;
{
	show_window(&IcoWindow,NULL);
}

/*********************************************/
/* Test un fichier contient un type de module*/
/* que l'on connait.			     */
/*********************************************/

int tst_file_type(p_filename,p_num_routine)
char *p_filename;
int  *p_num_routine;
{
   int code_ret;
   char	*p_module;
   struct FileLock *my_lock;

   code_ret=UNDEF;
   if( (my_lock = (struct FileLock *)Open (p_filename, MODE_OLDFILE))==NULL){
	printf("Ouverture NOK....Erreur!\n");
   }else{
	p_module=(char *)malloc(SIZE_INFO);
        if( Read(my_lock,(char *)p_module,SIZE_INFO) == SIZE_INFO){
		code_ret=tst_type(p_module,p_num_routine);
	}
	Close(my_lock);
	free(p_module);
   }

   return(code_ret);
}

/************************************************************************/
/* Cette routine teste le type du module, et retourne le type de module */
/* si on le connait, UNDEF sinon         				*/
/************************************************************************/

tst_type(p_module,p_num_routine)
char	*p_module;
int  *p_num_routine;
{
	int code_ret;
	char *tempo_p,*p_pattern;
	int i,n;
	code_ret=UNDEF;
	i=0;
        do{
	     p_pattern=tab_replay[i].p_ident;
             tempo_p=p_module+tab_replay[i].offset;
             n=0;
             while( (p_pattern[n] == tempo_p[n]) && (p_pattern[n+1]!=0)){
		n++;
		if( p_pattern[n+1]=='/'){
			*p_pattern++;
		}
	     }

   	     if( p_pattern[n+1]==0){
#ifdef DEBUG
		printf("Replay found:%s\n",tab_replay[i].p_name);
#endif
                code_ret=tab_replay[i].type_replay;
		*p_num_routine=i;
             }
	     i++;
	}while((tab_replay[i].type_replay!=UNDEF) && (code_ret==UNDEF));
	return(code_ret);
}

/**********************************************************/
/* This is the input event handler. I use special keyword */
/* of the Lattice compiler. If you doesn't have these,you */
/* must write it in ASM!				  */
/**********************************************************/

struct InputEvent * __saveds __asm myproc_Handler
			(reg __a0 struct InputEvent *ev,reg __a1 struct my_data *info)
{
	struct InputEvent *inev;

	inev = ev;
	while (ev) {
		if( (ev->ie_Qualifier &(IEQUALIFIER_LEFTBUTTON + IEQUALIFIER_RBUTTON ))==
		    ( IEQUALIFIER_LEFTBUTTON + IEQUALIFIER_RBUTTON )){
				Signal(info->task,1<<info->sigbit);
			}
		ev = ev->ie_NextEvent;
	}
	return (inev);
}

/********************************************************/
/* This is the initialisation of my input event handler */
/********************************************************/

int	init_input_ev()
{
	my_info.sigbit=AllocSignal(-1);
	if(my_info.sigbit==-1){
		return(NOK);
	}
	my_info.task=(struct Task *)FindTask(0);

	if ( (inputreq = (struct IOStdreq *)CreateStdIO (port)) ==NULL){
		return(NOK);
	}
	inputopen = OpenDevice ("input.device", 0L, inputreq, 0L);
	if ( inputopen !=0 ){
		return(NOK);
	}

	myhandler.is_Code = (void (*)())myproc_Handler;
	myhandler.is_Data =(APTR)&my_info;
	myhandler.is_Node.ln_Pri = 51;
	inputreq->io_Command = IND_ADDHANDLER;
	inputreq->io_Data =(APTR) &myhandler;
	DoIO (inputreq);

	return(OK);
}

/******************************************************************/
/* This is the liberation of the previously allocated ressources  */
/* of the input event						  */
/******************************************************************/

void	free_input_ev()
{
	if(inputreq){
		inputreq->io_Command = IND_REMHANDLER;
		inputreq->io_Data = (APTR)&myhandler;
		DoIO (inputreq);
	}
	if (!inputopen) CloseDevice (inputreq);
	if(inputreq)DeleteStdIO (inputreq);
	if(my_info.sigbit!=-1)FreeSignal(my_info.sigbit);
} 

int FileRequest()
	{

	answerarray[0] = 0;

		/* Initialize the 'PathName' field so that the file requester will */
		/* construct a complete path name for me.  It will also put the two */
		/* parts of the answer (directory and file name) into the directory */
		/* file name which I also decided to supply it with.  Since the */
		/* directory and file name arrays are present, it will use their */
		/* initial contents as the initial file and directory.  If they aren't */
		/* present it will leave both blank to start. */
	MyFileReqStruct.PathName = answerarray;
	MyFileReqStruct.Dir = directoryname;
	MyFileReqStruct.File = fname;

		/* The directory caching of this file requester is one of its nice */
		/* features, so I decided to show it off.  It is completely optional */
		/* though, so if you don't want it, don't set this flag.  If you do */
		/* want it, don't forget to call PurgeFiles() when you are done. */
	MyFileReqStruct.Flags = FRQCACHINGM;

		/* Initialize a few colour fields.  Not strictly necessary, but */
		/* personally, I like having my files a different colour from my */
		/* directories. */
	MyFileReqStruct.dirnamescolor = 2;
	MyFileReqStruct.devicenamescolor = 2;
		/* I could also make it larger, pass it a file and/or directory */
		/* name, set the window title, set various flags and customize */
		/* in many other ways, but I wanted to show that it can be easily */
		/* used without having to fill in a lot of fields. */
	if (FileRequester(&MyFileReqStruct)){
		return(1);
	}else{
		return(0);
	}
}

/***********************/
/* PROGRAMME PRINCIPAL */
/***********************/

main(argc,argv)
int   argc;
char  **argv;

{
   struct  MsgPort *port_find;
   int     sig_recu;

   struct WBArg *arg;
   LONG   olddir;
   int	i;

   ReqBase = (struct ReqBase *)OpenLibrary("req.library", 0L);
   if(ReqBase==NULL){
	printf("Shit, I Can't open req.library!\n");
	goto cleanup1;
   }
   IntuitionBase = OpenLibrary("intuition.library", 0);
   if (IntuitionBase == NULL)
   {
	printf("intuition is not here.  where are we?\n");
	goto cleanup1;
   }
   GfxBase =(struct GfxBase *)OpenLibrary("graphics.library", 0);
   if (GfxBase == NULL)
   {
	printf("gfx is not here.  where are we?\n");
	goto cleanup1;
   }

   /* If the port is already existing, we send a signal to tell the */
   /* active multi_player to stop. If it stop, it remove the port   */
   /* If after sending the signal, the port is still here, this mean*/
   /* that the other nulti_player was running with a window, so you */
   /* can't stop like this                                          */

   if( (port_find=FindPort (portname)) !=NULL){
	Signal(port_find->mp_SigTask,1<<port_find->mp_SigBit);
	Delay(2);
   }
   if( FindPort (portname) !=NULL){
	SimpleRequest("Sorry, there is another multi_player running");
	goto cleanup1;
   }else if((port=(struct MsgPort *)CreatePort (portname, 0L)) ==NULL){
	goto cleanup1;
   }
   if(SetCIAInt() == FALSE){
	goto cleanup1;
   }
   /********************************************************************/
   /* If the programm have an argument, we assume that's a module name */
   /********************************************************************/

   if( (argc>1) || ( (WBenchMsg->sm_NumArgs>1)&&(argc==0)) ){
	sig_recu=0;
	if(init_input_ev()==OK){

		/* There is on signal waiting, so we remove it */
		Wait(1<<port->mp_SigBit);

		if(argc>1){
			/***********************/
			/* It was run from CLI */
			/***********************/

			for(	i=1;
				(i<argc) && (sig_recu != 1<<port->mp_SigBit);
				i++
			){
#ifdef DEBUG
				printf("argv:%s\n",argv[i]);
#endif
				play_module(argv[i],&my_interrupt);
				if(type_replay!=UNDEF){
					sig_recu=Wait((1<<my_info.sigbit) | (1<<port->mp_SigBit));
	 			}
			}
		}else{
			/***********************/
			/* It was run from WB  */
			/***********************/

		        for(	i=1,arg=WBenchMsg->sm_ArgList,arg++;
				(i<WBenchMsg->sm_NumArgs) && (sig_recu!=1<<port->mp_SigBit);
				i++,arg++
			){

				olddir=CurrentDir(arg->wa_Lock);
				play_module(arg->wa_Name,&my_interrupt);
				if(type_replay!=UNDEF){
					sig_recu=Wait((1<<my_info.sigbit) | (1<<port->mp_SigBit));
				}
				CurrentDir(olddir);
			}
		}
	}
	free_input_ev();
   }else{

	/********************************************************/
	/* The programm is run with no argument, so we open the */
	/* window and ask for a file to load!			*/
	/********************************************************/

	wG = OpenWindow(&NewWindowStructure1);	/* open the window */
	if ( wG == NULL )
	{
		printf ("open window failed\n");
		goto cleanup1;
	}else{

	   do{

        	/***************************************************/
		/* We ask the user for a file to load. If he gives */
		/* one, we try to load it and to play it	   */
        	/***************************************************/

		if(FileRequest() !=0 ){
			play_module(answerarray,&my_interrupt);
	
		}
		main_loop(num_replay);

	   }while(quit_flag == FALSE);
	}
    }

cleanup2:
   if ( wG != NULL) CloseWindow(wG);
cleanup1:
   stop(&my_interrupt);
   if(type_replay!=UNDEF){
	   exec_safe(tab_replay[num_replay].p_end);
   }

   /**************************************************/
   /* If memory was previously allocated, we free it */
   /**************************************************/

   My_FreeMem(&adr_data,size_file);
   My_FreeMem(&adr_data2,size_file2);

   if (port) DeletePort (port);

   if (ReqBase != NULL)   CloseLibrary(ReqBase);
   if (GfxBase != NULL)   CloseLibrary(GfxBase);
   if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
   return(0);

}

/**************************************************************/
/* This function load a module and activate the interrupt     */
/* handler with the correct replayroutine                     */
/**************************************************************/
/* p_name=pointer to the filename                             */
/* pp_interrupt=pointer to the var containing the interrupt struct */

int play_module(p_name,pp_interrupt)
char *p_name;
struct   Interrupt **pp_interrupt;
{
       int err;

	if(type_replay!=UNDEF){
		old_end=tab_replay[num_replay].p_end;
	}
	type_replay=tst_file_type(p_name,&num_replay);

        /************************************************/
	/* Si il y a un fichier de charge, on l'execute */
        /************************************************/

	if(type_replay!=UNDEF){

	    /*****************************************************/
	    /* Si l'on etait en train de jouer qq chose, on stop */
	    /*****************************************************/

	    if(old_end!=NULL){
		exec_safe(old_end);
	    }

	    stop(pp_interrupt);


	    /***************************************/
	    /* Si c'est du powerpacker, on charge! */
	    /***************************************/
	    My_FreeMem(&adr_data,size_file);
   	    
	    err = PP_LoadData (p_name, DECR_POINTER,
            			MEMF_PUBLIC+MEMF_CHIP, &adr_data, &size_file, NULL); 
	    if (err == PP_LOADOK) {                                      
	    	    if(type_replay==PP){
			type_replay=tst_type(adr_data,&num_replay);
		    }                                                         
	    }else{
		if(err==PP_LOCKERR){
			SimpleRequest("File:%s not found!",p_name);
		}
		My_FreeMem(&adr_data,size_file);
	    }

	    /********************************************************/
	    /* Si tout est bien charge,  et si le replay est defini,*/
	    /* et bien on execute le programme!!!                   */
	    /********************************************************/

	    if((adr_data!=NULL) && (type_replay !=UNDEF) ){
		My_FreeMem(&adr_data2,size_file2);

		/**********************************************************/
		/* Si c'est un modules startrekker AM, on charge la suite */
		/**********************************************************/

		if( (type_replay == STARTREKKER)||(type_replay == NOISETRACKER)){
			read_file_nt(p_name);
/*
			if(adr_data2==0){
			   My_FreeMem(&adr_data,size_file);
			   type_replay=UNDEF;
			}
*/
		}
		if(type_replay == TFMX){
			read_file_tfmx(p_name);
			if(adr_data2==0){
			   My_FreeMem(&adr_data,size_file);
			   type_replay=UNDEF;
			}
		}
		if(wG!=NULL)SetWindowTitles(wG,fname,fname);
		sprintf(RequIText4.IText,"Module Name:%.26s",fname);
		if(adr_data2!=0){
			sprintf(RequIText5.IText,"Module Size:%d+%d",size_file,size_file2);
		}else{
			sprintf(RequIText5.IText,"Module Size:%d",size_file);
		}
		sprintf(RequIText6.IText,"Replay Used:%.22s",tab_replay[num_replay].p_name);


		exec_safe(tab_replay[num_replay].p_start);
		if(setup(pp_interrupt,tab_replay[num_replay].p_music)!=OK){
			num_replay=UNDEF;
		}
  
	   }
	}else{
		SimpleRequest("Unknow replay!");
	}
	return(num_replay);
}

/**********************************************/
/* Procedure d'attente d'evenements intuition */
/**********************************************/

void main_loop(num_replay)
int num_replay;
{
	struct IntuiMessage *message;	/* the message the IDCMP sends us */
	UWORD code;
	ULONG class;
	APTR object;

	flag_out=FALSE;
	do
	{
		WaitPort(wG->UserPort);

		while( (message = (struct IntuiMessage *)
			GetMsg(wG->UserPort) ) != NULL)
			{
				code = message->Code;  /* MENUNUM */
				object = message->IAddress;  /* Gadget */
				class = message->Class;
				ReplyMsg(message);
				switch(class){
				     case  CLOSEWINDOW:
					 flag_out = TRUE;
					 quit_flag= TRUE;
				 	 break;
				     case  GADGETUP:
				     case  GADGETDOWN:
					HandleEvent(object);
					break;
				     case VANILLAKEY:

					if( (code>='0') && (code<='9')) {
						num_musique=code-'1';
						if(code==-1)code=10;

						if( (tab_replay[num_replay].type_replay==FRED)||
						    (tab_replay[num_replay].type_replay==TFMX)){
							exec_safe(tab_replay[num_replay].p_start);
						}
					}
					break;
				     default:
					break;
				}

			}
	} while (flag_out == FALSE);
}


/*************************************************/
/* Lecture d'un fichier de sons de noisetrakcer! */
/*************************************************/

void read_file_nt(p_filename)
char *p_filename;
{
   char  *buffer;
   int err;
   /* Lecture du deuxieme fichier! */

   buffer=(char *)malloc(strlen(p_filename)+5);
   sprintf(buffer,"%s.NT",p_filename);

    err = PP_LoadData (buffer, DECR_POINTER,
               			MEMF_PUBLIC+MEMF_CHIP, &adr_data2, &size_file2, NULL); 
    if (err != PP_LOADOK) {                                      
	My_FreeMem(&adr_data2,size_file2);
/*
	if(err==PP_LOCKERR){
		SimpleRequest("File:%s not found!",buffer);
	}
*/
    }
    free(buffer);
}
/*****************************************/
/* Load a TFMX smpl data file!           */
/*****************************************/

void read_file_tfmx(p_filename)
char *p_filename;
{
   char  *buffer;
   int err,i;
   /* Lecture du deuxieme fichier! */
   buffer=(char *)malloc(strlen(p_filename)+1);
   strcpy(buffer,p_filename);
   i=0;
   while( (buffer[i]!='m') || (buffer[i+1] != 'd') || (buffer[i+2] != 'a') || (buffer[i+3] != 't')){
	i++;
   }
   buffer[i]='s';
   buffer[i+1]='m';
   buffer[i+2]='p';
   buffer[i+3]='l';

    err = PP_LoadData (buffer, DECR_POINTER,
               			MEMF_PUBLIC+MEMF_CHIP, &adr_data2, &size_file2, NULL); 
    if (err != PP_LOADOK) {
	My_FreeMem(&adr_data2,size_file2);
	if(err==PP_LOCKERR){
		SimpleRequest("File:%s not found!",buffer);
	}
    }
    free(buffer);
}

/**************************************************/
/* Initialisation de notre handler d'interruption */
/**************************************************/

int	setup(pp_interrupt,p_func)
struct	Interrupt **pp_interrupt;
void	(*p_func)();
{

   if(*pp_interrupt!=NULL){
	printf("Erreur,pp_interrupt <>0! Deja alloue?\n");
	return(NOK);
   }
   *pp_interrupt=(struct Interrupt *)My_AllocMem(sizeof(struct Interrupt),
                                                MEMF_PUBLIC,pp_interrupt);

   if(*pp_interrupt == NULL){
	printf("Pas assez de memoire pour la structure d'interruption\n");
	return(NOK);
   }
   (*pp_interrupt)->is_Node.ln_Type=NT_INTERRUPT;
   (*pp_interrupt)->is_Node.ln_Pri=0;
   (*pp_interrupt)->is_Node.ln_Name="Multi replay Interrupt";
   (*pp_interrupt)->is_Data=(APTR)p_func;
   (*pp_interrupt)->is_Code=interrupt_music;

   if(AddICRVector(myCiaPointer,CIAICRB_TA,*pp_interrupt)!=0){
	SimpleRequest("I can't allocate the interruption");
	return(NOK);
   }else{
	ciab.ciatalo=(UBYTE)(frequ & 0xff);
	ciab.ciatahi=(UBYTE)((frequ>>8) & 0xff);
	ciab.ciacra|=1;
   }
   return(OK);
}

/******************************************/
/* Arret  de notre handler d'interruption */
/******************************************/

void stop(pp_interrupt)
struct Interrupt **pp_interrupt;
{
   if(*pp_interrupt != NULL){
	AbleICR(myCiaPointer,(1<<CIAICRB_TA) );
   	RemICRVector(myCiaPointer,CIAICRB_TA,*pp_interrupt);
	My_FreeMem(pp_interrupt,sizeof(struct Interrupt));
        *pp_interrupt=NULL;
   }
}

