/*---------------------------------------------------------------
FILE:   micro3d.c
ROLE:   management of Microphone+Doppler effect for DSound3d

MODIFICATIONS: - J.Vibert - 01/12/98 - extracted from sndxdwav.c
----------------------------------------------------------------*/

#include <windows.h>
#include <mmsystem.h>
#include <dsound.h>
#include "SNDinc.h"

#if defined(_DLL_COMPILATION_MODE) && defined(_DLL_MODULE) 
#include "snddll.h"
#endif

#include "priv3dFl.h"

extern SndBool			stereo_reverse;
extern SndBool			driver_SND_OK;
extern LPDIRECTSOUND3DLISTENER lpListener3D;

long	idMainMicro=C_CREATEMICRO_FAILED;

void SND_fn_vCreateMicroSxdWave(MicroParam* par,long idMicro)
{
#ifndef DISABLE_WAVE

	DS3DLISTENER parameters;
	SndVector dir_pv;

	if (driver_SND_OK == FALSE) {
		return ;
	}
	if (lpListener3D == NULL) return;

	//only 1 micro supported
	if (idMainMicro != C_CREATEMICRO_FAILED) return;

	// VERSION computation of MICRO

	parameters.dwSize = sizeof(DS3DLISTENER);
	if (par!=NULL)
	{
		dir_pv.x = SND_fn_rMulRealRealSnd(par->dirtan.y,par->dirnor.z);
		dir_pv.x -= SND_fn_rMulRealRealSnd(par->dirtan.z,par->dirnor.y);

		dir_pv.y = SND_fn_rMulRealRealSnd(par->dirtan.x,par->dirnor.z);
		dir_pv.y -= SND_fn_rMulRealRealSnd(par->dirtan.z,par->dirnor.x);

		dir_pv.z = SND_fn_rMulRealRealSnd(par->dirtan.x,par->dirnor.y);
		dir_pv.z -= SND_fn_rMulRealRealSnd(par->dirtan.y,par->dirnor.x);

		if (!stereo_reverse) {
			parameters.vPosition.x = (float)M_RealToDoubleSnd(par->pos.x);
			parameters.vPosition.y = (float)M_RealToDoubleSnd(par->pos.y);
			parameters.vPosition.z = (float)M_RealToDoubleSnd(par->pos.z);
			parameters.vVelocity.dvX = (float)M_RealToDoubleSnd(par->vit.x);
			parameters.vVelocity.dvY = (float)M_RealToDoubleSnd(par->vit.y);
			parameters.vVelocity.dvZ = (float)M_RealToDoubleSnd(par->vit.z);
			parameters.vOrientFront.x = (float)M_RealToDoubleSnd(par->dirnor.x);
			parameters.vOrientFront.y = (float)M_RealToDoubleSnd(par->dirnor.y);
			parameters.vOrientFront.z = (float)M_RealToDoubleSnd(par->dirnor.z);
			parameters.vOrientTop.x = (float)M_RealToDoubleSnd(dir_pv.x);
			parameters.vOrientTop.y = (float)M_RealToDoubleSnd(dir_pv.y);
			parameters.vOrientTop.z = (float)M_RealToDoubleSnd(dir_pv.z);
		} else {
			parameters.vPosition.x = (float)M_RealToDoubleSnd(par->pos.y);
			parameters.vPosition.y = (float)M_RealToDoubleSnd(par->pos.x);
			parameters.vPosition.z = (float)M_RealToDoubleSnd(par->pos.z);
			parameters.vVelocity.dvX = (float)M_RealToDoubleSnd(par->vit.y);
			parameters.vVelocity.dvY = (float)M_RealToDoubleSnd(par->vit.x);
			parameters.vVelocity.dvZ = (float)M_RealToDoubleSnd(par->vit.z);
			parameters.vOrientFront.x = (float)M_RealToDoubleSnd(par->dirnor.y);
			parameters.vOrientFront.y = (float)M_RealToDoubleSnd(par->dirnor.x);
			parameters.vOrientFront.z = (float)M_RealToDoubleSnd(par->dirnor.z);
			parameters.vOrientTop.x = (float)M_RealToDoubleSnd(dir_pv.y);
			parameters.vOrientTop.y = (float)M_RealToDoubleSnd(dir_pv.x);
			parameters.vOrientTop.z = (float)M_RealToDoubleSnd(dir_pv.z);
		}
	}
	else
	{
		memset(&parameters.vPosition,0,sizeof(parameters.vPosition));
		memset(&parameters.vVelocity,0,sizeof(parameters.vVelocity));
		memset(&parameters.vOrientFront,0,sizeof(parameters.vOrientFront));
		memset(&parameters.vOrientTop,0,sizeof(parameters.vOrientTop));
		//05/11/98
		parameters.vOrientFront.x=1.0f;
		parameters.vOrientTop.z=1.0f;
	}

	parameters.flDistanceFactor = DISTANCE_FACTOR;
	parameters.flRolloffFactor = ROLLOFF_FACTOR;
	parameters.flDopplerFactor = DOPPLER_FACTOR;

	IDirectSound3DListener_SetAllParameters(lpListener3D,&parameters,DS3D_DEFERRED);
	idMainMicro =idMicro;
#endif

}

