router.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. #include "config.h"
  2. #include "router.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "AL/alc.h"
  7. #include "AL/al.h"
  8. #include "almalloc.h"
  9. #include "version.h"
  10. DriverIface *DriverList = NULL;
  11. int DriverListSize = 0;
  12. static int DriverListSizeMax = 0;
  13. altss_t ThreadCtxDriver;
  14. enum LogLevel LogLevel = LogLevel_Error;
  15. FILE *LogFile;
  16. static void LoadDriverList(void);
  17. BOOL APIENTRY DllMain(HINSTANCE UNUSED(module), DWORD reason, void* UNUSED(reserved))
  18. {
  19. const char *str;
  20. int i;
  21. switch(reason)
  22. {
  23. case DLL_PROCESS_ATTACH:
  24. LogFile = stderr;
  25. str = getenv("ALROUTER_LOGFILE");
  26. if(str && *str != '\0')
  27. {
  28. FILE *f = fopen(str, "w");
  29. if(f == NULL)
  30. ERR("Could not open log file: %s\n", str);
  31. else
  32. LogFile = f;
  33. }
  34. str = getenv("ALROUTER_LOGLEVEL");
  35. if(str && *str != '\0')
  36. {
  37. char *end = NULL;
  38. long l = strtol(str, &end, 0);
  39. if(!end || *end != '\0')
  40. ERR("Invalid log level value: %s\n", str);
  41. else if(l < LogLevel_None || l > LogLevel_Trace)
  42. ERR("Log level out of range: %s\n", str);
  43. else
  44. LogLevel = l;
  45. }
  46. TRACE("Initializing router v0.1-%s %s\n", ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
  47. LoadDriverList();
  48. altss_create(&ThreadCtxDriver, NULL);
  49. InitALC();
  50. break;
  51. case DLL_THREAD_ATTACH:
  52. case DLL_THREAD_DETACH:
  53. break;
  54. case DLL_PROCESS_DETACH:
  55. ReleaseALC();
  56. altss_delete(ThreadCtxDriver);
  57. for(i = 0;i < DriverListSize;i++)
  58. {
  59. if(DriverList[i].Module)
  60. FreeLibrary(DriverList[i].Module);
  61. }
  62. al_free(DriverList);
  63. DriverList = NULL;
  64. DriverListSize = 0;
  65. DriverListSizeMax = 0;
  66. if(LogFile && LogFile != stderr)
  67. fclose(LogFile);
  68. LogFile = NULL;
  69. break;
  70. }
  71. return TRUE;
  72. }
  73. #ifdef __GNUC__
  74. #define CAST_FUNC(x) (__typeof(x))
  75. #else
  76. #define CAST_FUNC(x) (void*)
  77. #endif
  78. static void AddModule(HMODULE module, const WCHAR *name)
  79. {
  80. DriverIface newdrv;
  81. int err = 0;
  82. int i;
  83. for(i = 0;i < DriverListSize;i++)
  84. {
  85. if(DriverList[i].Module == module)
  86. {
  87. TRACE("Skipping already-loaded module %p\n", module);
  88. FreeLibrary(module);
  89. return;
  90. }
  91. if(wcscmp(DriverList[i].Name, name) == 0)
  92. {
  93. TRACE("Skipping similarly-named module %ls\n", name);
  94. FreeLibrary(module);
  95. return;
  96. }
  97. }
  98. if(DriverListSize == DriverListSizeMax)
  99. {
  100. int newmax = DriverListSizeMax ? DriverListSizeMax<<1 : 4;
  101. void *newlist = al_calloc(DEF_ALIGN, sizeof(DriverList[0])*newmax);
  102. if(!newlist) return;
  103. memcpy(newlist, DriverList, DriverListSize*sizeof(DriverList[0]));
  104. al_free(DriverList);
  105. DriverList = newlist;
  106. DriverListSizeMax = newmax;
  107. }
  108. memset(&newdrv, 0, sizeof(newdrv));
  109. /* Load required functions. */
  110. #define LOAD_PROC(x) do { \
  111. newdrv.x = CAST_FUNC(newdrv.x) GetProcAddress(module, #x); \
  112. if(!newdrv.x) \
  113. { \
  114. ERR("Failed to find entry point for %s in %ls\n", #x, name); \
  115. err = 1; \
  116. } \
  117. } while(0)
  118. LOAD_PROC(alcCreateContext);
  119. LOAD_PROC(alcMakeContextCurrent);
  120. LOAD_PROC(alcProcessContext);
  121. LOAD_PROC(alcSuspendContext);
  122. LOAD_PROC(alcDestroyContext);
  123. LOAD_PROC(alcGetCurrentContext);
  124. LOAD_PROC(alcGetContextsDevice);
  125. LOAD_PROC(alcOpenDevice);
  126. LOAD_PROC(alcCloseDevice);
  127. LOAD_PROC(alcGetError);
  128. LOAD_PROC(alcIsExtensionPresent);
  129. LOAD_PROC(alcGetProcAddress);
  130. LOAD_PROC(alcGetEnumValue);
  131. LOAD_PROC(alcGetString);
  132. LOAD_PROC(alcGetIntegerv);
  133. LOAD_PROC(alcCaptureOpenDevice);
  134. LOAD_PROC(alcCaptureCloseDevice);
  135. LOAD_PROC(alcCaptureStart);
  136. LOAD_PROC(alcCaptureStop);
  137. LOAD_PROC(alcCaptureSamples);
  138. LOAD_PROC(alEnable);
  139. LOAD_PROC(alDisable);
  140. LOAD_PROC(alIsEnabled);
  141. LOAD_PROC(alGetString);
  142. LOAD_PROC(alGetBooleanv);
  143. LOAD_PROC(alGetIntegerv);
  144. LOAD_PROC(alGetFloatv);
  145. LOAD_PROC(alGetDoublev);
  146. LOAD_PROC(alGetBoolean);
  147. LOAD_PROC(alGetInteger);
  148. LOAD_PROC(alGetFloat);
  149. LOAD_PROC(alGetDouble);
  150. LOAD_PROC(alGetError);
  151. LOAD_PROC(alIsExtensionPresent);
  152. LOAD_PROC(alGetProcAddress);
  153. LOAD_PROC(alGetEnumValue);
  154. LOAD_PROC(alListenerf);
  155. LOAD_PROC(alListener3f);
  156. LOAD_PROC(alListenerfv);
  157. LOAD_PROC(alListeneri);
  158. LOAD_PROC(alListener3i);
  159. LOAD_PROC(alListeneriv);
  160. LOAD_PROC(alGetListenerf);
  161. LOAD_PROC(alGetListener3f);
  162. LOAD_PROC(alGetListenerfv);
  163. LOAD_PROC(alGetListeneri);
  164. LOAD_PROC(alGetListener3i);
  165. LOAD_PROC(alGetListeneriv);
  166. LOAD_PROC(alGenSources);
  167. LOAD_PROC(alDeleteSources);
  168. LOAD_PROC(alIsSource);
  169. LOAD_PROC(alSourcef);
  170. LOAD_PROC(alSource3f);
  171. LOAD_PROC(alSourcefv);
  172. LOAD_PROC(alSourcei);
  173. LOAD_PROC(alSource3i);
  174. LOAD_PROC(alSourceiv);
  175. LOAD_PROC(alGetSourcef);
  176. LOAD_PROC(alGetSource3f);
  177. LOAD_PROC(alGetSourcefv);
  178. LOAD_PROC(alGetSourcei);
  179. LOAD_PROC(alGetSource3i);
  180. LOAD_PROC(alGetSourceiv);
  181. LOAD_PROC(alSourcePlayv);
  182. LOAD_PROC(alSourceStopv);
  183. LOAD_PROC(alSourceRewindv);
  184. LOAD_PROC(alSourcePausev);
  185. LOAD_PROC(alSourcePlay);
  186. LOAD_PROC(alSourceStop);
  187. LOAD_PROC(alSourceRewind);
  188. LOAD_PROC(alSourcePause);
  189. LOAD_PROC(alSourceQueueBuffers);
  190. LOAD_PROC(alSourceUnqueueBuffers);
  191. LOAD_PROC(alGenBuffers);
  192. LOAD_PROC(alDeleteBuffers);
  193. LOAD_PROC(alIsBuffer);
  194. LOAD_PROC(alBufferf);
  195. LOAD_PROC(alBuffer3f);
  196. LOAD_PROC(alBufferfv);
  197. LOAD_PROC(alBufferi);
  198. LOAD_PROC(alBuffer3i);
  199. LOAD_PROC(alBufferiv);
  200. LOAD_PROC(alGetBufferf);
  201. LOAD_PROC(alGetBuffer3f);
  202. LOAD_PROC(alGetBufferfv);
  203. LOAD_PROC(alGetBufferi);
  204. LOAD_PROC(alGetBuffer3i);
  205. LOAD_PROC(alGetBufferiv);
  206. LOAD_PROC(alBufferData);
  207. LOAD_PROC(alDopplerFactor);
  208. LOAD_PROC(alDopplerVelocity);
  209. LOAD_PROC(alSpeedOfSound);
  210. LOAD_PROC(alDistanceModel);
  211. if(!err)
  212. {
  213. ALCint alc_ver[2] = { 0, 0 };
  214. wcsncpy(newdrv.Name, name, 32);
  215. newdrv.Module = module;
  216. newdrv.alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &alc_ver[0]);
  217. newdrv.alcGetIntegerv(NULL, ALC_MINOR_VERSION, 1, &alc_ver[1]);
  218. if(newdrv.alcGetError(NULL) == ALC_NO_ERROR)
  219. newdrv.ALCVer = MAKE_ALC_VER(alc_ver[0], alc_ver[1]);
  220. else
  221. newdrv.ALCVer = MAKE_ALC_VER(1, 0);
  222. #undef LOAD_PROC
  223. #define LOAD_PROC(x) do { \
  224. newdrv.x = CAST_FUNC(newdrv.x) newdrv.alcGetProcAddress(NULL, #x); \
  225. if(!newdrv.x) \
  226. { \
  227. ERR("Failed to find entry point for %s in %ls\n", #x, name); \
  228. err = 1; \
  229. } \
  230. } while(0)
  231. if(newdrv.alcIsExtensionPresent(NULL, "ALC_EXT_thread_local_context"))
  232. {
  233. LOAD_PROC(alcSetThreadContext);
  234. LOAD_PROC(alcGetThreadContext);
  235. }
  236. }
  237. if(!err)
  238. {
  239. TRACE("Loaded module %p, %ls, ALC %d.%d\n", module, name,
  240. newdrv.ALCVer>>8, newdrv.ALCVer&255);
  241. DriverList[DriverListSize++] = newdrv;
  242. }
  243. #undef LOAD_PROC
  244. }
  245. static void SearchDrivers(WCHAR *path)
  246. {
  247. WCHAR srchPath[MAX_PATH+1] = L"";
  248. WIN32_FIND_DATAW fdata;
  249. HANDLE srchHdl;
  250. TRACE("Searching for drivers in %ls...\n", path);
  251. wcsncpy(srchPath, path, MAX_PATH);
  252. wcsncat(srchPath, L"\\*oal.dll", MAX_PATH - lstrlenW(srchPath));
  253. srchHdl = FindFirstFileW(srchPath, &fdata);
  254. if(srchHdl != INVALID_HANDLE_VALUE)
  255. {
  256. do {
  257. HMODULE mod;
  258. wcsncpy(srchPath, path, MAX_PATH);
  259. wcsncat(srchPath, L"\\", MAX_PATH - lstrlenW(srchPath));
  260. wcsncat(srchPath, fdata.cFileName, MAX_PATH - lstrlenW(srchPath));
  261. TRACE("Found %ls\n", srchPath);
  262. mod = LoadLibraryW(srchPath);
  263. if(!mod)
  264. WARN("Could not load %ls\n", srchPath);
  265. else
  266. AddModule(mod, fdata.cFileName);
  267. } while(FindNextFileW(srchHdl, &fdata));
  268. FindClose(srchHdl);
  269. }
  270. }
  271. static WCHAR *strrchrW(WCHAR *str, WCHAR ch)
  272. {
  273. WCHAR *res = NULL;
  274. while(str && *str != '\0')
  275. {
  276. if(*str == ch)
  277. res = str;
  278. ++str;
  279. }
  280. return res;
  281. }
  282. static int GetLoadedModuleDirectory(const WCHAR *name, WCHAR *moddir, DWORD length)
  283. {
  284. HMODULE module = NULL;
  285. WCHAR *sep0, *sep1;
  286. if(name)
  287. {
  288. module = GetModuleHandleW(name);
  289. if(!module) return 0;
  290. }
  291. if(GetModuleFileNameW(module, moddir, length) == 0)
  292. return 0;
  293. sep0 = strrchrW(moddir, '/');
  294. if(sep0) sep1 = strrchrW(sep0+1, '\\');
  295. else sep1 = strrchrW(moddir, '\\');
  296. if(sep1) *sep1 = '\0';
  297. else if(sep0) *sep0 = '\0';
  298. else *moddir = '\0';
  299. return 1;
  300. }
  301. void LoadDriverList(void)
  302. {
  303. WCHAR path[MAX_PATH+1] = L"";
  304. int len;
  305. if(GetLoadedModuleDirectory(L"OpenAL32.dll", path, MAX_PATH))
  306. SearchDrivers(path);
  307. GetCurrentDirectoryW(MAX_PATH, path);
  308. len = lstrlenW(path);
  309. if(len > 0 && (path[len-1] == '\\' || path[len-1] == '/'))
  310. path[len-1] = '\0';
  311. SearchDrivers(path);
  312. if(GetLoadedModuleDirectory(NULL, path, MAX_PATH))
  313. SearchDrivers(path);
  314. GetSystemDirectoryW(path, MAX_PATH);
  315. len = lstrlenW(path);
  316. if(len > 0 && (path[len-1] == '\\' || path[len-1] == '/'))
  317. path[len-1] = '\0';
  318. SearchDrivers(path);
  319. }
  320. void InitPtrIntMap(PtrIntMap *map)
  321. {
  322. map->keys = NULL;
  323. map->values = NULL;
  324. map->size = 0;
  325. map->capacity = 0;
  326. RWLockInit(&map->lock);
  327. }
  328. void ResetPtrIntMap(PtrIntMap *map)
  329. {
  330. WriteLock(&map->lock);
  331. al_free(map->keys);
  332. map->keys = NULL;
  333. map->values = NULL;
  334. map->size = 0;
  335. map->capacity = 0;
  336. WriteUnlock(&map->lock);
  337. }
  338. ALenum InsertPtrIntMapEntry(PtrIntMap *map, ALvoid *key, ALint value)
  339. {
  340. ALsizei pos = 0;
  341. WriteLock(&map->lock);
  342. if(map->size > 0)
  343. {
  344. ALsizei count = map->size;
  345. do {
  346. ALsizei step = count>>1;
  347. ALsizei i = pos+step;
  348. if(!(map->keys[i] < key))
  349. count = step;
  350. else
  351. {
  352. pos = i+1;
  353. count -= step+1;
  354. }
  355. } while(count > 0);
  356. }
  357. if(pos == map->size || map->keys[pos] != key)
  358. {
  359. if(map->size == map->capacity)
  360. {
  361. ALvoid **keys = NULL;
  362. ALint *values;
  363. ALsizei newcap;
  364. newcap = (map->capacity ? (map->capacity<<1) : 4);
  365. if(newcap > map->capacity)
  366. keys = al_calloc(16, (sizeof(map->keys[0])+sizeof(map->values[0]))*newcap);
  367. if(!keys)
  368. {
  369. WriteUnlock(&map->lock);
  370. return AL_OUT_OF_MEMORY;
  371. }
  372. values = (ALint*)&keys[newcap];
  373. if(map->keys)
  374. {
  375. memcpy(keys, map->keys, map->size*sizeof(map->keys[0]));
  376. memcpy(values, map->values, map->size*sizeof(map->values[0]));
  377. }
  378. al_free(map->keys);
  379. map->keys = keys;
  380. map->values = values;
  381. map->capacity = newcap;
  382. }
  383. if(pos < map->size)
  384. {
  385. memmove(&map->keys[pos+1], &map->keys[pos],
  386. (map->size-pos)*sizeof(map->keys[0]));
  387. memmove(&map->values[pos+1], &map->values[pos],
  388. (map->size-pos)*sizeof(map->values[0]));
  389. }
  390. map->size++;
  391. }
  392. map->keys[pos] = key;
  393. map->values[pos] = value;
  394. WriteUnlock(&map->lock);
  395. return AL_NO_ERROR;
  396. }
  397. ALint RemovePtrIntMapKey(PtrIntMap *map, ALvoid *key)
  398. {
  399. ALint ret = -1;
  400. WriteLock(&map->lock);
  401. if(map->size > 0)
  402. {
  403. ALsizei pos = 0;
  404. ALsizei count = map->size;
  405. do {
  406. ALsizei step = count>>1;
  407. ALsizei i = pos+step;
  408. if(!(map->keys[i] < key))
  409. count = step;
  410. else
  411. {
  412. pos = i+1;
  413. count -= step+1;
  414. }
  415. } while(count > 0);
  416. if(pos < map->size && map->keys[pos] == key)
  417. {
  418. ret = map->values[pos];
  419. if(pos < map->size-1)
  420. {
  421. memmove(&map->keys[pos], &map->keys[pos+1],
  422. (map->size-1-pos)*sizeof(map->keys[0]));
  423. memmove(&map->values[pos], &map->values[pos+1],
  424. (map->size-1-pos)*sizeof(map->values[0]));
  425. }
  426. map->size--;
  427. }
  428. }
  429. WriteUnlock(&map->lock);
  430. return ret;
  431. }
  432. ALint LookupPtrIntMapKey(PtrIntMap *map, ALvoid *key)
  433. {
  434. ALint ret = -1;
  435. ReadLock(&map->lock);
  436. if(map->size > 0)
  437. {
  438. ALsizei pos = 0;
  439. ALsizei count = map->size;
  440. do {
  441. ALsizei step = count>>1;
  442. ALsizei i = pos+step;
  443. if(!(map->keys[i] < key))
  444. count = step;
  445. else
  446. {
  447. pos = i+1;
  448. count -= step+1;
  449. }
  450. } while(count > 0);
  451. if(pos < map->size && map->keys[pos] == key)
  452. ret = map->values[pos];
  453. }
  454. ReadUnlock(&map->lock);
  455. return ret;
  456. }