/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
////																					 ////
////																					 ////
////								 - SCOLoldSound.cpp -								 ////
////																					 ////
////																					 ////
////				Implémentation des fonctions SCOL de la librairie sonore			 ////
////									 Version  1.0									 ////
////																					 ////
////								  Hilaire Verschuere								 ////
////																					 ////
////																					 ////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////


#include "..\Basic\ZooScene.h"
#include "..\SCOL\SCOLsound.h"


extern HSoundManager* pHSoundManager ;

int DSobj;
int DSListenerobj;
int DSBufferobj;


int _CreateDirectSound (mmachine m)
{
	if( !initDirectSound() ) { MMpull(m) ; MMpull(m) ; MMpull(m) ; MMpull(m) ; MMpull(m) ; MMset(m,0,NIL) ; return 0 ; }

	MMpull(m) ;
	MMpull(m) ;
	MMpull(m) ;
	MMpull(m) ;
	MMpull(m) ;

	int* dsobj = new int[1] ;
	int  ds = MMmalloc(m,1,TYPETAB);
	if ( ds == NIL ) { MMset(m,0,NIL) ; return MERRMEM ; }
	MMstore(m,ds,0,(int)dsobj);
	
	MMpush(m,PTOM(ds));
	return OBJcreate(m,DSobj,(int)dsobj,-1,0) ;
}





int _InitDirectSound (mmachine m)
{
	MMpush( m, MMget(m, 0) ) ;
	MMset( m, 1, MMget( m, 2 ) );
	MMset( m, 2, MMget( m, 3 ) );
	MMset( m, 3, MMget( m, 4 ) );
	MMset( m, 4, MMget( m, 5 ) );
	MMset( m, 5, MMgetglobal( m, OFFSCCUR ) ) ;

	return _CreateDirectSound( m ) ;
}




int _ReleaseDirectSound (mmachine m)
{
	int ds = MTOP( MMget(m,0) ) ;
	if (ds==NIL) { MMset(m,0,NIL) ; return 0 ; }

	OBJdelTM(m,DSobj,PTOM(ds)) ;
	
	MMset(m,0,0);
	return 0;
}



int ReleaseDirectSound(mmachine m,int handsys,int objm)
{
	int* ds = (int*)MMfetch(m, MTOP(objm), 0) ;
	if(!ds) { MMset(m,0,NIL) ; return 0 ; }

	SAFE_DELETE( ds ) ;

	MMstore( m, MTOP(objm), 0, NULL ) ;
	return 0 ;
}



int createSoundBuffer( mmachine m, bool is3D )
{
	if( !initDirectSound() ) { MMpull(m) ; MMpull(m) ; MMpull(m) ; MMpull(m) ; MMpull(m) ; MMpull(m) ; MMset(m,0,NIL) ; return 0 ; }

	int flag			= MTOI( MMpull(m) ) ;
	int size			= MTOI( MMpull(m) ) ;
	int nBitsPerSample	= MTOI( MMpull(m) ) ;
	int nSamplesPerSec	= MTOI( MMpull(m) ) ;
	int nChannels		= MTOI( MMpull(m) ) ;
	
	int ds = MTOP( MMpull(m) ) ;
	if (ds==NIL) { MMset(m,0,NIL) ; return 0 ; }
	
	int* dsobj = (int*)MMfetch(m,ds,0);	
	if (!dsobj) { MMset(m,0,NIL) ; return 0 ; }

	if ( nChannels<1 || nChannels>2 ) { MMset(m,0,NIL); return 0; }
	if ( nBitsPerSample!=8 && nBitsPerSample!=16 ) { MMset(m,0,NIL); return 0; }
	if ( nSamplesPerSec<0 ) { MMset(m,0,NIL); return 0; }
	if (size<0) { MMset(m,0,NIL) ; return 0 ; }
	
	int wflag = DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
	if( flag&1 ) wflag |= DSBCAPS_STATIC ;
	if( is3D )
	{
		wflag |= DSBCAPS_CTRL3D ;
		if( flag&4 ) wflag |= DSBCAPS_MUTE3DATMAXDISTANCE ;
	}
	WSound* pWSound = new WSound( wflag ) ;

	
	pWSound->load( new HData( true ) ) ;
	if ( FAILED( pWSound->pHSound->SetData( nChannels, nBitsPerSample, nSamplesPerSec, OBJSOUND_LINEAR ) ) ) { MMset(m,0,NIL); return 0; }
	pWSound->pHSound->m_dwSize = size * pWSound->pHSound->m_pwfx->nBlockAlign ;
	if ( FAILED( pWSound->pHSound->CreateStatic( pWSound->flag ) ) ) { MMset(m,0,NIL); return 0; }

	int	buffer = MMmalloc(m,1,TYPETAB) ;
	if ( buffer == NIL ) { SAFE_DELETE(pWSound) ; MMset(m,0,NIL) ; return MERRMEM ; }
	MMstore( m, buffer, 0, (int)pWSound ) ;

	MMpush(m,PTOM(buffer)) ;
	return OBJcreate(m, DSBufferobj, (int)pWSound, DSobj, (int)dsobj) ;
}


int _CreateSoundBuffer (mmachine m)
{
	return createSoundBuffer( m, false ) ;
}


int _CRSoundBuffer (mmachine m)
{
	MMpush( m, MMget(m, 0) ) ;
	MMset( m, 1, MMget( m, 2 ) );
	MMset( m, 2, MMget( m, 3 ) );
	MMset( m, 3, MMget( m, 4 ) );
	MMset( m, 4, MMget( m, 5 ) );
	MMset( m, 5, MMget( m, 6 ) );
	MMset( m, 6, MMgetglobal( m, OFFSCCUR ) ) ;

	return createSoundBuffer( m, false ) ;
}


int _CreateSoundBuffer3D (mmachine m)
{
	return createSoundBuffer( m, true ) ;
}



int _CRSoundBuffer3D(mmachine m)
{
	MMpush( m, MMget(m, 0) ) ;
	MMset( m, 1, MMget( m, 2 ) );
	MMset( m, 2, MMget( m, 3 ) );
	MMset( m, 3, MMget( m, 4 ) );
	MMset( m, 4, MMget( m, 5 ) );
	MMset( m, 5, MMget( m, 6 ) );
	MMset( m, 6, MMgetglobal( m, OFFSCCUR ) ) ;

	return createSoundBuffer( m, true ) ;
}




