]> icculus.org git repositories - taylor/freespace2.git/blob - src/sound/rsx_lib.cpp
Fix net_addr vs net_addr_t
[taylor/freespace2.git] / src / sound / rsx_lib.cpp
1 /*
2  * $Logfile: /Freespace2/code/Sound/rsx_lib.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * C module for RSX sound lib
8  *
9  * $Log$
10  * Revision 1.2  2002/05/07 03:16:52  theoddone33
11  * The Great Newline Fix
12  *
13  * Revision 1.1.1.1  2002/05/03 03:28:10  root
14  * Initial import.
15  *
16  * 
17  * 2     10/07/98 10:54a Dave
18  * Initial checkin.
19  * 
20  * 1     10/07/98 10:51a Dave
21  * 
22  * 3     10/14/97 11:33p Lawrance
23  * get RSX implemented
24  * 
25  * 1     10/14/97 12:58p Lawrance
26  * 
27  * 1     10/14/97 10:35a Lawrance
28  *
29  * $NoKeywords: $
30  */
31
32 #define INITGUID
33 #include "pstypes.h"
34 #include <windows.h>
35 #include <rsx.h>
36 #include "rsx_lib.h"
37 #include "sound.h"
38 #include "osapi.h"
39
40 // gloabl variable to keep track of initalized status for RSX
41 int rsx_initialized = 0;
42
43 ////////////////////////////////////////////
44 // Global RSX data
45 ////////////////////////////////////////////
46 IUnknown                                        *lpRSXUnk;
47 //IRSX2                                         *lpRSX;
48 IRSX                                            *lpRSX;
49 IRSXDirectListener      *lpDL;
50
51 RSXENVIRONMENT                  rsxEnv;
52
53 IRSXCachedEmitter               *lpCE[MAX_SOUNDS];
54
55 // initialize the listener.  Return -1 if failed to init listener, otherwise return 0
56 int rsx_init_listener()
57 {
58 //      HRESULT hr;
59
60         // Create a listener and save the IRSXDirectListener interface
61         RSXDIRECTLISTENERDESC rsxDL;            // listener description
62
63         rsxDL.cbSize = sizeof(RSXDIRECTLISTENERDESC);
64 //      rsxDL.hMainWnd = NULL;
65         rsxDL.hMainWnd = (HWND)os_get_window();
66         rsxDL.dwUser = 0;
67         rsxDL.lpwf = NULL;
68
69 /*
70         hr = CoCreateInstance(CLSID_RSXDIRECTLISTENER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXDirectListener, (void **) &lpDL);
71         if ( SUCCEEDED(hr) ) {
72                 hr = lpDL->Initialize(&rsxDL, lpRSXUnk);
73                 if ( SUCCEEDED(hr) )
74                         return 0;
75                 else {
76                         Warning(LOCATION,"Unable to create the RSX listener\n");
77                         return -1;
78                 }
79         } else {
80                 Warning(LOCATION,"Unable to create the RSX listener\n");
81                 return -1;
82         }
83 */
84
85         if( SUCCEEDED(lpRSX->CreateDirectListener(&rsxDL, &lpDL, NULL)) ) {
86                 return 0;
87         } else {
88                 return -1;
89         }
90 }
91
92 // initialize the environment.  lpRSX must be non-null.  Return -1 if there is
93 // an error, otherwise return 0
94 int rsx_init_environment()
95 {
96         Assert(lpRSX != NULL);
97
98         rsxEnv.cbSize = sizeof(RSXENVIRONMENT);
99         rsxEnv.dwFlags = RSXENVIRONMENT_SPEEDOFSOUND;
100         rsxEnv.fSpeedOfSound = 200.0f;
101         if ( lpRSX->SetEnvironment(&rsxEnv) == S_OK )
102                 return 0;
103         else
104                 return -1;
105 }
106
107 // init the RSX sound system.  Return -1 if a failure occurs, otherwise return 0
108 int rsx_init()
109 {
110         HRESULT hr;
111         int             i;
112
113         if ( rsx_initialized )
114                 return 0;
115
116         // Initialize COM Library
117         hr  = CoInitialize(NULL);
118
119         // Specify the class Id for RSX and the interface ID for the IRSX2 interface (use IID_IRSX20 if using IRSX)
120         hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IRSX20, (void **) &lpRSX);
121         if ( !SUCCEEDED(hr) ) {
122                 Warning(LOCATION,"Unable to create the RSX interface\n");
123                 return -1;
124         }
125 /*
126 //      hr = CoCreateInstance(CLSID_RSX20, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **) &lpRSXUnk);
127         // Query the object for an IUnknown interface
128    hr = lpRSX->QueryInterface(IID_IUnknown, (void**)&lpRSXUnk);
129         if ( !SUCCEEDED(hr) ) {
130                 Warning(LOCATION,"Unable to create the RSX Unknown interface\n");
131                 return -1;
132         }
133 */
134
135         if ( rsx_init_environment() == -1 ) {
136                 Warning(LOCATION,"Unable to initialize the RSX environment\n");
137                 return -1;
138         }
139
140         if ( rsx_init_listener() == -1 ) {
141                 Warning(LOCATION,"Unable to initialize the RSX direct listener\n");
142                 return -1;
143         }
144
145         for ( i = 0; i < MAX_SOUNDS; i++ ) {
146                 if ( lpCE[i] != NULL ) {
147                         lpCE[i]->Release();
148                         lpCE[i] = NULL;
149                 }
150         }
151         
152         rsx_initialized = 1;
153         return 0;
154 }
155
156 // called once per frame to update the listener position and orientation
157 void rsx_update_listener(vector *pos, matrix *orient)
158 {
159         HRESULT hr;
160         RSXVECTOR3D u, v;
161
162         if ( !rsx_initialized )
163                 return;
164
165         u.x = pos->x;
166         u.y = pos->y;
167         u.z = pos->z;
168         hr = lpDL->SetPosition(&u);
169         if (hr != S_OK)
170                 Warning(LOCATION,"Unable to set position for the RSX listener\n");
171                 
172         u.x = orient->fvec.x;
173         u.y = orient->fvec.y;
174         u.z = orient->fvec.z;
175
176         v.x = orient->uvec.x;
177         v.y = orient->uvec.y;
178         v.z = orient->uvec.z;
179         
180         hr = lpDL->SetOrientation(&u, &v);
181         if (hr != S_OK)
182                 Warning(LOCATION,"Unable to set orientation for the RSX listener\n");
183 }
184
185 // uninitialize the RSX sound system
186 void rsx_close()
187 {
188         int i;
189
190         for(i = 0; i < MAX_SOUNDS; i++){
191                 if ( lpCE[i] != NULL) {
192                         lpCE[i]->Release();
193                         lpCE[i] = NULL;
194                 }
195         }
196
197         // TODO: release the channels
198     
199         // Release the listener
200         if ( lpDL ) {
201                 lpDL->Release();
202                 lpDL = NULL;
203         }
204
205         // Release RSX
206         if( lpRSX ) {
207                 lpRSX->Release();
208       lpRSX = NULL;
209         }
210
211         CoUninitialize();
212 }
213
214 // return index into lpCE[] array, this is the Sounds[].sid member used to link the game-level
215 // description of the sound to the low-level cached emitter
216 int rsx_create_cached_emitter(char *filename, int is_3d, int use_doppler, int min, int max, float max_volume)
217 {
218         RSXCACHEDEMITTERDESC    rsxCE;  
219         RSXEMITTERMODEL         rsxModel;
220         int                                             ce_index;
221 //      HRESULT                                 hr;
222
223         ZeroMemory(&rsxCE, sizeof(RSXCACHEDEMITTERDESC));
224         rsxCE.cbSize = sizeof(RSXCACHEDEMITTERDESC);
225         strcpy(rsxCE.szFilename, filename);
226
227         ZeroMemory(&rsxModel, sizeof(RSXEMITTERMODEL));
228         rsxModel.cbSize = sizeof(RSXEMITTERMODEL);
229
230         for ( ce_index = 0; ce_index < MAX_SOUNDS; ce_index++ ) {
231                 if ( lpCE[ce_index] == NULL )
232                         break;
233         }
234
235         if ( ce_index == MAX_SOUNDS ) {
236                 Warning(LOCATION, "RSX has exceeded the maximum number of sounds\n");
237                 return -1;
238         } 
239
240         if ( is_3d ) {
241                 rsxCE.dwFlags |= RSXEMITTERDESC_NOREVERB;       // no reverb by default
242                 if ( !use_doppler )
243                         rsxCE.dwFlags |= RSXEMITTERDESC_NODOPPLER;
244
245                 rsxModel.fIntensity     = max_volume;           
246 //              rsxModel.fIntensity     = 1.0f;         
247                 rsxModel.fMinBack               = i2fl(min);
248                 rsxModel.fMinFront      = i2fl(min);
249                 rsxModel.fMaxBack               = i2fl(max);
250                 rsxModel.fMaxFront      = i2fl(max);
251         } else {
252                 rsxCE.dwFlags = RSXEMITTERDESC_NOSPATIALIZE | RSXEMITTERDESC_NOATTENUATE | RSXEMITTERDESC_NODOPPLER | RSXEMITTERDESC_NOREVERB;
253                 rsxModel.fIntensity     = max_volume;           
254         }
255
256 /*
257         hr = CoCreateInstance(CLSID_RSXCACHEDEMITTER, NULL, CLSCTX_INPROC_SERVER, IID_IRSXCachedEmitter, (void **) &lpCE[ce_index]);
258         if ( FAILED(hr) ) {
259                 Warning(LOCATION, "Creating an RSX cached emitter failed\n");
260                 return -1;
261         }
262
263         hr = lpCE[ce_index]->Initialize(&rsxCE, lpRSXUnk);
264         if ( FAILED(hr) ) {
265                 Warning(LOCATION, "Initialization of an RSX cached emitter failed\n");
266                 return -1;
267         }
268 */
269
270         if( !SUCCEEDED(lpRSX->CreateCachedEmitter(&rsxCE, &lpCE[ce_index], NULL)) ) {
271                 Warning(LOCATION, "Could not create a RSX cached emitter\n");
272                 return -1;
273         }
274         
275         lpCE[ce_index]->SetModel(&rsxModel);
276         return ce_index;
277 }
278
279 int rsx_play_3d(int sid, float priority, float volume, vector *pos, vector *sound_fvec)
280 {
281         RSXQUERYMEDIAINFO qmi;
282         qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
283         lpCE[sid]->QueryMediaState(&qmi);
284
285    if ( qmi.dwControl == RSX_PLAY )
286                 return -1;
287
288         lpCE[sid]->SetPosition((RSXVECTOR3D*)pos);
289 //      lpCE[sid]->SetOrientation((RSXVECTOR3D*)sound_fvec);
290         lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
291         return 1;
292 }
293
294 int rsx_play( int sid, float priority, float volume)
295 {
296         RSXQUERYMEDIAINFO qmi;
297         HRESULT                         hr;
298
299         qmi.cbSize = sizeof(RSXQUERYMEDIAINFO);
300         lpCE[sid]->QueryMediaState(&qmi);
301
302    if ( qmi.dwControl == RSX_PLAY )
303                 return -1;
304
305         hr = lpCE[sid]->ControlMedia(RSX_PLAY, 1, 0.0f);
306         if ( hr != S_OK ) {
307                 Warning(LOCATION, "rsx_play() failure\n");
308                 return -1;
309         }
310         return 1;
311 }
312
313
314 void rsx_unload_buffer(int sid)
315 {
316         if ( sid != -1 ) {
317                 if ( lpCE[sid] != NULL ) {
318                         lpCE[sid]->Release();
319                         lpCE[sid] = NULL;
320                 }
321         }
322 }
323