diff options
-rw-r--r-- | Alc/alu.cpp | 27 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 10 | ||||
-rw-r--r-- | OpenAL32/alSource.cpp | 18 | ||||
-rw-r--r-- | OpenAL32/event.cpp | 21 |
4 files changed, 36 insertions, 40 deletions
diff --git a/Alc/alu.cpp b/Alc/alu.cpp index b9fe95f0..197d554d 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -287,31 +287,12 @@ aluVector aluMatrixfVector(const aluMatrixf *mtx, const aluVector *vec) void SendSourceStoppedEvent(ALCcontext *context, ALuint id) { - AsyncEvent evt = ASYNC_EVENT(EventType_SourceStateChange); - ALbitfieldSOFT enabledevt; - size_t strpos; - ALuint scale; - - enabledevt = context->EnabledEvts.load(std::memory_order_acquire); + ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)}; if(!(enabledevt&EventType_SourceStateChange)) return; - evt.u.user.type = AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT; - evt.u.user.id = id; - evt.u.user.param = AL_STOPPED; - - /* Normally snprintf would be used, but this is called from the mixer and - * that function's not real-time safe, so we have to construct it manually. - */ - strcpy(evt.u.user.msg, "Source ID "); strpos = 10; - scale = 1000000000; - while(scale > 0 && scale > id) - scale /= 10; - while(scale > 0) - { - evt.u.user.msg[strpos++] = '0' + ((id/scale)%10); - scale /= 10; - } - strcpy(evt.u.user.msg+strpos, " state changed to AL_STOPPED"); + AsyncEvent evt{ASYNC_EVENT(EventType_SourceStateChange)}; + evt.u.srcstate.id = id; + evt.u.srcstate.state = AL_STOPPED; if(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) == 1) context->EventSem.post(); diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 898c8a08..bff3d52e 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -841,11 +841,15 @@ enum { EventType_ReleaseEffectState = 65536, }; -typedef struct AsyncEvent { +struct AsyncEvent { unsigned int EnumType; union { char dummy; struct { + ALuint id; + ALenum state; + } srcstate; + struct { ALenum type; ALuint id; ALuint param; @@ -853,8 +857,8 @@ typedef struct AsyncEvent { } user; EffectState *mEffectState; } u; -} AsyncEvent; -#define ASYNC_EVENT(t) { t, { 0 } } +}; +#define ASYNC_EVENT(t) AsyncEvent{ t, { 0 } } void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends); diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index 87729c73..11cea945 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -684,21 +684,13 @@ inline bool SourceShouldUpdate(ALsource *source, ALCcontext *context) /** Can only be called while the mixer is locked! */ void SendStateChangeEvent(ALCcontext *context, ALuint id, ALenum state) { - AsyncEvent evt = ASYNC_EVENT(EventType_SourceStateChange); - ALbitfieldSOFT enabledevt; - - enabledevt = context->EnabledEvts.load(std::memory_order_acquire); + ALbitfieldSOFT enabledevt{context->EnabledEvts.load(std::memory_order_acquire)}; if(!(enabledevt&EventType_SourceStateChange)) return; - evt.u.user.type = AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT; - evt.u.user.id = id; - evt.u.user.param = state; - snprintf(evt.u.user.msg, sizeof(evt.u.user.msg), "Source ID %u state changed to %s", id, - (state==AL_INITIAL) ? "AL_INITIAL" : - (state==AL_PLAYING) ? "AL_PLAYING" : - (state==AL_PAUSED) ? "AL_PAUSED" : - (state==AL_STOPPED) ? "AL_STOPPED" : "<unknown>" - ); + AsyncEvent evt{ASYNC_EVENT(EventType_SourceStateChange)}; + evt.u.srcstate.id = id; + evt.u.srcstate.state = state; + /* The mixer may have queued a state change that's not yet been processed, * and we don't want state change messages to occur out of order, so send * it through the async queue to ensure proper ordering. diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp index b7599a02..4980abee 100644 --- a/OpenAL32/event.cpp +++ b/OpenAL32/event.cpp @@ -39,7 +39,26 @@ static int EventThread(ALCcontext *context) } ALbitfieldSOFT enabledevts{context->EnabledEvts.load(std::memory_order_acquire)}; - if(context->EventCb && (enabledevts&evt.EnumType) == evt.EnumType) + if(!context->EventCb) continue; + + if(evt.EnumType == EventType_SourceStateChange) + { + if(!(enabledevts&EventType_SourceStateChange)) + continue; + char msg[1024]{}; + int msglen{snprintf(msg, sizeof(msg), "Source ID %u state changed to %s", + evt.u.srcstate.id, + (evt.u.srcstate.state==AL_INITIAL) ? "AL_INITIAL" : + (evt.u.srcstate.state==AL_PLAYING) ? "AL_PLAYING" : + (evt.u.srcstate.state==AL_PAUSED) ? "AL_PAUSED" : + (evt.u.srcstate.state==AL_STOPPED) ? "AL_STOPPED" : "<unknown>" + )}; + if(msglen < 1) msglen = strlen(msg); + context->EventCb(AL_EVENT_TYPE_SOURCE_STATE_CHANGED_SOFT, evt.u.srcstate.id, + evt.u.srcstate.state, msglen, msg, context->EventParam + ); + } + else if((enabledevts&evt.EnumType) == evt.EnumType) context->EventCb(evt.u.user.type, evt.u.user.id, evt.u.user.param, (ALsizei)strlen(evt.u.user.msg), evt.u.user.msg, context->EventParam ); |