1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #ifdef USE_OPENAL
22 
23 #include "../client/snd_loc.h"
24 
25 
26 alConfig_t	alConfig;
27 alState_t	alState;
28 
29 
30 /*
31  =================
32  AL_InitExtensions
33  =================
34 */
AL_InitExtensions(void)35 static void AL_InitExtensions (void)
36 {
37 	if (!s_openal_extensions->intvalue)
38 	{
39 		Com_Printf("*** IGNORING OPENAL EXTENSIONS ***\n", LOG_CLIENT);
40 		return;
41 	}
42 
43 	Com_Printf("Initializing OpenAL extensions\n", LOG_CLIENT);
44 
45 	if (qalIsExtensionPresent("EAX2.0"))
46 	{
47 		if (s_openal_eax->intvalue)
48 		{
49 			alConfig.eax = true;
50 
51 			qalEAXSet = (ALEAXSET)qalGetProcAddress("EAXSet");
52 			qalEAXGet = (ALEAXGET)qalGetProcAddress("EAXGet");
53 
54 			Com_Printf("...using EAX2.0\n", LOG_CLIENT);
55 		}
56 		else
57 			Com_Printf("...ignoring EAX2.0\n", LOG_CLIENT);
58 	}
59 	else
60 		Com_Printf("...EAX2.0 not found\n", LOG_CLIENT);
61 }
62 
63 /*
64  =================
65  AL_InitDriver
66  =================
67 */
AL_InitDriver(void)68 static qboolean AL_InitDriver (void)
69 {
70 	char	*deviceName;
71 
72 	Com_Printf("Initializing OpenAL driver\n", LOG_CLIENT);
73 
74 	// Open the device
75 	deviceName = s_openal_device->string;
76 
77 	if (!deviceName[0])
78 		deviceName = NULL;
79 
80 	if (deviceName)
81 		Com_Printf("...opening device (%s): ", LOG_CLIENT, deviceName);
82 	else
83 		Com_Printf("...opening device: ", LOG_CLIENT);
84 
85 	if ((alState.hDevice = qalcOpenDevice(deviceName)) == NULL)
86 	{
87 		Com_Printf("failed\n", LOG_CLIENT);
88 		return false;
89 	}
90 
91 	if (!deviceName)
92 		Com_Printf("succeeded (%s)\n", LOG_CLIENT, qalcGetString(alState.hDevice, ALC_DEVICE_SPECIFIER));
93 	else
94 		Com_Printf("succeeded\n", LOG_CLIENT);
95 
96 	// Create the AL context and make it current
97 	Com_Printf("...creating AL context: ", LOG_CLIENT);
98 	if ((alState.hALC = qalcCreateContext(alState.hDevice, NULL)) == NULL)
99 	{
100 		Com_Printf("failed\n", LOG_CLIENT);
101 		goto failed;
102 	}
103 	Com_Printf("succeeded\n", LOG_CLIENT);
104 
105 	// turol: FIXME: this is broken
106 	Com_Printf("...making context current: ", LOG_CLIENT);
107 	if (!qalcMakeContextCurrent(alState.hALC))
108 	{
109 		Com_Printf("failed\n", LOG_CLIENT);
110 		goto failed;
111 	}
112 	Com_Printf("succeeded\n", LOG_CLIENT);
113 
114 	return true;
115 
116 failed:
117 
118 	Com_Printf("...failed hard\n", LOG_CLIENT);
119 
120 	if (alState.hALC)
121 	{
122 		qalcDestroyContext(alState.hALC);
123 		alState.hALC = NULL;
124 	}
125 
126 	if (alState.hDevice)
127 	{
128 		qalcCloseDevice(alState.hDevice);
129 		alState.hDevice = NULL;
130 	}
131 
132 	return false;
133 }
134 
135 /*
136  =================
137  AL_StartOpenAL
138  =================
139 */
AL_StartOpenAL(const char * driver)140 static qboolean AL_StartOpenAL (const char *driver)
141 {
142 	// Initialize our QAL dynamic bindings
143 	if (!QAL_Init(driver))
144 		return false;
145 
146 	// Get device list
147 	if (qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
148 		alConfig.deviceList = qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
149 	else
150 		alConfig.deviceList = "DirectSound3D\0DirectSound\0MMSYSTEM\0\0";
151 
152 	// Initialize the device, context, etc...
153 	if (AL_InitDriver())
154 		return true;
155 
156 	// Shutdown QAL
157 	QAL_Shutdown();
158 
159 	return false;
160 }
161 
162 /*
163  =================
164  AL_Init
165  =================
166 */
AL_Init(void)167 qboolean AL_Init (void){
168 
169 	Com_Printf("Initializing OpenAL subsystem\n", LOG_CLIENT);
170 
171 	// Initialize OpenAL subsystem
172 	if (!AL_StartOpenAL(AL_DRIVER_OPENAL))
173 	{
174 		// Let the user continue without sound
175 		Com_Printf ("WARNING: OpenAL initialization failed\n", LOG_CLIENT|LOG_WARNING);
176 		return false;
177 	}
178 
179 	// Get AL strings
180 	alConfig.vendorString = qalGetString(AL_VENDOR);
181 	alConfig.rendererString = qalGetString(AL_RENDERER);
182 	alConfig.versionString = qalGetString(AL_VERSION);
183 	alConfig.extensionsString = qalGetString(AL_EXTENSIONS);
184 
185 	// Get device name
186 	alConfig.deviceName = qalcGetString(alState.hDevice, ALC_DEVICE_SPECIFIER);
187 
188 	// Initialize extensions
189 	AL_InitExtensions();
190 
191 	return true;
192 }
193 
194 /*
195  =================
196  AL_Shutdown
197  =================
198 */
AL_Shutdown(void)199 void AL_Shutdown (void){
200 
201 	Com_Printf("Shutting down OpenAL subsystem\n", LOG_CLIENT);
202 
203 	if (alState.hALC)
204 	{
205 		if (qalcMakeContextCurrent)
206 		{
207 			Com_Printf("...alcMakeContextCurrent( NULL ): ", LOG_CLIENT);
208 			if (!qalcMakeContextCurrent(NULL))
209 				Com_Printf("failed\n", LOG_CLIENT);
210 			else
211 				Com_Printf("succeeded\n", LOG_CLIENT);
212 		}
213 
214 		if (qalcDestroyContext)
215 		{
216 			Com_Printf("...destroying AL context\n", LOG_CLIENT);
217 			qalcDestroyContext(alState.hALC);
218 		}
219 
220 		alState.hALC = NULL;
221 	}
222 
223 	if (alState.hDevice)
224 	{
225 		if (qalcCloseDevice)
226 		{
227 			Com_Printf("...closing device\n", LOG_CLIENT);
228 			qalcCloseDevice(alState.hDevice);
229 		}
230 
231 		alState.hDevice = NULL;
232 	}
233 
234 	QAL_Shutdown();
235 
236 	memset(&alConfig, 0, sizeof(alConfig_t));
237 	memset(&alState, 0, sizeof(alState_t));
238 }
239 
240 #endif
241