diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 018829d1..eb4e01c2 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "599ecd97a8fded8c00aa261535880a4d8b5d2693" + echo "c09a5da157585d171ad896e9862db00d505e4363" } # Show version information @@ -269,6 +269,7 @@ patch_enable_all () enable_xactengine_initial="$1" enable_xactengine3_7_Notification="$1" enable_xactengine3_7_PrepareWave="$1" + enable_xactengine3_7_callbacks="$1" } # Enable or disable a specific patchset @@ -836,6 +837,9 @@ patch_enable () xactengine3_7-PrepareWave) enable_xactengine3_7_PrepareWave="$2" ;; + xactengine3_7-callbacks) + enable_xactengine3_7_callbacks="$2" + ;; *) return 1 ;; @@ -1183,6 +1187,13 @@ patch_apply() } +if test "$enable_xactengine3_7_callbacks" -eq 1; then + if test "$enable_xactengine3_7_Notification" -gt 1; then + abort "Patchset xactengine3_7-Notification disabled, but xactengine3_7-callbacks depends on that." + fi + enable_xactengine3_7_Notification=1 +fi + if test "$enable_winex11_WM_WINDOWPOSCHANGING" -eq 1; then if test "$enable_winex11__NET_ACTIVE_WINDOW" -gt 1; then abort "Patchset winex11-_NET_ACTIVE_WINDOW disabled, but winex11-WM_WINDOWPOSCHANGING depends on that." @@ -4014,6 +4025,23 @@ if test "$enable_xactengine3_7_PrepareWave" -eq 1; then patch_apply xactengine3_7-PrepareWave/0003-xactengine3_7-Implement-IXACT3Engine-PrepareInMemory.patch fi +# Patchset xactengine3_7-callbacks +# | +# | This patchset has the following (direct or indirect) dependencies: +# | * xactengine3_7-Notification +# | +# | This patchset fixes the following Wine bugs: +# | * [#49678] - xactengine: Implement callback notifications. +# | +# | Modified files: +# | * dlls/xactengine3_7/xact_dll.c, libs/faudio/include/FACT.h, libs/faudio/src/FACT.c, libs/faudio/src/FACT_internal.h +# | +if test "$enable_xactengine3_7_callbacks" -eq 1; then + patch_apply xactengine3_7-callbacks/0001-Add-support-for-private-contexts.patch + patch_apply xactengine3_7-callbacks/0002-xactengine3_7-notifications.patch + patch_apply xactengine3_7-callbacks/0003-Send-NOTIFY_CUESTOP-when-Stop-is-called.patch +fi + if test "$enable_autoconf" -eq 1; then if ! update_configure; then abort "'autoreconf -f' failed." diff --git a/patches/xactengine3_7-callbacks/0001-Add-support-for-private-contexts.patch b/patches/xactengine3_7-callbacks/0001-Add-support-for-private-contexts.patch new file mode 100644 index 00000000..06d4b73a --- /dev/null +++ b/patches/xactengine3_7-callbacks/0001-Add-support-for-private-contexts.patch @@ -0,0 +1,159 @@ +From 71be762c3d84b84c3d9249f80467797ce3519bb6 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 12 Sep 2020 16:31:09 +1000 +Subject: Add support for private contexts + + +diff --git a/libs/faudio/include/FACT.h b/libs/faudio/include/FACT.h +index 579b7168812..084b1e55cfe 100644 +--- a/libs/faudio/include/FACT.h ++++ b/libs/faudio/include/FACT.h +@@ -805,6 +805,18 @@ FACTAPI uint32_t FACTCue_SetOutputVoiceMatrix( + const float *pLevelMatrix /* SourceChannels * DestinationChannels */ + ); + ++FACTAPI void FACTWave_SetPrivateContext(FACTWave *pWave, void *context); ++FACTAPI void* FACTWave_GetPrivateContext(FACTWave *pWave); ++ ++FACTAPI void FACTWaveBank_SetPrivateContext(FACTWaveBank *pWaveBank, void *context); ++FACTAPI void* FACTWaveBank_GetPrivateContext(FACTWaveBank *pWaveBank); ++ ++FACTAPI void FACTSoundBank_SetPrivateContext(FACTSoundBank *pSoundBank, void *context); ++FACTAPI void* FACTSoundBank_GetPrivateContext(FACTSoundBank *pSoundBank); ++ ++FACTAPI void FACTCue_SetPrivateContext(FACTCue *pCue, void *context); ++FACTAPI void* FACTCue_GetPrivateContext(FACTCue *pCue); ++ + #ifdef __cplusplus + } + #endif /* __cplusplus */ +diff --git a/libs/faudio/src/FACT.c b/libs/faudio/src/FACT.c +index 5eca83b389f..e2e7b10058d 100644 +--- a/libs/faudio/src/FACT.c ++++ b/libs/faudio/src/FACT.c +@@ -1177,6 +1177,9 @@ uint32_t FACTSoundBank_Prepare( + (*ppCue)->notifyOnDestroy = 0; + (*ppCue)->usercontext = NULL; + ++ /* User data */ ++ (*ppCue)->privatecontext = NULL; ++ + /* Sound data */ + (*ppCue)->data = &pSoundBank->cues[nCueIndex]; + if ((*ppCue)->data->flags & 0x04) +@@ -1798,6 +1801,9 @@ uint32_t FACTWaveBank_Prepare( + (*ppWave)->pitch = 0; + (*ppWave)->loopCount = nLoopCount; + ++ /* User data */ ++ (*ppWave)->privatecontext = NULL; ++ + /* TODO: Convert dwPlayOffset to a byte offset */ + FAudio_assert(dwPlayOffset == 0); + #if 0 +@@ -2175,11 +2181,14 @@ uint32_t FACTWave_Stop(FACTWave *pWave, uint32_t dwFlags) + { + FACTNotification note; + note.type = FACTNOTIFICATIONTYPE_WAVESTOP; ++ note.wave.cueIndex = pWave->parentCue->index; ++ note.wave.pCue = pWave->parentCue; ++ note.wave.pSoundBank = pWave->parentCue->parentBank; + note.wave.pWave = pWave; +- if (pWave->parentBank->parentEngine->notifications & NOTIFY_WAVESTOP) +- { +- note.pvContext = pWave->parentBank->parentEngine->wave_context; +- } ++ note.wave.pWaveBank = pWave->parentBank; ++ ++ note.pvContext = pWave->parentBank->parentEngine->wave_context; ++ + pWave->parentBank->parentEngine->notificationCallback(¬e); + } + +@@ -3018,4 +3027,42 @@ uint32_t FACTCue_SetOutputVoiceMatrix( + return 0; + } + ++void FACTWave_SetPrivateContext(FACTWave *pWave, void *context) ++{ ++ pWave->privatecontext = context; ++} ++void* FACTWave_GetPrivateContext(FACTWave *pWave) ++{ ++ return pWave->privatecontext; ++} ++ ++FACTAPI void FACTWaveBank_SetPrivateContext(FACTWaveBank *pWaveBank, void *context) ++{ ++ pWaveBank->privatecontext = context; ++} ++ ++FACTAPI void* FACTWaveBank_GetPrivateContext(FACTWaveBank *pWaveBank) ++{ ++ return pWaveBank->privatecontext; ++} ++ ++FACTAPI void FACTSoundBank_SetPrivateContext(FACTSoundBank *pSoundBank, void *context) ++{ ++ pSoundBank->privatecontext = context; ++} ++FACTAPI void* FACTSoundBank_GetPrivateContext(FACTSoundBank *pSoundBank) ++{ ++ return pSoundBank->privatecontext; ++} ++ ++FACTAPI void FACTCue_SetPrivateContext(FACTCue *pCue, void *context) ++{ ++ pCue->privatecontext = context; ++} ++ ++FACTAPI void* FACTCue_GetPrivateContext(FACTCue *pCue) ++{ ++ return pCue->privatecontext; ++} ++ + /* vim: set noexpandtab shiftwidth=8 tabstop=8: */ +diff --git a/libs/faudio/src/FACT_internal.h b/libs/faudio/src/FACT_internal.h +index 6bf522e64c4..52d07e5f9d3 100644 +--- a/libs/faudio/src/FACT_internal.h ++++ b/libs/faudio/src/FACT_internal.h +@@ -473,6 +473,9 @@ struct FACTSoundBank + uint32_t *variationCodes; + FACTTransitionTable *transitions; + uint32_t *transitionCodes; ++ ++ /* Application data */ ++ void *privatecontext; + }; + + struct FACTWaveBank +@@ -498,6 +501,9 @@ struct FACTWaveBank + uint8_t *packetBuffer; + uint32_t packetBufferLen; + void* io; ++ ++ /* Application data */ ++ void *privatecontext; + }; + + struct FACTWave +@@ -524,6 +530,9 @@ struct FACTWave + uint16_t srcChannels; + FAudioSourceVoice *voice; + FACTWaveCallback callback; ++ ++ /* Application data */ ++ void *privatecontext; + }; + + struct FACTCue +@@ -569,6 +578,9 @@ struct FACTCue + /* Timer */ + uint32_t start; + uint32_t elapsed; ++ ++ /* Application data */ ++ void *privatecontext; + }; + + /* Internal functions */ diff --git a/patches/xactengine3_7-callbacks/0002-xactengine3_7-notifications.patch b/patches/xactengine3_7-callbacks/0002-xactengine3_7-notifications.patch new file mode 100644 index 00000000..90d2fbec --- /dev/null +++ b/patches/xactengine3_7-callbacks/0002-xactengine3_7-notifications.patch @@ -0,0 +1,155 @@ +From a5439a8a6d3706ee6c3ea13cd76deee1484083d4 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Sat, 12 Sep 2020 14:10:18 +1000 +Subject: xactengine3_7: notifications + + +diff --git a/dlls/xactengine3_7/xact_dll.c b/dlls/xactengine3_7/xact_dll.c +index 326f79f0ecd..62084f9234f 100644 +--- a/dlls/xactengine3_7/xact_dll.c ++++ b/dlls/xactengine3_7/xact_dll.c +@@ -329,6 +329,8 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Prepare(IXACT3SoundBank *iface, + cue->fact_cue = fcue; + *ppCue = &cue->IXACT3Cue_iface; + ++ FACTCue_SetPrivateContext(fcue, &cue->IXACT3Cue_iface); ++ + TRACE("Created Cue: %p\n", cue); + + return S_OK; +@@ -370,6 +372,8 @@ static HRESULT WINAPI IXACT3SoundBankImpl_Play(IXACT3SoundBank *iface, + cue->IXACT3Cue_iface.lpVtbl = &XACT3Cue_Vtbl; + cue->fact_cue = fcue; + *ppCue = &cue->IXACT3Cue_iface; ++ ++ FACTCue_SetPrivateContext(fcue, &cue->IXACT3Cue_iface); + } + + return hr; +@@ -627,6 +631,8 @@ static HRESULT WINAPI IXACT3WaveBankImpl_Prepare(IXACT3WaveBank *iface, + wave->fact_wave = fwave; + *ppWave = &wave->IXACT3Wave_iface; + ++ FACTWave_SetPrivateContext(fwave, &wave->IXACT3Wave_iface); ++ + TRACE("Created Wave: %p\n", wave); + + return S_OK; +@@ -668,6 +674,8 @@ static HRESULT WINAPI IXACT3WaveBankImpl_Play(IXACT3WaveBank *iface, + wave->IXACT3Wave_iface.lpVtbl = &XACT3Wave_Vtbl; + wave->fact_wave = fwave; + *ppWave = &wave->IXACT3Wave_iface; ++ ++ FACTWave_SetPrivateContext(fwave, &wave->IXACT3Wave_iface); + } + + return hr; +@@ -837,6 +845,7 @@ static HRESULT WINAPI IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine *iface, + static void FACTCALL fact_notification_cb(const FACTNotification *notification) + { + XACT3EngineImpl *engine = (XACT3EngineImpl *)notification->pvContext; ++ XACT_NOTIFICATION note; + + /* Older versions of FAudio don't pass through the context */ + if (!engine) +@@ -845,7 +854,45 @@ static void FACTCALL fact_notification_cb(const FACTNotification *notification) + return; + } + +- FIXME("Unsupported callback type %d\n", notification->type); ++ note.type = notification->type; ++ note.pvContext = engine->contexts[notification->type - 1]; ++ ++ switch (notification->type) ++ { ++ case XACTNOTIFICATIONTYPE_SOUNDBANKDESTROYED: ++ note.soundBank.pSoundBank = FACTSoundBank_GetPrivateContext(notification->wave.pSoundBank); ++ break; ++#if XACT3_VER >= 0x0205 ++ case XACTNOTIFICATIONTYPE_WAVEDESTROYED: ++ case XACTNOTIFICATIONTYPE_WAVELOOPED: ++ case XACTNOTIFICATIONTYPE_WAVEPLAY: ++ case XACTNOTIFICATIONTYPE_WAVEPREPARED: ++#endif ++ case XACTNOTIFICATIONTYPE_WAVESTOP: ++ note.wave.cueIndex = notification->wave.cueIndex; ++ note.wave.pCue = FACTCue_GetPrivateContext(notification->wave.pCue); ++ note.wave.pSoundBank = FACTSoundBank_GetPrivateContext(notification->wave.pSoundBank); ++#if XACT3_VER >= 0x0205 ++ note.wave.pWave = FACTWave_GetPrivateContext(notification->wave.pWave); ++#endif ++ note.wave.pWaveBank = FACTWaveBank_GetPrivateContext(notification->wave.pWaveBank); ++ break; ++ ++ case XACTNOTIFICATIONTYPE_CUEPLAY: ++ case XACTNOTIFICATIONTYPE_CUEPREPARED: ++ case XACTNOTIFICATIONTYPE_CUESTOP: ++ note.cue.pCue = FACTCue_GetPrivateContext(notification->cue.pCue); ++ /* Fall through */ ++ case XACTNOTIFICATIONTYPE_CUEDESTROYED: ++ note.cue.cueIndex = notification->cue.cueIndex; ++ note.cue.pSoundBank = FACTSoundBank_GetPrivateContext(notification->cue.pSoundBank); ++ break; ++ default: ++ FIXME("Unsupported callback type %d\n", notification->type); ++ return; ++ } ++ ++ engine->notification_callback(¬e); + } + + static HRESULT WINAPI IXACT3EngineImpl_Initialize(IXACT3Engine *iface, +@@ -961,6 +1008,8 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface, + sb->fact_soundbank = fsb; + *ppSoundBank = &sb->IXACT3SoundBank_iface; + ++ FACTSoundBank_SetPrivateContext(fsb, &sb->IXACT3SoundBank_iface); ++ + TRACE("Created SoundBank: %p\n", sb); + + return S_OK; +@@ -1037,6 +1086,8 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *ifac + + send_wavebank_notification(This, &wb->IXACT3WaveBank_iface); + ++ FACTWaveBank_SetPrivateContext(fwb, &wb->IXACT3WaveBank_iface); ++ + TRACE("Created in-memory WaveBank: %p\n", wb); + + return S_OK; +@@ -1087,6 +1138,8 @@ static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *ifa + + send_wavebank_notification(This, &wb->IXACT3WaveBank_iface); + ++ FACTWaveBank_SetPrivateContext(fwb, &wb->IXACT3WaveBank_iface); ++ + TRACE("Created streaming WaveBank: %p\n", wb); + + return S_OK; +@@ -1135,6 +1188,8 @@ static HRESULT WINAPI IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine *iface, + wave->fact_wave = fwave; + *ppWave = &wave->IXACT3Wave_iface; + ++ FACTWave_SetPrivateContext(fwave, &wave->IXACT3Wave_iface); ++ + TRACE("Created Wave: %p\n", wave); + + return S_OK; +@@ -1197,6 +1252,8 @@ static HRESULT WINAPI IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine *iface, + wave->fact_wave = fwave; + *ppWave = &wave->IXACT3Wave_iface; + ++ FACTWave_SetPrivateContext(fwave, &wave->IXACT3Wave_iface); ++ + TRACE("Created Wave: %p\n", wave); + + return S_OK; +@@ -1234,6 +1291,8 @@ static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface, + wave->fact_wave = fwave; + *ppWave = &wave->IXACT3Wave_iface; + ++ FACTWave_SetPrivateContext(fwave, &wave->IXACT3Wave_iface); ++ + TRACE("Created Wave: %p\n", wave); + + return S_OK; diff --git a/patches/xactengine3_7-callbacks/0003-Send-NOTIFY_CUESTOP-when-Stop-is-called.patch b/patches/xactengine3_7-callbacks/0003-Send-NOTIFY_CUESTOP-when-Stop-is-called.patch new file mode 100644 index 00000000..c474b8b8 --- /dev/null +++ b/patches/xactengine3_7-callbacks/0003-Send-NOTIFY_CUESTOP-when-Stop-is-called.patch @@ -0,0 +1,25 @@ +From a8f9265b71b423e2d280645a225465750a1d4594 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Mon, 25 Oct 2021 09:48:50 +1100 +Subject: [PATCH 3/3] Send NOTIFY_CUESTOP when Stop is called + +--- + libs/faudio/src/FACT.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libs/faudio/src/FACT.c b/libs/faudio/src/FACT.c +index cea960d6710..d9c5d7c2766 100644 +--- a/libs/faudio/src/FACT.c ++++ b/libs/faudio/src/FACT.c +@@ -2685,6 +2685,8 @@ uint32_t FACTCue_Stop(FACTCue *pCue, uint32_t dwFlags) + } + } + ++ FACT_INTERNAL_SendCueNotification(pCue, NOTIFY_CUESTOP, FACTNOTIFICATIONTYPE_CUESTOP); ++ + FAudio_PlatformUnlockMutex(pCue->parentBank->parentEngine->apiLock); + return 0; + } +-- +2.33.0 + diff --git a/patches/xactengine3_7-callbacks/definition b/patches/xactengine3_7-callbacks/definition new file mode 100644 index 00000000..b44efb6d --- /dev/null +++ b/patches/xactengine3_7-callbacks/definition @@ -0,0 +1,2 @@ +Fixes: [49678] - xactengine: Implement callback notifications. +Depends: xactengine3_7-Notification