/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
//#define INITGUID
#include "error/error.hh"
#include "error/alert.hh"
#include "sound/dsound/d3dsound.hh"
#include "loaders/wav_load.hh"
#include "string/string.hh"
#include "file/file.hh"
#include "video/win32/win32.hh"
direct_3dsound_class direct_3dsound;
static sw16 volume_table[I4_SOUND_VOLUME_LEVELS] =
{
// Volume ramp
//{{{ Note:
// Generated with:
//
// perl -e 'printf " %6d, ", -10000; for ($i=1; $i<64; $i++)
// { printf( "%6d, ", 1000*log($i/63)); if ($i%10 == 9) { print "\n "; }}; print "\n"'
//}}}
-10000, -4143, -3449, -3044, -2756, -2533, -2351, -2197, -2063, -1945,
-1840, -1745, -1658, -1578, -1504, -1435, -1370, -1309, -1252, -1198,
-1147, -1098, -1052, -1007, -965, -924, -885, -847, -810, -775,
-741, -709, -677, -646, -616, -587, -559, -532, -505, -479,
-454, -429, -405, -381, -358, -336, -314, -292, -271, -251,
-231, -211, -191, -172, -154, -135, -117, -100, -82, -65,
-48, -32, -16, 0
};
int check_result(HRESULT err)
//{{{
{
switch (err)
{
case DS_OK:
return 1;
break;
case DSERR_ALLOCATED:
i4_warning("i4_direct_sound - resources already used by another.");
break;
case DSERR_ALREADYINITIALIZED:
i4_warning("i4_direct_sound - object already initialized.");
break;
case DSERR_BADFORMAT:
i4_warning("i4_direct_sound - format not supported.");
break;
case DSERR_BUFFERLOST:
i4_warning("i4_direct_sound - buffer memory lost.");
break;
case DSERR_CONTROLUNAVAIL:
i4_warning("i4_direct_sound - control is unavailable.");
break;
case DSERR_GENERIC:
i4_warning("i4_direct_sound - error.");
break;
case DSERR_INVALIDCALL:
i4_warning("i4_direct_sound - function is invalid.");
break;
case DSERR_INVALIDPARAM:
i4_warning("i4_direct_sound - invalid parameter.");
break;
case DSERR_NOAGGREGATION:
i4_warning("i4_direct_sound - object does not support aggregation.");
break;
case DSERR_NODRIVER:
i4_warning("i4_direct_sound - no sound driver available.");
break;
case DSERR_OUTOFMEMORY:
i4_warning("i4_direct_sound - out of memory.");
break;
case DSERR_PRIOLEVELNEEDED:
i4_warning("i4_direct_sound - insufficient priority level to perform function.");
break;
case DSERR_UNINITIALIZED:
i4_warning("i4_direct_sound - uninitializd sound system.");
break;
case DSERR_UNSUPPORTED:
i4_warning("i4_direct_sound - function currently unsupported.");
break;
}
return 0;
}
//}}}
void d3dsound_buffer_class::play()
//{{{
{
if (!pDSB)
return;
// pDSB->SetCurrentPosition(0);
pDSB->Play(0,0,flags);
}
//}}}
void d3dsound_buffer_class::update()
//{{{
{
if (!pDSB)
return;
pDSB->SetFrequency(frequency);
pDSB->SetVolume(volume_table[volume]);
ds_param.vPosition.x = position.x*0.01;
ds_param.vPosition.y = position.y*0.01;
ds_param.vPosition.z = position.z*0.01;
ds_param.vVelocity.x = velocity.x*0.5;
ds_param.vVelocity.y = velocity.y*0.5;
ds_param.vVelocity.z = velocity.z*0.5;
pDS3DB->SetAllParameters(&ds_param, DS3D_IMMEDIATE);
}
//}}}
void d3dsound_buffer_class::set_completer(completion_function_type _completer, void *_context)
//{{{
{
completer = _completer;
context = _context;
}
//}}}
void direct_3dsound_class::load(w32 max_sounds)
//{{{
{
sound = new d3dsound_buffer_class[max_sounds];
i4_sound_info info;
i4_const_str *sounds=i4_string_man.get_array("sounds");
for (w32 count=0; !sounds[count].null(); count++)
{
i4_file_class *fp=i4_file_man.open(sounds[count]);
if (!fp)
i4_alert(i4gets("file_missing"),200,&sounds[count]);
else
{
if (i4_load_wav(fp,info))
{
DSBUFFERDESC dsBD = {0};
PCMWAVEFORMAT pcmwf;
d3dsound_buffer_class *snd = &sound[count];
ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = info.channels;
pcmwf.wf.nSamplesPerSec = info.sample_rate;
pcmwf.wf.nBlockAlign = info.sample_size*info.channels;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = info.sample_size*8;
dsBD.dwSize = sizeof(dsBD);
dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME;
dsBD.dwBufferBytes = info.size;
dsBD.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
if (!check_result(lpDirectSound->CreateSoundBuffer(&dsBD, &snd->pDSB, 0)))
{
i4_warning("couldn't create sound buffer");
snd->pDSB = 0;
return;
}
if (!check_result(snd->pDSB->QueryInterface(IID_IDirectSound3DBuffer,
(void**)&snd->pDS3DB)))
{
i4_warning("couldn't create 3D sound buffer");
snd->pDSB = 0;
snd->pDS3DB = 0;
return;
}
snd->ds_param.dwSize = sizeof(snd->ds_param);
snd->ds_param.vPosition.x = 0;
snd->ds_param.vPosition.y = 0;
snd->ds_param.vPosition.z = 0;
snd->ds_param.vVelocity.x = 0;
snd->ds_param.vVelocity.y = 0;
snd->ds_param.vVelocity.z = 0;
snd->ds_param.dwInsideConeAngle = 360;
snd->ds_param.dwOutsideConeAngle = 360;
snd->ds_param.vConeOrientation.x;
snd->ds_param.vConeOrientation.y;
snd->ds_param.vConeOrientation.z;
snd->ds_param.lConeOutsideVolume = 0;
snd->ds_param.flMinDistance = 1;
snd->ds_param.flMaxDistance = 100;
snd->ds_param.dwMode = DS3DMODE_NORMAL;
check_result(snd->pDS3DB->SetAllParameters(&snd->ds_param, DS3D_IMMEDIATE));
LPVOID m1,m2;
DWORD s1,s2;
snd->data = (w8*)info.data;
if (!check_result(snd->pDSB->Lock(0, info.size, &m1, &s1, &m2, &s2, 0)))
{
i4_warning("i4_sound_manager_class::play - couldn't get write access to sound buffer");
snd->pDSB->Release();
snd->pDSB = 0;
return;
}
CopyMemory(m1, snd->data, s1);
if (s2 != 0)
CopyMemory(m2, snd->data+s1, s2);
if (!check_result(snd->pDSB->Unlock(m1,s1,m2,s2)))
{
i4_warning("i4_3d_sound_manager_class::load - couldn't unlock sound buffer");
snd->pDSB->Release();
snd->pDSB = 0;
return;
}
}
delete fp;
}
}
i4_free(sounds);
}
//}}}
void direct_3dsound_class::load_sounds(w32 max_sounds)
//{{{
{
i4_3d_sound_man = (i4_3d_sound_manager_class*)&i4_null_3d_sound;
DSBUFFERDESC dsBD;
if (DirectSoundCreate(0, &lpDirectSound, 0) != DS_OK)
{
i4_warning("i4_sound_manager_class::load_sounds - DirectSound not initialized");
return;
}
if (lpDirectSound->SetCooperativeLevel(win32_display_instance.window_handle,
DSSCL_EXCLUSIVE) != DS_OK)
{
i4_warning("i4_sound_manager_class::load_sounds - couldn't get exclusive sound");
return;
}
ZeroMemory( &dsBD, sizeof(DSBUFFERDESC) );
dsBD.dwSize = sizeof(dsBD);
dsBD.dwFlags = DSBCAPS_PRIMARYBUFFER;
if (!check_result( lpDirectSound->CreateSoundBuffer( &dsBD, &lpPrimary, 0)))
{
i4_warning("i4_sound_manager_class::load_sounds - couldn't create primary buffer");
return;
}
#if 0
PCMWAVEFORMAT pcmwf;
ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
pcmwf.wf.nChannels = 1;
pcmwf.wf.nSamplesPerSec = 22050;
pcmwf.wf.nBlockAlign = 1;
pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
pcmwf.wBitsPerSample = 8;
if (!check_result( lpPrimary->SetFormat((LPWAVEFORMATEX)&pcmwf) ))
{
i4_warning("i4_sound_manager_class::load_sounds - couldn't format primary buffer");
return;
}
#endif
if (!check_result( lpPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ))
{
i4_warning("i4_sound_manager_class::load_sounds - couldn't start primary buffer");
return;
}
lpPrimary->Release();
i4_3d_sound_man = this;
load(max_sounds);
}
//}}}
i4_3d_voice_class *direct_3dsound_class::alloc(i4_sound_id sound_id,
const i4_3d_sound_parameters& param)
//{{{
{
sound[sound_id].flags = 0;
if (param.looping)
sound[sound_id].flags |= DSBPLAY_LOOPING;
sound[sound_id].set_completer(0,0);
sound[sound_id].set(param);
sound[sound_id].update();
return &sound[sound_id];
}
//}}}
//{{{ Emacs Locals
// Local Variables:
// folded-file: t
// End:
//}}}