//
//===========================================================================
//
// C-interface for SoundSystem3
//
// Written for Borland C 3.1 & Tasm 3.1
//
// (pd)1995 by the Frontman of Crew242
//
//
// .model MEDIUM
//
//===========================================================================
//

/***************************************************************************

	Player definitions

***************************************************************************/

#include <dos.h>

extern void far MAIN0(void);	// auto-detection
extern void far MAIN1(void);
extern void far MAIN2(void);
extern void far MAIN3(void);
extern void far MAIN4(void);
int near call_function(int player,int func,int param_ax,int param_bx,int param_cx,int param_dx,int param_ds,int *handle,int *param);
typedef struct pblock
{	int baseport;
	char dma_number;
	char irq_number;
	unsigned int samplerate;
	char intern_type;
	char irq_type;
	char start_pos;
	char loop_pos;
	char song_mod;
	unsigned char master_vol;
	unsigned char music_vol;
	unsigned char fx_vol;
};

/***************************************************************************

	Player functions

***************************************************************************/

int autodetect(struct pblock *paramblock)
{       int handle, param;
	call_function(0,0,0,FP_OFF(paramblock),0,0,FP_SEG(paramblock),&handle,&param);
	return handle;
}

int config_init(int player, int code, struct pblock *paramblock)
{       int c, handle, param;
	c= call_function(player,1,0,FP_OFF(paramblock),code,0,FP_SEG(paramblock),&handle,&param);
	return c;
}

int load_mod(int player, char *filename)
{       int c, handle, param;
	c= call_function(player,2,0,0,0,FP_OFF(filename),FP_SEG(filename),&handle,&param);
	return c;
}

int play_music(int player)
{       int c, handle, param;
	c= call_function(player,3,0,0,0,0,0,&handle,&param);
	return c;
}

int stop_music(int player)
{       int c, handle, param;
	c= call_function(player,4,0,0,0,0,0,&handle,&param);
	return c;
}

int end_music(int player)
{       int c, handle, param;
	c= call_function(player,5,0,0,0,0,0,&handle,&param);
	return c;
}

int load_sample(int player, char *filename, int amiga_pc, int *handle)
{       int c, param;
	c= call_function(player,6,0,0,amiga_pc & 0x80,FP_OFF(filename),FP_SEG(filename),handle,&param);
	return c;
}

int play_sample(int player, int handle, int freq_in_hz, int panning)
{       int c, param;
	c= call_function(player,7,panning & 255,handle,freq_in_hz,0,0,&handle,&param);
	return c;
}

int end_sample(int player)
{       int c, handle, param;
	c= call_function(player,8,0,0,0,0,0,&handle,&param);
	return c;
}

int set_samplerate(int player, int freq_in_hz)
{       int c, handle, param;
	c= call_function(player,9,freq_in_hz,0,0,0,0,&handle,&param);
	return c;
}

int get_volume(int player, int *master_vol, int *music_vol, int *fx_vol)
{       int c, handle, param;
	c= call_function(player,10,0,0,0,0,0,&handle,&param);
	*master_vol= handle & 255;
	*music_vol= param & 255;
	*fx_vol= param >> 8;
	return c;
}

int set_volume(int player, int master_vol, int music_vol, int fx_vol)
{       int c, handle, param;
	c= call_function(player,11,master_vol & 255,(fx_vol << 8)+(music_vol & 255),0,0,0,&handle,&param);
	return c;
}

int set_songloop(int player, int loop_position)
{       int c, handle, param;
	c= call_function(player,12,loop_position & 255,0,0,0,0,&handle,&param);
	return c;
}

int get_songposition(int player, int *song_position)
{       int c, handle, param;
	c= call_function(player,13,0,0,0,0,0,&handle,&param);
	*song_position= handle & 127;
	return c;
}

int set_songposition(int player, int song_position)
{       int c, handle, param;
	c= call_function(player,14,song_position & 127,0,0,0,0,&handle,&param);
	return c;
}

int get_songmod(int player, int *song_modus)
{       int c, handle, param;
	c= call_function(player,15,0,0,0,0,0,&handle,&param);
	*song_modus= handle & 3;
	return c;
}

int set_songmod(int player, int song_modus)
{       int c, handle, param;
	c= call_function(player,16,song_modus & 3,0,0,0,0,&handle,&param);
	return c;
}

/***************************************************************************

	Player interface subroutines

***************************************************************************/

int near call_function(int player,int func,int param_ax,int param_bx,int param_cx,int param_dx,int param_ds,int *handle,int *param)
{	int c,ra,rb,rc;
	switch(player){
	case 0:
		{asm{	pusha           /* VERY IMPORTANT, BECAUSE C USES */
			mov ax,param_ax /* SI AND DI AS TEMP VAR */
			mov bx,param_bx
			mov cx,param_cx
			mov dx,param_dx
			mov es,param_ds
			mov di,func};
		MAIN0();
		asm{	mov ra,ax
			mov rb,bx
			mov rc,cx
			mov c,dx
			popa};
		break;
		};
	case 1:
		{asm{	pusha           /* VERY IMPORTANT, BECAUSE C USES */
			mov ax,param_ax /* SI AND DI AS TEMP VAR */
			mov bx,param_bx
			mov cx,param_cx
			mov dx,param_dx
			mov es,param_ds
			mov di,func};
		MAIN1();
		asm{	mov ra,ax
			mov rb,bx
			mov rc,cx
			mov c,dx
			popa};
		break;
		};
	case 2:
		{asm{	pusha           /* VERY IMPORTANT, BECAUSE C USES */
			mov ax,param_ax /* SI AND DI AS TEMP VAR */
			mov bx,param_bx
			mov cx,param_cx
			mov dx,param_dx
			mov es,param_ds
			mov di,func};
		MAIN2();
		asm{	mov ra,ax
			mov rb,bx
			mov rc,cx
			mov c,dx
			popa};
		break;
		};
	case 3:
		{asm{	pusha           /* VERY IMPORTANT, BECAUSE C USES */
			mov ax,param_ax /* SI AND DI AS TEMP VAR */
			mov bx,param_bx
			mov cx,param_cx
			mov dx,param_dx
			mov es,param_ds
			mov di,func};
		MAIN3();
		asm{	mov ra,ax
			mov rb,bx
			mov rc,cx
			mov c,dx
			popa};
		break;
		};
	case 4:
		{asm{	pusha           /* VERY IMPORTANT, BECAUSE C USES */
			mov ax,param_ax /* SI AND DI AS TEMP VAR */
			mov bx,param_bx
			mov cx,param_cx
			mov dx,param_dx
			mov es,param_ds
			mov di,func};
		MAIN4();
		asm{	mov ra,ax
			mov rb,bx
			mov rc,cx
			mov c,dx
			popa};
		break;
		};
	}
	*handle= ra;
	*param= rb;
	return c;
}
//
//===========================================================================
//