void SND_fn_vSetMicroParamSxdWave(long idMicro,MicroParam* par)
{
#ifndef DISABLE_WAVE

	DS3DLISTENER parameters;
	SndVector dir_pv;

	// compute normal vector for this micro
	if (driver_SND_OK == FALSE) {
		return ;
	}
	if (lpListener3D == NULL) return;
	if (idMicro != idMainMicro) return;

	//jvdbg("SetMicroParamSxdWav");

	dir_pv.x = SND_fn_rMulRealRealSnd(par->dirtan.y,par->dirnor.z);
	dir_pv.x -= SND_fn_rMulRealRealSnd(par->dirtan.z,par->dirnor.y);

	dir_pv.y = SND_fn_rMulRealRealSnd(par->dirtan.x,par->dirnor.z);
	dir_pv.y -= SND_fn_rMulRealRealSnd(par->dirtan.z,par->dirnor.x);

	dir_pv.z = SND_fn_rMulRealRealSnd(par->dirtan.x,par->dirnor.y);
	dir_pv.z -= SND_fn_rMulRealRealSnd(par->dirtan.y,par->dirnor.x);

	parameters.dwSize = sizeof(DS3DLISTENER);
	if (!stereo_reverse) {
		parameters.vPosition.x = (float)M_RealToDoubleSnd(par->pos.x);
		parameters.vPosition.y = (float)M_RealToDoubleSnd(par->pos.y);
		parameters.vPosition.z = (float)M_RealToDoubleSnd(par->pos.z);
		parameters.vVelocity.dvX = (float)M_RealToDoubleSnd(par->vit.x);
		parameters.vVelocity.dvY = (float)M_RealToDoubleSnd(par->vit.y);
		parameters.vVelocity.dvZ = (float)M_RealToDoubleSnd(par->vit.z);
		parameters.vOrientFront.x = (float)M_RealToDoubleSnd(par->dirnor.x);
		parameters.vOrientFront.y = (float)M_RealToDoubleSnd(par->dirnor.y);
		parameters.vOrientFront.z = (float)M_RealToDoubleSnd(par->dirnor.z);
		parameters.vOrientTop.x = (float)M_RealToDoubleSnd(dir_pv.x);
		parameters.vOrientTop.y = (float)M_RealToDoubleSnd(dir_pv.y);
		parameters.vOrientTop.z = (float)M_RealToDoubleSnd(dir_pv.z);
	} else {
		parameters.vPosition.x = (float)M_RealToDoubleSnd(par->pos.y);
		parameters.vPosition.y = (float)M_RealToDoubleSnd(par->pos.x);
		parameters.vPosition.z = (float)M_RealToDoubleSnd(par->pos.z);
		parameters.vVelocity.dvX = (float)M_RealToDoubleSnd(par->vit.y);
		parameters.vVelocity.dvY = (float)M_RealToDoubleSnd(par->vit.x);
		parameters.vVelocity.dvZ = (float)M_RealToDoubleSnd(par->vit.z);
		parameters.vOrientFront.x = (float)M_RealToDoubleSnd(par->dirnor.y);
		parameters.vOrientFront.y = (float)M_RealToDoubleSnd(par->dirnor.x);
		parameters.vOrientFront.z = (float)M_RealToDoubleSnd(par->dirnor.z);
		parameters.vOrientTop.x = (float)M_RealToDoubleSnd(dir_pv.y);
		parameters.vOrientTop.y = (float)M_RealToDoubleSnd(dir_pv.x);
		parameters.vOrientTop.z = (float)M_RealToDoubleSnd(dir_pv.z);
	}
	/*
	_RPT3(_CRT_WARN,"MIC POS %f %f %f\n",
		parameters.vPosition.x,
		parameters.vPosition.y,
		parameters.vPosition.z);

	_RPT3(_CRT_WARN,"FRT POS %f %f %f\n",
		parameters.vOrientFront.x,
		parameters.vOrientFront.y,
		parameters.vOrientFront.z);

	_RPT3(_CRT_WARN,"TOP POS %f %f %f\n",
		parameters.vOrientTop.x,
		parameters.vOrientTop.y,
		parameters.vOrientTop.z);

	_RPT3(_CRT_WARN,"TOP TAN %f %f %f\n",
		(float)M_RealToDoubleSnd(par->dirtan.x),
		(float)M_RealToDoubleSnd(par->dirtan.y),
		(float)M_RealToDoubleSnd(par->dirtan.z));
		*/

	parameters.flDistanceFactor = DISTANCE_FACTOR;
	parameters.flRolloffFactor = ROLLOFF_FACTOR;
	parameters.flDopplerFactor = DOPPLER_FACTOR;
	IDirectSound3DListener_SetAllParameters(lpListener3D,&parameters,DS3D_DEFERRED);
	//jvdbg("after setAllParam");

#endif
}