int _DSSoundBuffer (mmachine m)
{
	int	buffer = MTOP(MMget(m,0)) ;
	if ( buffer == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	OBJdelTM(m,DSBufferobj,PTOM(buffer)) ;	
	MMset(m,0,0);

	return 0;
}



int SDSBufferdestroy(mmachine m,int handsys,int objm)
{
	WSound* pWSound = (WSound*) MMfetch(m, MTOP(objm), 0) ;
	if( !pWSound ) { MMset(m,0,NIL) ; return 0 ; }

	SAFE_DELETE( pWSound ) ;
	
	MMstore( m, MTOP(objm), 0, NULL ) ;
	MMechostr(1,"DSBuffer destroyed\n");
	return 0 ;
}




int _CopySoundBuffer(mmachine m)
{
	if( !initDirectSound() ) { MMpull(m) ; MMpull(m) ; MMset(m,0,NIL) ; return 0 ; }

	int	obj = MTOP( MMpull(m) ) ;
	int ds  = MTOP( MMpull(m) ) ;
	if ( ds==NIL || obj==NIL ) { MMset(m,0,NIL); return 0;}
	
	int* dsobj = (int*)MMfetch(m,ds,0);	
	if (!dsobj) { MMset(m,0,NIL); return 0;} 

	WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
	if( !pWSound || !pWSound->pHSound ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* dupWSound = new WSound( *pWSound ) ;

	int	buffer = MMmalloc(m,1,TYPETAB) ;
	if ( buffer == NIL ) { SAFE_DELETE(dupWSound) ; MMset(m,0,NIL) ; return MERRMEM ; }
	MMstore( m, buffer, 0, (int)dupWSound ) ;

	MMpush(m,PTOM(buffer)) ;
	return OBJcreate(m, DSBufferobj, (int)dupWSound, DSobj, (int)dsobj) ;
}




int _DUPSoundBuffer(mmachine m)
{
	MMpush( m, MMget(m, 0) ) ;
	MMset( m, 1, MMget( m, 2 ) );
	MMset( m, 2, MMgetglobal( m, OFFSCCUR ) ) ;

	return _CopySoundBuffer( m ) ;
}




int _CreateListener3D (mmachine m)
{
	if( !initDirectSound() ) { MMpull(m) ; MMset(m,0,NIL) ; return 0 ; }

 	int ds = MTOP( MMpull(m) ) ;
	if (ds==NIL) { MMset(m,0,NIL); return 0;}

	int* dsobj = (int*)MMfetch(m,ds,0);	
	if (!dsobj) { MMset(m,0,NIL); return 0;} 

	HListener* pHListener = new HListener() ;
	
	int listener = MMmalloc(m,1,TYPETAB) ;
	if( listener == NIL ) { SAFE_DELETE(pHListener) ; MMset(m,0,NIL) ; return MERRMEM ; }
	MMstore( m, listener, 0, (int)pHListener ) ;
	
	MMpush(m,PTOM(listener)) ;
	return OBJcreate(m,DSListenerobj,(int)pHListener,DSobj,(int)dsobj);
}



int _CRListener3D(mmachine m)
{
	MMpush( m, MMget(m, 0) ) ;
	MMset( m, 1, MMgetglobal( m, OFFSCCUR ) ) ;

	return _CreateListener3D( m ) ;
}



int _DSListener (mmachine m)
{
	int	listener = MTOP(MMget(m,0)) ;
	if ( listener == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	OBJdelTM(m,DSListenerobj,PTOM(listener)) ;	
	MMset(m,0,0);

	return 0;
}




int SDSListenerdestroy(mmachine m,int handsys,int objm)
{
	HListener* pHListener = (HListener*)MMfetch(m, MTOP(objm), 0) ;
	if( !pHListener ) { MMset(m,0,NIL) ; return 0 ; }

	SAFE_DELETE( pHListener ) ;
	
	MMstore( m, MTOP(objm), 0, NULL ) ;
	MMechostr(1,"DSListener destroyed\n");

	return 0 ;
}


int _PLAYSoundBuffer (mmachine m)
{
	return _PLAYsound( m ) ;
}



int _STOPSoundBuffer (mmachine m)
{
	return _STOPsound( m ) ;
}



int _SETSoundBuffer (mmachine m)
{
	DWORD size1, size2;
	LPVOID buf1, buf2 ;

	int start  = MTOP( MMpull(m) ) ;
	int string = MTOP( MMpull(m) ) ;
	
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL || string==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
	if( !pWSound || !pWSound->pHSound ) { MMset(m,0,NIL) ; return 0 ; }

	if (start==NIL) start=0 ;

	if( FAILED( pWSound->pHSound->m_pBuffer->Lock( start, MMsizestr(m,string), &buf1, &size1, &buf2, &size2, 0 ) ) ) { MMset(m,0,NIL) ; return 0 ; }

	if (buf1) memcpy( buf1, MMstartstr(m,string), size1);
	if (buf2) memcpy( buf2, MMstartstr(m,string)+size1, size2);

	if( FAILED( pWSound->pHSound->m_pBuffer->Unlock( buf1, size1 ,buf2, size2 ) ) ) { MMset(m,0,NIL) ; return 0 ; }

	return 0;
}




int seti(mmachine m, int fun)
{
	DWORD param	 = MTOI( MMpull(m) ) ;
	int	objSound = MTOP( MMget(m,0) ) ;
	if( objSound==NIL || param==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, objSound, 0) ;
	if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_pBuffer ) { MMset(m,0,NIL) ; return 0 ; }
	
	if( fun>=1 && fun<=3 )
	{
		LPDIRECTSOUNDBUFFER ptr = pWSound->pHSound->m_pBuffer ;	

		if( fun==1 )
		{
			if (param>0) param = -param ;
			if( FAILED( ptr->SetVolume(param) ) ) { MMset(m,0,NIL) ; return 0 ; }
		}
		else if( fun==2 ) { if( FAILED( ptr->SetPan(param) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==3 ) { if( FAILED( ptr->SetCurrentPosition(param) ) ) 
			{ MMset(m,0,NIL) ; return 0 ; } 
		}
	}
	else
	{
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;
		if( !ptr ) { MMset(m,0,NIL) ; return 0 ; }

		if( fun==4 )      { if( FAILED( ptr->SetMode( param, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==5 ) { if( FAILED( ptr->SetConeOutsideVolume( param, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}


	return 0 ;
}


int _SETVolume (mmachine m)
{
	return seti(m, 1) ;
}


int _SETPan (mmachine m)
{
	return seti(m, 2) ;
}



int _SETPlayPosition (mmachine m)
{
	return seti(m, 3) ;
}


int _SETOperationMode (mmachine m)
{
	return seti(m, 4) ;
}


int _SETConeOutsideVolume (mmachine m)
{
	return seti(m, 5) ;
}








/*int _SETFrequency (mmachine m)
{
	return _SETsoundFrequency( m ) ;
}


int _GETFrequency (mmachine m)
{
	return _GETsoundFrequency( m ) ;
}*/







int geti(mmachine m, int fun)
{
	int	dsbuffer = MTOP( MMget(m,0) ) ;
	if( dsbuffer==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, dsbuffer, 0) ;
	if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_pBuffer ) { MMset(m,0,NIL) ; return 0 ; }

	DWORD param ;
	if( fun>=1 && fun<=4 ) 
	{
		LPDIRECTSOUNDBUFFER ptr = pWSound->pHSound->m_pBuffer ;
		if( fun==1 )	  { if( FAILED( ptr->GetVolume((long*)&param) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==2 ) { if( FAILED( ptr->GetPan((long*)&param) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==3 ) {	if( FAILED( ptr->GetCurrentPosition( &param, NULL ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==4 ) { if( FAILED( ptr->GetCurrentPosition( NULL, &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}
	else 
	{
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;
		if( !ptr )   { MMset(m,0,NIL) ; return 0 ; }	
		if( fun==5 ) { if( FAILED( ptr->GetMode( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		if( fun==6 ) { if( FAILED( ptr->GetConeOutsideVolume( (long*)&param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}

	MMset( m, 0, ITOM(param) ) ;
	return 0 ;
}


int _GETVolume (mmachine m)
{
	return geti( m, 1 ) ;
}


int _GETPan (mmachine m)
{
	return geti( m, 2 ) ;
}


int _GETPlayPosition (mmachine m)
{
	return geti( m, 3 ) ;
}


int _GETWritePosition (mmachine m)
{
	return geti( m, 4 ) ;
}


int _GETOperationMode (mmachine m)
{
	return geti( m, 5 ) ;
}


int _GETConeOutsideVolume (mmachine m)
{
	return geti( m, 6 ) ;
}





int setf( mmachine m, int fun )
{
	int dist = MMpull(m) ;
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL || dist==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	float distf = MTOF( dist ) ;

	if( fun==1 || fun==2 )
	{
		WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
		if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;	

		if( fun==1)		  { if( FAILED( ptr->SetMinDistance( distf, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==2 ) { if( FAILED( ptr->SetMaxDistance( distf, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}
	else
	{
		HListener* pHListener = (HListener*)MMfetch(m, obj, 0) ;
		if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DLISTENER ptr = pHListener->m_pListener ;
		
		if( fun==3)		  { if( FAILED( ptr->SetDistanceFactor( distf, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==4 ) { if( FAILED( ptr->SetDopplerFactor( distf, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==5 ) { if( FAILED( ptr->SetRolloffFactor( distf, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}

	return 0;
}


int _SETMinDistance (mmachine m)
{
	return setf( m, 1 ) ;
}


int _SETMaxDistance (mmachine m)
{
	return setf( m, 2 ) ;
}


int _SETDistanceFactor (mmachine m)
{
 	return setf( m, 3 ) ;
}


int _SETDopplerFactor (mmachine m)
{
	return setf( m, 4 ) ;
}


int _SETRollOffFactor (mmachine m)
{
 	return setf( m, 5 ) ;
}





int setXYZ(mmachine m, int fun )
{
	int z = MMpull(m);
	int y = MMpull(m);
	int x = MMpull(m);
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL || x==NIL || y==NIL || z==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	float xx = MTOF( x ) ; 
	float yy = MTOF( y ) ; 
	float zz = MTOF( z ) ;

	if( fun >= 1 && fun <= 3 )
	{
		WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
		if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;

		if( fun==1 )		{ if( FAILED( ptr->SetPosition( xx, yy, zz, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==2 )	{ if( FAILED( ptr->SetVelocity( xx, yy, zz, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==3 )	{ if( FAILED( ptr->SetConeOrientation( xx, yy, zz, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}
	else
	{
		HListener* pHListener = (HListener*)MMfetch(m, obj, 0) ;
		if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DLISTENER ptr = pHListener->m_pListener ;

		if( fun==4 )		{ if( FAILED( ptr->SetPosition( xx, yy, zz, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==5 )	{ if( FAILED( ptr->SetVelocity( xx, yy, zz, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}

	return 0 ;
}


int _SETPosition3D (mmachine m)
{
	return setXYZ( m, 1 ) ;
}


int _SETVelocity3D (mmachine m)
{
	return setXYZ( m, 2 ) ;
}


int _SETConeOrientation (mmachine m)
{
	return setXYZ( m, 3 ) ;
}


int _SETListenerPosition3D (mmachine m)
{
	return setXYZ( m, 4 ) ;
}


int _SETListenerVelocity3D (mmachine m)
{
  return setXYZ( m, 5 ) ;
}










int getf(mmachine m, int fun)
{
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	float param ;
	if( fun<=1 && fun>=2 )
	{
		WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
		if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;
		if( fun==1 )	  { if( FAILED( ptr->GetMinDistance( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==2 ) { if( FAILED( ptr->GetMaxDistance( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}
	else
	{
		HListener* pHListener = (HListener*)MMfetch(m, obj, 0) ;
		if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DLISTENER ptr = pHListener->m_pListener ;
		if( fun==3 )	  { if( FAILED( ptr->GetDistanceFactor( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==4 ) { if( FAILED( ptr->GetDopplerFactor( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==5 ) { if( FAILED( ptr->GetRolloffFactor( &param ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}

	MMset(m,0,FTOM(param));
	return 0 ;
}


int _GETMinDistance (mmachine m)
{
	return getf( m, 1 ) ;
}


int _GETMaxDistance (mmachine m)
{
	return getf( m, 2 ) ;
}


int _GETDistanceFactor (mmachine m)
{
	return getf( m, 3 ) ;
}


int _GETDopplerFactor (mmachine m)
{
	return getf( m, 4 ) ;
}


int _GETRollOffFactor (mmachine m)
{
	return getf( m, 5 ) ;
}






int get3f( mmachine m, int fun )
{
	int	dsbuffer = MTOP( MMget(m,0) ) ;
	if( dsbuffer==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	D3DVECTOR vec ;

	if( fun>=1 || fun <=3 )
	{
		WSound* pWSound = (WSound*)MMfetch(m, dsbuffer, 0) ;
		if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DBUFFER ptr = pWSound->pHSound->m_p3DBuffer ;

		if( fun==1 )	  { if( FAILED( ptr->GetPosition( &vec ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==2 ) { if( FAILED( ptr->GetVelocity( &vec ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==3 ) { if( FAILED( ptr->GetConeOrientation( &vec ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}
	else
	{
		HListener* pHListener = (HListener*)MMfetch(m, dsbuffer, 0) ;
		if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }
		LPDIRECTSOUND3DLISTENER ptr = pHListener->m_pListener ;

		if( fun==4 )	  { if( FAILED( ptr->GetPosition( &vec ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
		else if( fun==5 ) { if( FAILED( ptr->GetVelocity( &vec ) ) ) { MMset(m,0,NIL) ; return 0 ; } }
	}

	int tuple = MMmalloc(m,3,TYPETAB);
	if (tuple<0) return tuple;

	MMstore(m,tuple,0,FTOM(vec.x));
	MMstore(m,tuple,1,FTOM(vec.y));
	MMstore(m,tuple,2,FTOM(vec.z));

	MMset(m,0,PTOM(tuple));
	return 0 ;
}


int _GETPosition3D (mmachine m)
{
	return get3f( m, 1 ) ;
}


int _GETVelocity3D (mmachine m)
{
	return get3f( m, 2 ) ;
}


int _GETConeOrientation (mmachine m)
{
	return get3f( m, 3 ) ;
}


int _GETListenerPosition3D (mmachine m)
{
	return get3f( m, 4 ) ;
}


int _GETListenerVelocity3D (mmachine m)
{
	return get3f( m, 5 ) ;
}





int _GETListenerOrientation3D (mmachine m)
{
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	D3DVECTOR vec1, vec2 ;

	HListener* pHListener = (HListener*)MMfetch(m, obj, 0) ;
	if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }

	if( FAILED( pHListener->m_pListener->GetOrientation(&vec1,&vec2) ) ) { MMset(m,0,NIL) ; return 0 ; }

	int tuple1 = MMmalloc(m,3,TYPETAB);
	if (tuple1<0) return tuple1;
	MMstore(m,tuple1,0,FTOM(vec1.x));
	MMstore(m,tuple1,1,FTOM(vec1.y));
	MMstore(m,tuple1,2,FTOM(vec1.z));

	int tuple2 = MMmalloc(m,3,TYPETAB);
	if (tuple2<0) return tuple2;
	MMstore(m,tuple2,0,FTOM(vec2.x));
	MMstore(m,tuple2,1,FTOM(vec2.y));
	MMstore(m,tuple2,2,FTOM(vec2.z));

	int tuple = MMmalloc(m,2,TYPETAB);
	if (tuple<0) return tuple;
	MMstore(m,tuple,0,PTOM(tuple1));
    MMstore(m,tuple,1,PTOM(tuple2));
	
	MMset(m,0,PTOM(tuple));
	return 0 ;
}




int _SETConeAngles (mmachine m)
{
	DWORD outside = MTOI( MMpull(m) ) ;
	DWORD inside  = MTOI( MMpull(m) ) ;
	int	obj  = MTOP( MMget(m,0) ) ;
	if( obj==NIL || outside==NIL || inside==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
	if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }

	if( FAILED( pWSound->pHSound->m_p3DBuffer->SetConeAngles( inside, outside, DS3D_DEFERRED ) ) ) { MMset(m,0,NIL) ; return 0 ; }

	return 0;
}




int _GETConeAngles (mmachine m)
{
	int	obj = MTOP( MMget(m,0) ) ;
	if( obj==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
	if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_p3DBuffer ) { MMset(m,0,NIL) ; return 0 ; }

	DWORD inside, outside ; ;

	if( FAILED( pWSound->pHSound->m_p3DBuffer->GetConeAngles(&inside,&outside) ) ) { MMset(m,0,NIL) ; return 0 ; }
	
	int tuple=MMmalloc(m,2,TYPETAB);
	if (tuple<0) return tuple;

	MMstore(m,tuple,0,MTOI(outside));
	MMstore(m,tuple,1,MTOI(inside));

	MMset(m,0,MTOP(tuple));
	return 0;
}




int _SETListenerOrientation (mmachine m)
{
	DWORD zt = MMpull( m ) ;
	DWORD yt = MMpull( m ) ;
	DWORD xt = MMpull( m ) ;
	DWORD zf = MMpull( m ) ;
	DWORD yf = MMpull( m ) ;
	DWORD xf = MMpull( m ) ;
	int	dsbuffer = MTOP( MMget( m, 0 ) ) ;
	if( dsbuffer==NIL || xf==NIL || yf==NIL || zf==NIL || xt==NIL || yt==NIL || zt==NIL ) { MMset( m, 0, NIL ) ; return 0 ; }

	float xxf = MTOF( xf );
	float yyf = MTOF( yf );
	float zzf = MTOF( zf );
	float xxt = MTOF( xt );
	float yyt = MTOF( yt );
	float zzt = MTOF( zt );

	HListener* pHListener = (HListener*)MMfetch(m, dsbuffer, 0) ;
	if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }

	if( FAILED( pHListener->m_pListener->SetOrientation( xxf, yyf, zzf, xxt, yyt, zzt, DS3D_DEFERRED ) ) ) { MMset( m, 0, NIL ) ; return 0 ; }
	
	return 0 ;
}






int _COMMITSoundSettings (mmachine m)
{
	int	dsbuffer = MTOP( MMget(m,0) ) ;
	if( dsbuffer==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	HListener* pHListener = (HListener*)MMfetch(m, dsbuffer, 0) ;
	if( !pHListener || !pHListener->m_pListener ) { MMset(m,0,NIL) ; return 0 ; }

	if( FAILED( pHListener->m_pListener->CommitDeferredSettings() ) ) { MMset(m,0,NIL) ; return 0 ; }
	
	MMset(m,0,ITOM(1));
	return 0;
}





int _CreateSoundStream(mmachine m)
{
	MMpull( m ) ;
	MMpull( m ) ;
	MMpull( m ) ;
	MMset( m, 0, NIL ) ;

	return 0 ;
}

int _CRSoundStream(mmachine m)
{
	MMpull( m ) ;
	MMpull( m ) ;
	MMset( m, 0, NIL ) ;

	return 0 ;
}





/////////////////////////////////////////////////////// WAVE I/O
int _OPENwave( mmachine m )
{
	MMpush( m, MMget(m,0)) ;
	MMset( m, 1, MMgetglobal( m, OFFSCCUR ) ) ;
	
	return _CRwave( m ) ;
}





int _SETSoundBufferFromWave (mmachine m)
{
	int read;
	LPVOID buf1,buf2;
	DWORD size1,size2;

	int restart = MTOI(MMpull(m));
	int pos		= MTOI(MMpull(m));
	int size	= MTOI(MMpull(m));
	int wave	= MTOP(MMpull(m));
	int start	= MTOI(MMpull(m));
	int obj		= MTOP(MMget(m,0));
	if( obj==NIL || wave==NIL || size==NIL ) { MMset(m,0,NIL) ; return 0 ; }

	WSound* pWSound = (WSound*)MMfetch(m, obj, 0) ;
	if( !pWSound || !pWSound->pHSound || !pWSound->pHSound->m_pBuffer ) { MMset(m,0,NIL) ; return 0 ; }

	if (start==NIL) start=0;
	if( restart!=NIL && restart!=0 ) pWSound->pHSound->m_loop = true ;

	HWave* pHWave = (HWave*)MMfetch(m, wave, 0) ;
	if( !pHWave )  { MMset(m,0,NIL) ; return 0 ; }
	if( pos!=NIL ) pHWave->SetPosition( pos, SEEK_SET ) ;


	// Play Buffer
	if( FAILED( pWSound->pHSound->m_pBuffer->Lock( start, size, &buf1, &size1, &buf2, &size2, 0 ) ) ) { MMset(m,0,NIL) ; return 0 ; }

	if(buf1)
	{
		read = pHWave->Read( (char*)buf1, size1 ) ;
		if (read<0) { MMset(m,0,NIL) ; return 0 ; }
		if ((unsigned)read!=size1) 
		{
			if (restart)
			{
				pHWave->Reset() ;
				pHWave->Read( (char*)buf1+read, size1-read ) ;
			}
			memset((char*)buf1+read,0,size1-read) ;
		}
	}

	if (buf2) 
	{
		read = pHWave->Read( (char*)buf2, size2 ) ;
		if (read<0) { MMset(m,0,NIL) ; return 0 ; }
		if ((unsigned)read!=size2) 
		{
			if (restart)
			{
				pHWave->Reset() ;
				pHWave->Read( (char*)buf2+read, size2-read ) ;
			}
			else memset((char*)buf2+read,0,size2-read);
		}
	}


	if( FAILED( pWSound->pHSound->m_pBuffer->Unlock( buf1, size1, buf2, size2 ) ) ) { MMset(m,0,NIL) ; return 0 ; }

	return 0;
}




//////////////////////////////////////////////////////////////////////////////////////////////
///		_GETwaveData													
//////////////////////////////////////////////////////////////////////////////////////////////
// fun [P] S
int _GETwaveData (mmachine m)
{
	int filename  = MTOP( MMget(m,0) ) ;
	if( filename == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	char* strFileName = (char*)MMstartstr(m,filename) ;	
	HWave wave( false ) ;

	if( FAILED( wave.Open( strFileName ) ) ) 
	{ 
		MMechostr(1,"%s is not a wav file.\n", strFileName) ; 
		MMset(m,0,NIL) ; 
		return 0 ; 
	}
	
	int sizeWave = wave.m_dwSize ;

	int buff = MMmalloc(m,((sizeWave+4)*4)+1,TYPEBUF);
	if( buff < 0 ) { MMset(m,0,NIL) ; return MERRMEM ; }
  
	char* buf = MMstartstr(m,buff);

	wave.Read( buf,sizeWave ) ;

	buf[sizeWave] = 0 ;
	MMstore( m, buff, 0, sizeWave );

	MMset(m, 0, PTOM(buff) );
	
	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		_SEEKwave													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [Wave I I] I
int _SEEKwave (mmachine m)
{
	int flag = MTOI(MMpull(m)) ;
	int pos  = MTOI(MMpull(m)) ;
	int wave = MTOP(MMget(m,0)) ;

	if( (wave == NIL) || (flag == NIL) || (pos == NIL) ) { MMset(m,0,NIL) ; return 0 ; }

	HWave* pHWave = (HWave*)MMfetch(m, wave, 0) ;
	if( !pHWave ) { MMset(m,0,NIL) ; return 0 ; }

	pHWave->SetPosition( pos, flag ) ;

	return 0 ;
}




//////////////////////////////////////////////////////////////////////////////////////////////
///		_GetMP3FrameInfo													
//////////////////////////////////////////////////////////////////////////////////////////////
//fun [S] [I I I I I I]
int _GetMP3FrameInfo(mmachine m)
{
	int s = MTOP( MMget(m,0) ) ;
	if( s == NIL ) { MMset(m,0,NIL) ; return 0 ; }

	char* buffer = (char*)MMstartstr(m,s) ;
	int size = MMsizestr(m,s) ;

	HMp3 hmp3( false ) ;
	int framesize = hmp3.GetFrameInfo( buffer, size ) ;

	int res = MMmalloc(m,6,TYPETAB) ;
	if ( res == NIL )	{ MMset(m,0,NIL) ;	return MERRMEM ; }

	MMstore(m, res, 0, ITOM( hmp3.cur_mp3info.nch ) ) ;
	MMstore(m, res, 1, NIL ) ;
	MMstore(m, res, 2, NIL ) ;
	MMstore(m, res, 3, ITOM( hmp3.cur_mp3info.freq ) ) ;
	MMstore(m, res, 4, ITOM( framesize ) ) ;
	MMstore(m, res, 5, ITOM( hmp3.cur_mp3info.bitrate ) ) ;

	MMset(m, 0, PTOM(res)) ;
	return 0 ;
}





/////////////////////////////////////////////////////// DEFINITIONS
#define NSDSPKG 68

char * SDSname [ NSDSPKG ] = 
{                  
  "DS",                           //  DS,                   
  "DSBuffer",                     //  DSBuffer,                   
  "DSListener3D",                 //  DSListener3D,                   

  "DSSCL_NORMAL",				  //  DSSCL_NORMAL
  "DSSCL_PRIORITY",				  //  DSSCL_PRIORITY
  "DSSCL_EXCLUSIVE",			  //  DSSCL_EXCLUSIVE

  "_CreateDirectSound",           //  _CreateDirectSound,
  "_InitDirectSound",			  //  _InitDirectSound,
  "_ReleaseDirectSound",          //  _ReleaseDirectSound,    
  ////////////////////////////////////////////////////////// 2D     
  "_CreateSoundBuffer",           //  _CreateSoundBuffer,
  "_CRSoundBuffer",				  //  _CRSoundBuffer,
  "_CopySoundBuffer",             //  _CopySoundBuffer,
  "_DUPSoundBuffer",			  //  _DUPSoundBuffer,
  "_DSSoundBuffer",               //  _DSSoundBuffer,         
  "_PLAYSoundBuffer",             //  _PLAYSoundBuffer,       
  "_STOPSoundBuffer",             //  _STOPSoundBuffer,       
  "_SETVolume",                   //  _SETVolume,             
  "_SETFrequency",                //  _SETFrequency,          
  "_SETPan",                      //  _SETPan,                
  "_GETVolume",                   //  _GETVolume,             
  "_GETFrequency",                //  _GETFrequency,          
  "_GETPan",                      //  _GETPan,                
  "_SETSoundBuffer",              //  _SETSoundBuffer,        
  "_GETPlayPosition",             //  _GETPlayPosition,       
  "_GETWritePosition",            //  _GETWritePosition,      
  "_SETPlayPosition",             //  _SETPlayPosition,       
  ///////////////////////////////////////////////////// 3D     
  "_CreateSoundBuffer3D",         //  _CreateSoundBuffer3D,
  "_CRSoundBuffer3D",			  //  _CRSoundBuffer3D,
  ////////////////////////////////////////////////////                          
  "_SETMinDistance",              //  _SETMinDistance,                     
  "_SETMaxDistance",              //  _SETMaxDistance,                     
  "_SETOperationMode",            //  _SETOperationMode,                   
  "_SETPosition3D",               //  _SETPosition3D,                      
  "_SETVelocity3D",               //  _SETVelocity3D,                      
  "_SETConeAngles",               //  _SETConeAngles,                      
  "_SETConeOrientation",          //  _SETConeOrientation,                 
  "_SETConeOutsideVolume",        //  _SETConeOutsideVolume,               
  ///////////////////////////////////////////////////////////////////    
  "_GETMinDistance",              //  _GETMinDistance,                     
  "_GETMaxDistance",              //  _GETMaxDistance,                     
  "_GETOperationMode",            //  _GETOperationMode,                   
  "_GETPosition3D",               //  _GETPosition3D,                      
  "_GETVelocity3D",               //  _GETVelocity3D,                      
  "_GETConeAngles",               //  _GETConeAngles,                      
  "_GETConeOrientation",          //  _GETConeOrientation,                 
  "_GETConeOutsideVolume",        //  _GETConeOutsideVolume                
  /////////////////////////////////////////////////////// 3D LISTENER
  "_CreateListener3D",            //  _CreateListener3D,         
  "_DSListener3D",                //  _DSListener3D,         
  "_SETDistanceFactor",           //  _SETDistanceFactor           
  "_SETDopplerFactor",            //  _SETDopplerFactor            
  "_SETRollOffFactor",            //  _SETRollOffFactor            
  "_SETListenerPosition3D",       //  _SETListenerPosition3D       
  "_SETListenerVelocity3D",       //  _SETListenerVelocity3D       
  "_SETListenerOrientation",      //  _SETListenerOrientation      
  "_GETDistanceFactor",           //  _GETDistanceFactor           
  "_GETDopplerFactor",            //  _GETDopplerFactor            
  "_GETRollOffFactor",            //  _GETRollOffFactor            
  "_GETListenerPosition3D",       //  _GETListenerPosition3D       
  "_GETListenerVelocity3D",       //  _GETListenerVelocity3D       
  "_GETListenerOrientation3D",    //  _GETListenerOrientation3D    
  "_COMMITSoundSettings",         //  _COMMITSoundSettings
  //////////////////////////////////////////// WAVE IO
  "_GETwaveData",				  //  _GETwaveData
  "_OPENwave",                    //  _OPENwave
  "_CLOSEwave",                   //  _CLOSEwave
  "_SEEKwave",					  //  _SEEKwave
  "_SETSoundBufferFromWave",      //  _SETSoundBufferFromWave  

  //////////////////////////////////////////// MP3!
  "_DecodeMp3",
  "_GetMP3FrameInfo",

  /////////////////////////////////////////// STREAM
  "_CreateSoundStream",			  //  _CreateSoundStream
  "_CRSoundStream",				  //  _CRSoundStream

} ;

char * SDStype [ NSDSPKG ] = 
{
////// TYPES                                            
  NULL,                               //  DS,                            
  NULL,                               //  DSBuffer,                      
  NULL,                               //  DSListener3D, 

  "I",								  //  DSSCL_NORMAL
  "I",								  //  DSSCL_PRIORITY
  "I",								  //  DSSCL_EXCLUSIVE

  "fun [Chn I I I I ObjWin] DS",      //  _CreateDirectSound,
  "fun [I I I I ObjWin] DS",		  //  _InitDirectSound
  "fun [DS] I",                       //  _ReleaseDirectSound,    
///// 2D ////////////////////////////////////////////// 2D     
  "fun [Chn DS I I I I I] DSBuffer",  //  _CreateSoundBuffer,
  "fun [DS I I I I I] DSBuffer",	  //  _CRSoundBuffer
  "fun [Chn DS DSBuffer] DSBuffer",   //  _CopySoundBuffer,
  "fun [DS DSBuffer] DSBuffer",		  //  _DUPSoundBuffer,
  "fun [DSBuffer] I",                 //  _DSSoundBuffer,         
  "fun [DSBuffer I] DSBuffer",        //  _PLAYSoundBuffer,       
  "fun [DSBuffer] DSBuffer",          //  _STOPSoundBuffer,       
  "fun [DSBuffer I] DSBuffer",        //  _SETVolume,             
  "fun [DSBuffer I] DSBuffer",        //  _SETFrequency,          
  "fun [DSBuffer I] DSBuffer",        //  _SETPan,                
  "fun [DSBuffer] I",                 //  _GETVolume,             
  "fun [DSBuffer] I",                 //  _GETFrequency,          
  "fun [DSBuffer] I",                 //  _GETPan,                
  "fun [DSBuffer S I] DSBuffer",      //  _SETSoundBuffer,       
  "fun [DSBuffer] I",                 //  _GETPlayPosition,       
  "fun [DSBuffer] I",                 //  _GETWritePosition,      
  "fun [DSBuffer I] DSBuffer",        //  _SETPlayPosition,       
///// 3D STANDARDS /////////////////////////////////// 3D     
  "fun [Chn DS I I I I I] DSBuffer",  //  _CreateSoundBuffer3D,
  "fun [DS I I I I I] DSBuffer",	  //  _CRSoundBuffer3D  
////// 3D SPECS ////////////////////////////////////////                          
  "fun [DSBuffer F] DSBuffer",		//  _SETMinDistance
  "fun [DSBuffer F] DSBuffer",		//  _SETMaxDistance
  "fun [DSBuffer I] DSBuffer",		//  _SETOperationMode
  "fun [DSBuffer F F F] DSBuffer",	//  _SETPosition3D
  "fun [DSBuffer F F F] DSBuffer",	//  _SETVelocity3D
  "fun [DSBuffer I I] DSBuffer",	//  _SETConeAngles
  "fun [DSBuffer F F F] DSBuffer",	//  _SETConeOrientation
  "fun [DSBuffer I] DSBuffer",		//  _SETConeOutsideVolume
  /////////////////////////////////////////////////////////////
  "fun [DSBuffer] I",               //  _GETMinDistance
  "fun [DSBuffer] I",               //  _GETMaxDistance
  "fun [DSBuffer] I",               //  _GETOperationMode
  "fun [DSBuffer] [F F F]",         //  _GETPosition3D
  "fun [DSBuffer] [F F F]",         //  _GETVelocity3D
  "fun [DSBuffer] [I I]",           //  _GETConeAngles
  "fun [DSBuffer] [F F F]",         //  _GETConeOrientation
  "fun [DSBuffer] I",               //  _GETConeOutsideVolume
  //////////////////////////////////////// 3D LISTENER 
  "fun [Chn DS] DSListener3D",            //  _CreateListener3D,         
  "fun [DSListener3D] I",              //  _DSListener3D,         
  "fun [DSListener3D F] DSListener3D",//  _SETDistanceFactor           
  "fun [DSListener3D F] DSListener3D",//  _SETDopplerFactor            
  "fun [DSListener3D F] DSListener3D",//  _SETRollOffFactor            
  "fun [DSListener3D F F F] DSListener3D",  //  _SETListenerPosition3D       
  "fun [DSListener3D F F F] DSListener3D",        //  _SETListenerVelocity3D       
  "fun [DSListener3D F F F F F F] DSListener3D",        //  _SETListenerOrientation      
  "fun [DSListener3D] F",             //  _GETDistanceFactor           
  "fun [DSListener3D] F",             //  _GETDopplerFactor            
  "fun [DSListener3D] F",             //  _GETRollOffFactor            
  "fun [DSListener3D] [F F F]",       //  _GETListenerPosition3D       
  "fun [DSListener3D] [F F F]",       //  _GETListenerVelocity3D       
  "fun [DSListener3D] [F F F]",       //  _GETListenerOrientation3D    
  "fun [DSListener3D] I",             //  _COMMITSoundSettings
  //////////////////////////////////////////// WAVE IO
  "fun [P] S",						  //  _GETwaveData
  "fun [P] Wave",                     //  _OPENwave
  "fun [Wave] I",                     //  _CLOSEwave
  "fun [Wave I I] I",				  //  _SEEKwave
  "fun [DSBuffer I Wave I I I] DSBuffer",      //  _SETSoundBufferFromWave
  //////////////////////////////////////////// MP3!
  "fun [MP3 S] S",					  //  _DecodeMp3,
  "fun [S] [I I I I I I]",            //  _GetMP3FrameInfo,

  "fun [Chn DS P I] DSStream",		  //  _CreateSoundStream
  "fun [DS P I] DSStream",			  //  _CRSoundStream
} ;



int SDSnarg [ NSDSPKG ] = 
{                       
  TYPTYPE,  //  DS,                            
  TYPTYPE,  //  DSBuffer,                      
  TYPTYPE,  //  DSListener3D,                  

  TYPVAR,   //  DSSL_NORMAL
  TYPVAR,   //  DSSL_PRIORITY
  TYPVAR,   //  DSSCL_EXCLUSIVE

  6,        //  _CreateDirectSound,
  5,		//	_InitDirectSound
  1,        //  _ReleaseDirectSound,    
  //////////////////////////// 2D     
  7,        //  _CreateSoundBuffer,
  6,		//  _CRSoundBuffer,
  3,        //  _CopySoundBuffer,
  2,		//  _DUPSoundBuffer,
  1,        //  _DSSoundBuffer,         
  2,        //  _PLAYSoundBuffer,       
  1,        //  _STOPSoundBuffer,       
  2,        //  _SETVolume,             
  2,        //  _SETFrequency,          
  2,        //  _SETPan,                
  1,        //  _GETVolume,             
  1,        //  _GETFrequency,          
  1,        //  _GETPan,                
  3,        //  _SETSoundBuffer,        
  1,        //  _GETPlayPosition,       
  1,        //  _GETWritePosition,      
  2,        //  _SETPlayPosition,       
  ///////////////////////////// 3D     
  7,        //  _CreateSoundBuffer3D,
  6,		//  _CRSoundBuffer3D,
  /////////////////////////////                          
  2,        //  _SETMinDistance
  2,        //  _SETMaxDistance
  2,        //  _SETOperationMode
  4,        //  _SETPosition3D
  4,        //  _SETVelocity3D
  3,        //  _SETConeAngles
  4,        //  _SETConeOrientation
  2,        //  _SETConeOutsideVolume
  /////////////////////////////////
  1,        //  _GETMinDistance
  1,        //  _GETMaxDistance
  1,        //  _GETOperationMode
  1,        //  _GETPosition3D
  1,        //  _GETVelocity3D
  1,        //  _GETConeAngles
  1,        //  _GETConeOrientation
  1,        //  _GETConeOutsideVolume
  //////////////////////////////////////// 3D LISTENER 
  2,        //  _CreateListener3D,         
  1,        //  _DSListener3D,         
  2,        //  _SETDistanceFactor           
  2,        //  _SETDopplerFactor            
  2,        //  _SETRollOffFactor            
  4,        //  _SETListenerPosition3D       
  4,        //  _SETListenerVelocity3D       
  7,        //  _SETListenerOrientation      
  1,        //  _GETDistanceFactor           
  1,        //  _GETDopplerFactor            
  1,        //  _GETRollOffFactor            
  1,        //  _GETListenerPosition3D       
  1,        //  _GETListenerVelocity3D       
  1,        //  _GETListenerOrientation3D    
  1,        //  _COMMITSoundSettings
  //////////////////////////////////////////// WAVE IO
  1,		//  _GETwaveData
  1,        //  _OPENwave
  1,        //  _CLOSEwave
  3,		//  _SEEKwave
  6,        //  _SETSoundBufferFromWave 
  //////////////////////////////////////////// MP3!
  2,        //  _DecodeMP3
  1,        //  _GetMP3FrameInfo

  4,		//  _CreateSoundStream
  3,		//  _CRSoundStream

} ;


int (*SDSfun[NSDSPKG])(mmachine m)= 
{                   
  NULL,														//  DS,                           
  NULL,														//  DSBuffer,                     
  NULL,														//  DSListener3D,                 

  (int (__cdecl *)(struct Mmachine *))(2*DSSCL_NORMAL),		//  DSSL_NORMAL
  (int (__cdecl *)(struct Mmachine *))(2*DSSCL_PRIORITY),	//  DSSL_PRIORITY
  (int (__cdecl *)(struct Mmachine *))(2*DSSCL_EXCLUSIVE),	//  DSSCL_EXCLUSIVE

  _CreateDirectSound,										//  _CreateDirectSound,
  _InitDirectSound,											//  _InitDirectSound,
  _ReleaseDirectSound,										//  _ReleaseDirectSound,    
////////////////// 2D ////////////////////////////////// 2D     
  _CreateSoundBuffer,										//  _CreateSoundBuffer,
  _CRSoundBuffer,											//  _CRSoundBuffer
  _CopySoundBuffer,											//  _CopySoundBuffer, 
  _DUPSoundBuffer,											//  _DUPSoundBuffer
  _DSSoundBuffer,											//  _DSSoundBuffer,         
  _PLAYsound,												//  _PLAYSoundBuffer,       
  _STOPsound,												//  _STOPSoundBuffer,       
  _SETVolume,												//  _SETVolume,             
  _SETsoundFrequency,											//  _SETFrequency,          
  _SETPan,													//  _SETPan,                
  _GETVolume,												//  _GETVolume,             
  _GETsoundFrequency,											//  _GETFrequency,          
  _GETPan,													//  _GETPan,                
  _SETSoundBuffer,											//  _SETSoundBuffer,        
  _GETPlayPosition,											//  _GETPlayPosition,       
  _GETWritePosition,										//  _GETWritePosition,      
  _SETPlayPosition,											//  _SETPlayPosition,       
  ////////////////// 3D //////////////////////////////////// 3D     
  _CreateSoundBuffer3D,										//  _CreateSoundBuffer3D,
  _CRSoundBuffer3D,											//  _CRSoundBuffer3D,
  ////////////////////////////////////////////////////////////////////
  _SETMinDistance,											//  _SETMinDistance,
  _SETMaxDistance,											//  _SETMaxDistance,
  _SETOperationMode,										//  _SETOperationMode,
  _SETPosition3D,											//  _SETPosition3D,
  _SETVelocity3D,											//  _SETVelocity3D,
  _SETConeAngles,											//  _SETConeAngles,
  _SETConeOrientation,										//  _SETConeOrientation,
  _SETConeOutsideVolume,									//  _SETConeOutsideVolume,
  ////////////////////////////////////////////////////////////////////
  _GETMinDistance,											//  _GETMinDistance,
  _GETMaxDistance,											//  _GETMaxDistance,
  _GETOperationMode,										//  _GETOperationMode,
  _GETPosition3D,											//  _GETPosition3D,
  _GETVelocity3D,											//  _GETVelocity3D,
  _GETConeAngles,											//  _GETConeAngles,
  _GETConeOrientation,										//  _GETConeOrientation,
  _GETConeOutsideVolume,									//  _GETConeOutsideVolume
  //////////////////////////////////////// 3D LISTENER 
  _CreateListener3D,										//  _CreateListener3D,         
  _DSListener,												//  _DSListener3D,         
  _SETDistanceFactor,										//  _SETDistanceFactor           
  _SETDopplerFactor,										//  _SETDopplerFactor            
  _SETRollOffFactor,										//  _SETRollOffFactor            
  _SETListenerPosition3D,									//  _SETListenerPosition3D       
  _SETListenerVelocity3D,									//  _SETListenerVelocity3D       
  _SETListenerOrientation,									//  _SETListenerOrientation      
  _GETDistanceFactor,										//  _GETDistanceFactor           
  _GETDopplerFactor,										//  _GETDopplerFactor            
  _GETRollOffFactor,										//  _GETRollOffFactor            
  _GETListenerPosition3D,									//  _GETListenerPosition3D       
  _GETListenerVelocity3D,									//  _GETListenerVelocity3D       
  _GETListenerOrientation3D,								//  _GETListenerOrientation3D    
  _COMMITSoundSettings ,									//  _COMMITSoundSettings
  //////////////////////////////////////////// WAVE IO
  _GETwaveData,												//  _GETwaveData
  _OPENwave,												//  _OPENwave
  _DSwave,													//  _CLOSEwave
  _SEEKwave,												//  _SEEKwave
  _SETSoundBufferFromWave,									//  _SETSoundBufferFromWave 
  //////////////////////////////////////////// MP3!
  _DECODEmp3,
  _GetMP3FrameInfo,											// _GetMP3FrameInfo

  ///////////////////////////////////////////// STREAM
  _CreateSoundStream,									    // _CreateSoundStream
  _CRSoundStream,											// _CRSoundStream

} ;


int SCOLloadOldSound(mmachine m,cbmachine w)
{
	int k = PKhardpak(m, "SDSound deprecated", NSDSPKG, SDSname, SDSfun, SDSnarg, SDStype);
	
	DSobj = OBJregister(0, 0, ReleaseDirectSound, "DSobj"); 
	DSBufferobj=OBJregister(0,0,SDSBufferdestroy,"DSBufferObj");
	DSListenerobj=OBJregister(0,0,SDSListenerdestroy,"DSListenerObj");

	return k;
}


int SCOLfreeOldSound()
{
	return 0;
}