Remove another gratuitous [[likely]]
[openal-soft.git] / router / router.h
blob2a126d42cebbd2ee26af829f9c5a4901b515d5a9
1 #ifndef ROUTER_ROUTER_H
2 #define ROUTER_ROUTER_H
4 #define WIN32_LEAN_AND_MEAN
5 #include <windows.h>
6 #include <winnt.h>
8 #include <stdio.h>
10 #include <atomic>
11 #include <memory>
12 #include <mutex>
13 #include <string>
14 #include <utility>
15 #include <vector>
17 #include "AL/alc.h"
18 #include "AL/al.h"
19 #include "AL/alext.h"
22 #define MAKE_ALC_VER(major, minor) (((major)<<8) | (minor))
24 struct DriverIface {
25 std::wstring Name;
26 HMODULE Module{nullptr};
27 int ALCVer{0};
28 std::once_flag InitOnceCtx{};
30 LPALCCREATECONTEXT alcCreateContext{nullptr};
31 LPALCMAKECONTEXTCURRENT alcMakeContextCurrent{nullptr};
32 LPALCPROCESSCONTEXT alcProcessContext{nullptr};
33 LPALCSUSPENDCONTEXT alcSuspendContext{nullptr};
34 LPALCDESTROYCONTEXT alcDestroyContext{nullptr};
35 LPALCGETCURRENTCONTEXT alcGetCurrentContext{nullptr};
36 LPALCGETCONTEXTSDEVICE alcGetContextsDevice{nullptr};
37 LPALCOPENDEVICE alcOpenDevice{nullptr};
38 LPALCCLOSEDEVICE alcCloseDevice{nullptr};
39 LPALCGETERROR alcGetError{nullptr};
40 LPALCISEXTENSIONPRESENT alcIsExtensionPresent{nullptr};
41 LPALCGETPROCADDRESS alcGetProcAddress{nullptr};
42 LPALCGETENUMVALUE alcGetEnumValue{nullptr};
43 LPALCGETSTRING alcGetString{nullptr};
44 LPALCGETINTEGERV alcGetIntegerv{nullptr};
45 LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice{nullptr};
46 LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice{nullptr};
47 LPALCCAPTURESTART alcCaptureStart{nullptr};
48 LPALCCAPTURESTOP alcCaptureStop{nullptr};
49 LPALCCAPTURESAMPLES alcCaptureSamples{nullptr};
51 PFNALCSETTHREADCONTEXTPROC alcSetThreadContext{nullptr};
52 PFNALCGETTHREADCONTEXTPROC alcGetThreadContext{nullptr};
54 LPALENABLE alEnable{nullptr};
55 LPALDISABLE alDisable{nullptr};
56 LPALISENABLED alIsEnabled{nullptr};
57 LPALGETSTRING alGetString{nullptr};
58 LPALGETBOOLEANV alGetBooleanv{nullptr};
59 LPALGETINTEGERV alGetIntegerv{nullptr};
60 LPALGETFLOATV alGetFloatv{nullptr};
61 LPALGETDOUBLEV alGetDoublev{nullptr};
62 LPALGETBOOLEAN alGetBoolean{nullptr};
63 LPALGETINTEGER alGetInteger{nullptr};
64 LPALGETFLOAT alGetFloat{nullptr};
65 LPALGETDOUBLE alGetDouble{nullptr};
66 LPALGETERROR alGetError{nullptr};
67 LPALISEXTENSIONPRESENT alIsExtensionPresent{nullptr};
68 LPALGETPROCADDRESS alGetProcAddress{nullptr};
69 LPALGETENUMVALUE alGetEnumValue{nullptr};
70 LPALLISTENERF alListenerf{nullptr};
71 LPALLISTENER3F alListener3f{nullptr};
72 LPALLISTENERFV alListenerfv{nullptr};
73 LPALLISTENERI alListeneri{nullptr};
74 LPALLISTENER3I alListener3i{nullptr};
75 LPALLISTENERIV alListeneriv{nullptr};
76 LPALGETLISTENERF alGetListenerf{nullptr};
77 LPALGETLISTENER3F alGetListener3f{nullptr};
78 LPALGETLISTENERFV alGetListenerfv{nullptr};
79 LPALGETLISTENERI alGetListeneri{nullptr};
80 LPALGETLISTENER3I alGetListener3i{nullptr};
81 LPALGETLISTENERIV alGetListeneriv{nullptr};
82 LPALGENSOURCES alGenSources{nullptr};
83 LPALDELETESOURCES alDeleteSources{nullptr};
84 LPALISSOURCE alIsSource{nullptr};
85 LPALSOURCEF alSourcef{nullptr};
86 LPALSOURCE3F alSource3f{nullptr};
87 LPALSOURCEFV alSourcefv{nullptr};
88 LPALSOURCEI alSourcei{nullptr};
89 LPALSOURCE3I alSource3i{nullptr};
90 LPALSOURCEIV alSourceiv{nullptr};
91 LPALGETSOURCEF alGetSourcef{nullptr};
92 LPALGETSOURCE3F alGetSource3f{nullptr};
93 LPALGETSOURCEFV alGetSourcefv{nullptr};
94 LPALGETSOURCEI alGetSourcei{nullptr};
95 LPALGETSOURCE3I alGetSource3i{nullptr};
96 LPALGETSOURCEIV alGetSourceiv{nullptr};
97 LPALSOURCEPLAYV alSourcePlayv{nullptr};
98 LPALSOURCESTOPV alSourceStopv{nullptr};
99 LPALSOURCEREWINDV alSourceRewindv{nullptr};
100 LPALSOURCEPAUSEV alSourcePausev{nullptr};
101 LPALSOURCEPLAY alSourcePlay{nullptr};
102 LPALSOURCESTOP alSourceStop{nullptr};
103 LPALSOURCEREWIND alSourceRewind{nullptr};
104 LPALSOURCEPAUSE alSourcePause{nullptr};
105 LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers{nullptr};
106 LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers{nullptr};
107 LPALGENBUFFERS alGenBuffers{nullptr};
108 LPALDELETEBUFFERS alDeleteBuffers{nullptr};
109 LPALISBUFFER alIsBuffer{nullptr};
110 LPALBUFFERF alBufferf{nullptr};
111 LPALBUFFER3F alBuffer3f{nullptr};
112 LPALBUFFERFV alBufferfv{nullptr};
113 LPALBUFFERI alBufferi{nullptr};
114 LPALBUFFER3I alBuffer3i{nullptr};
115 LPALBUFFERIV alBufferiv{nullptr};
116 LPALGETBUFFERF alGetBufferf{nullptr};
117 LPALGETBUFFER3F alGetBuffer3f{nullptr};
118 LPALGETBUFFERFV alGetBufferfv{nullptr};
119 LPALGETBUFFERI alGetBufferi{nullptr};
120 LPALGETBUFFER3I alGetBuffer3i{nullptr};
121 LPALGETBUFFERIV alGetBufferiv{nullptr};
122 LPALBUFFERDATA alBufferData{nullptr};
123 LPALDOPPLERFACTOR alDopplerFactor{nullptr};
124 LPALDOPPLERVELOCITY alDopplerVelocity{nullptr};
125 LPALSPEEDOFSOUND alSpeedOfSound{nullptr};
126 LPALDISTANCEMODEL alDistanceModel{nullptr};
128 /* Functions to load after first context creation. */
129 LPALGENFILTERS alGenFilters{nullptr};
130 LPALDELETEFILTERS alDeleteFilters{nullptr};
131 LPALISFILTER alIsFilter{nullptr};
132 LPALFILTERF alFilterf{nullptr};
133 LPALFILTERFV alFilterfv{nullptr};
134 LPALFILTERI alFilteri{nullptr};
135 LPALFILTERIV alFilteriv{nullptr};
136 LPALGETFILTERF alGetFilterf{nullptr};
137 LPALGETFILTERFV alGetFilterfv{nullptr};
138 LPALGETFILTERI alGetFilteri{nullptr};
139 LPALGETFILTERIV alGetFilteriv{nullptr};
140 LPALGENEFFECTS alGenEffects{nullptr};
141 LPALDELETEEFFECTS alDeleteEffects{nullptr};
142 LPALISEFFECT alIsEffect{nullptr};
143 LPALEFFECTF alEffectf{nullptr};
144 LPALEFFECTFV alEffectfv{nullptr};
145 LPALEFFECTI alEffecti{nullptr};
146 LPALEFFECTIV alEffectiv{nullptr};
147 LPALGETEFFECTF alGetEffectf{nullptr};
148 LPALGETEFFECTFV alGetEffectfv{nullptr};
149 LPALGETEFFECTI alGetEffecti{nullptr};
150 LPALGETEFFECTIV alGetEffectiv{nullptr};
151 LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots{nullptr};
152 LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots{nullptr};
153 LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot{nullptr};
154 LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf{nullptr};
155 LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv{nullptr};
156 LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti{nullptr};
157 LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv{nullptr};
158 LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf{nullptr};
159 LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv{nullptr};
160 LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti{nullptr};
161 LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv{nullptr};
163 template<typename T>
164 DriverIface(T&& name, HMODULE mod)
165 : Name(std::forward<T>(name)), Module(mod)
167 ~DriverIface()
169 if(Module)
170 FreeLibrary(Module);
171 Module = nullptr;
174 using DriverIfacePtr = std::unique_ptr<DriverIface>;
176 extern std::vector<DriverIfacePtr> DriverList;
178 extern thread_local DriverIface *ThreadCtxDriver;
179 extern std::atomic<DriverIface*> CurrentCtxDriver;
181 /* HACK: MinGW generates bad code when accessing an extern thread_local object.
182 * Add a wrapper function for it that only accesses it where it's defined.
184 #ifdef __MINGW32__
185 DriverIface *GetThreadDriver() noexcept;
186 void SetThreadDriver(DriverIface *driver) noexcept;
187 #else
188 inline DriverIface *GetThreadDriver() noexcept { return ThreadCtxDriver; }
189 inline void SetThreadDriver(DriverIface *driver) noexcept { ThreadCtxDriver = driver; }
190 #endif
193 class PtrIntMap {
194 void **mKeys{nullptr};
195 /* Shares memory with keys. */
196 int *mValues{nullptr};
198 ALsizei mSize{0};
199 ALsizei mCapacity{0};
200 std::mutex mLock;
202 public:
203 PtrIntMap() = default;
204 ~PtrIntMap();
206 ALenum insert(void *key, int value);
207 int removeByKey(void *key);
208 int lookupByKey(void *key);
212 enum LogLevel {
213 LogLevel_None = 0,
214 LogLevel_Error = 1,
215 LogLevel_Warn = 2,
216 LogLevel_Trace = 3,
218 extern enum LogLevel LogLevel;
219 extern FILE *LogFile;
221 #define TRACE(...) do { \
222 if(LogLevel >= LogLevel_Trace) \
224 fprintf(LogFile, "AL Router (II): " __VA_ARGS__); \
225 fflush(LogFile); \
227 } while(0)
228 #define WARN(...) do { \
229 if(LogLevel >= LogLevel_Warn) \
231 fprintf(LogFile, "AL Router (WW): " __VA_ARGS__); \
232 fflush(LogFile); \
234 } while(0)
235 #define ERR(...) do { \
236 if(LogLevel >= LogLevel_Error) \
238 fprintf(LogFile, "AL Router (EE): " __VA_ARGS__); \
239 fflush(LogFile); \
241 } while(0)
243 #endif /* ROUTER_ROUTER_H */