source: golgotha/src/i4/sound/dsound/d3dsound.cc @ 608

Last change on this file since 608 was 80, checked in by Sam Hocevar, 15 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 9.5 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9//#define INITGUID
10
11#include "error/error.hh"
12#include "error/alert.hh"
13#include "sound/dsound/d3dsound.hh"
14#include "loaders/wav_load.hh"
15#include "string/string.hh"
16#include "file/file.hh"
17#include "video/win32/win32.hh"
18
19direct_3dsound_class direct_3dsound;
20static sw16 volume_table[I4_SOUND_VOLUME_LEVELS] =
21{
22  // Volume ramp
23  //{{{ Note:
24  //  Generated with:
25  //
26  // perl -e 'printf "  %6d, ", -10000; for ($i=1; $i<64; $i++)
27  //   { printf( "%6d, ", 1000*log($i/63)); if ($i%10 == 9) { print "\n  "; }}; print "\n"'
28  //}}}
29
30  -10000,  -4143,  -3449,  -3044,  -2756,  -2533,  -2351,  -2197,  -2063,  -1945,
31   -1840,  -1745,  -1658,  -1578,  -1504,  -1435,  -1370,  -1309,  -1252,  -1198,
32   -1147,  -1098,  -1052,  -1007,   -965,   -924,   -885,   -847,   -810,   -775,
33    -741,   -709,   -677,   -646,   -616,   -587,   -559,   -532,   -505,   -479,
34    -454,   -429,   -405,   -381,   -358,   -336,   -314,   -292,   -271,   -251,
35    -231,   -211,   -191,   -172,   -154,   -135,   -117,   -100,    -82,    -65,
36     -48,    -32,    -16,      0
37};
38
39int check_result(HRESULT err)
40//{{{
41{
42  switch (err)
43  {
44    case DS_OK:
45      return 1;
46      break;
47     
48    case DSERR_ALLOCATED:
49      i4_warning("i4_direct_sound - resources already used by another.");
50      break;
51     
52    case DSERR_ALREADYINITIALIZED:
53      i4_warning("i4_direct_sound - object already initialized.");
54      break;
55     
56    case DSERR_BADFORMAT:
57      i4_warning("i4_direct_sound - format not supported.");
58      break;
59     
60    case DSERR_BUFFERLOST:
61      i4_warning("i4_direct_sound - buffer memory lost.");
62      break;
63     
64    case DSERR_CONTROLUNAVAIL:
65      i4_warning("i4_direct_sound - control is unavailable.");
66      break;
67     
68    case DSERR_GENERIC:
69      i4_warning("i4_direct_sound - error.");
70      break;
71     
72    case DSERR_INVALIDCALL:
73      i4_warning("i4_direct_sound - function is invalid.");
74      break;
75     
76    case DSERR_INVALIDPARAM:
77      i4_warning("i4_direct_sound - invalid parameter.");
78      break;
79     
80    case DSERR_NOAGGREGATION:
81      i4_warning("i4_direct_sound - object does not support aggregation.");
82      break;
83     
84    case DSERR_NODRIVER:
85      i4_warning("i4_direct_sound - no sound driver available.");
86      break;
87     
88    case DSERR_OUTOFMEMORY:
89      i4_warning("i4_direct_sound - out of memory.");
90      break;
91     
92    case DSERR_PRIOLEVELNEEDED:
93      i4_warning("i4_direct_sound - insufficient priority level to perform function.");
94      break;
95     
96    case DSERR_UNINITIALIZED:
97      i4_warning("i4_direct_sound - uninitializd sound system.");
98      break;
99     
100    case DSERR_UNSUPPORTED:
101      i4_warning("i4_direct_sound - function currently unsupported.");
102      break;
103  }
104  return 0;
105}
106//}}}
107
108
109void d3dsound_buffer_class::play()
110//{{{
111{
112  if (!pDSB)
113    return;
114
115  //  pDSB->SetCurrentPosition(0);
116  pDSB->Play(0,0,flags);
117}
118//}}}
119
120
121void d3dsound_buffer_class::update()
122//{{{
123{
124  if (!pDSB)
125    return;
126
127  pDSB->SetFrequency(frequency);
128  pDSB->SetVolume(volume_table[volume]);
129
130  ds_param.vPosition.x = position.x*0.01;
131  ds_param.vPosition.y = position.y*0.01;
132  ds_param.vPosition.z = position.z*0.01;
133  ds_param.vVelocity.x = velocity.x*0.5;
134  ds_param.vVelocity.y = velocity.y*0.5;
135  ds_param.vVelocity.z = velocity.z*0.5;
136
137  pDS3DB->SetAllParameters(&ds_param, DS3D_IMMEDIATE);
138}
139//}}}
140
141
142void d3dsound_buffer_class::set_completer(completion_function_type _completer, void *_context)
143//{{{
144{
145  completer = _completer;
146  context = _context;
147}
148//}}}
149
150
151void direct_3dsound_class::load(w32 max_sounds)
152//{{{
153{
154  sound = new d3dsound_buffer_class[max_sounds];
155
156  i4_sound_info info;
157  i4_const_str *sounds=i4_string_man.get_array("sounds");
158 
159  for (w32 count=0; !sounds[count].null(); count++)
160  { 
161    i4_file_class *fp=i4_file_man.open(sounds[count]);
162    if (!fp)   
163      i4_alert(i4gets("file_missing"),200,&sounds[count]);
164    else
165    {
166      if (i4_load_wav(fp,info))
167      {
168        DSBUFFERDESC dsBD = {0};
169        PCMWAVEFORMAT pcmwf;
170        d3dsound_buffer_class *snd = &sound[count];
171     
172        ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
173        pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
174        pcmwf.wf.nChannels = info.channels;
175        pcmwf.wf.nSamplesPerSec = info.sample_rate;
176        pcmwf.wf.nBlockAlign = info.sample_size*info.channels;
177        pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
178        pcmwf.wBitsPerSample = info.sample_size*8;
179     
180        dsBD.dwSize = sizeof(dsBD);
181        dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME;
182        dsBD.dwBufferBytes = info.size;
183        dsBD.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
184     
185        if (!check_result(lpDirectSound->CreateSoundBuffer(&dsBD, &snd->pDSB, 0)))
186        {
187          i4_warning("couldn't create sound buffer");
188          snd->pDSB = 0;
189          return;
190        }
191     
192        if (!check_result(snd->pDSB->QueryInterface(IID_IDirectSound3DBuffer,
193                                                    (void**)&snd->pDS3DB)))
194        {
195          i4_warning("couldn't create 3D sound buffer");
196          snd->pDSB = 0;
197          snd->pDS3DB = 0;
198          return;
199        }
200
201        snd->ds_param.dwSize = sizeof(snd->ds_param);
202        snd->ds_param.vPosition.x = 0;
203        snd->ds_param.vPosition.y = 0;
204        snd->ds_param.vPosition.z = 0;
205        snd->ds_param.vVelocity.x = 0;
206        snd->ds_param.vVelocity.y = 0;
207        snd->ds_param.vVelocity.z = 0;
208        snd->ds_param.dwInsideConeAngle = 360;
209        snd->ds_param.dwOutsideConeAngle = 360;
210        snd->ds_param.vConeOrientation.x;
211        snd->ds_param.vConeOrientation.y;
212        snd->ds_param.vConeOrientation.z;
213        snd->ds_param.lConeOutsideVolume = 0;
214        snd->ds_param.flMinDistance = 1;
215        snd->ds_param.flMaxDistance = 100;
216        snd->ds_param.dwMode = DS3DMODE_NORMAL;
217
218        check_result(snd->pDS3DB->SetAllParameters(&snd->ds_param, DS3D_IMMEDIATE));
219     
220        LPVOID m1,m2;
221        DWORD s1,s2;
222     
223        snd->data = (w8*)info.data;
224     
225        if (!check_result(snd->pDSB->Lock(0, info.size, &m1, &s1, &m2, &s2, 0)))
226        {
227          i4_warning("i4_sound_manager_class::play - couldn't get write access to sound buffer");
228          snd->pDSB->Release();
229          snd->pDSB = 0;
230          return;
231        }
232     
233        CopyMemory(m1, snd->data, s1);
234     
235        if (s2 != 0)
236          CopyMemory(m2, snd->data+s1, s2);
237     
238        if (!check_result(snd->pDSB->Unlock(m1,s1,m2,s2)))
239        {
240          i4_warning("i4_3d_sound_manager_class::load - couldn't unlock sound buffer");
241          snd->pDSB->Release();
242          snd->pDSB = 0;
243          return;
244        }
245      }
246      delete fp;
247    }
248  }
249
250  i4_free(sounds);
251}
252//}}}
253
254
255void direct_3dsound_class::load_sounds(w32 max_sounds)
256//{{{
257{
258  i4_3d_sound_man = (i4_3d_sound_manager_class*)&i4_null_3d_sound;
259
260  DSBUFFERDESC dsBD;
261
262  if (DirectSoundCreate(0, &lpDirectSound, 0) != DS_OK)
263  {
264    i4_warning("i4_sound_manager_class::load_sounds - DirectSound not initialized");
265    return;
266  }
267
268  if (lpDirectSound->SetCooperativeLevel(win32_display_instance.window_handle,
269                                         DSSCL_EXCLUSIVE) != DS_OK)
270  {
271    i4_warning("i4_sound_manager_class::load_sounds - couldn't get exclusive sound");
272    return;
273  }
274
275  ZeroMemory( &dsBD, sizeof(DSBUFFERDESC) );
276  dsBD.dwSize = sizeof(dsBD);
277  dsBD.dwFlags = DSBCAPS_PRIMARYBUFFER;
278
279  if (!check_result( lpDirectSound->CreateSoundBuffer( &dsBD, &lpPrimary, 0)))
280  {
281    i4_warning("i4_sound_manager_class::load_sounds - couldn't create primary buffer");
282    return;
283  }
284
285#if 0
286  PCMWAVEFORMAT pcmwf;
287  ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
288  pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
289  pcmwf.wf.nChannels = 1;
290  pcmwf.wf.nSamplesPerSec = 22050;
291  pcmwf.wf.nBlockAlign = 1;
292  pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
293  pcmwf.wBitsPerSample = 8;
294
295  if (!check_result( lpPrimary->SetFormat((LPWAVEFORMATEX)&pcmwf) ))
296  {
297    i4_warning("i4_sound_manager_class::load_sounds - couldn't format primary buffer");
298    return;
299  }
300#endif
301
302  if (!check_result( lpPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ))
303  {
304    i4_warning("i4_sound_manager_class::load_sounds - couldn't start primary buffer");
305    return;
306  }
307
308  lpPrimary->Release();
309
310  i4_3d_sound_man = this;
311
312  load(max_sounds);
313}
314//}}}
315
316
317i4_3d_voice_class *direct_3dsound_class::alloc(i4_sound_id sound_id,
318                                               const i4_3d_sound_parameters& param)
319//{{{
320{
321  sound[sound_id].flags = 0;
322  if (param.looping)
323    sound[sound_id].flags |= DSBPLAY_LOOPING;
324
325  sound[sound_id].set_completer(0,0);
326  sound[sound_id].set(param);
327  sound[sound_id].update();
328
329  return &sound[sound_id];
330}
331//}}}
332
333
334//{{{ Emacs Locals
335// Local Variables:
336// folded-file: t
337// End:
338//}}}
Note: See TracBrowser for help on using the repository browser.