void SND_fn_vDestroyMicroSxdWave(long sxdId)
{
#ifndef DISABLE_WAVE
	if (driver_SND_OK == FALSE) {
		return ;
	}
	jvdbg("DestroyMicroSxdWave");
	idMainMicro = C_CREATEMICRO_FAILED;
#endif
}

//------------------------------------------------------------
//      SetDopplerFactorSxdWave:change Doppler effect range
//      input:new factor for Doppler effect
//              1.0=normal effect=physically realistic
//				0.0=no doppler effect
//      output: none
//------------------------------------------------------------
void SND_fn_vSetDopplerFactorSxdWave(SndReal factor)
{
	D3DVALUE flDopplerFactor;

	if (driver_SND_OK == FALSE) {
		return ;
	}
	if (lpListener3D == NULL) return;

	/*
	DS3D_MINDOPPLERFACTOR=0.0 to DS3D_MAXDOPPLERFACTOR=10.0
	realistic=DS3D_DEFAULTDOPPLERFACTOR=1.0
	*/

	flDopplerFactor=(float)M_RealToDoubleSnd(factor);
	if (flDopplerFactor<DS3D_MINDOPPLERFACTOR)
		flDopplerFactor=DS3D_MINDOPPLERFACTOR;
	else if (flDopplerFactor>DS3D_MAXDOPPLERFACTOR)
		flDopplerFactor=DS3D_MAXDOPPLERFACTOR;

	IDirectSound3DListener_SetDopplerFactor(lpListener3D,flDopplerFactor,DS3D_DEFERRED);
}

