From 4be16f9e11e9212f67456701f8c0b896e3454e71 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 4 Sep 2024 20:02:49 -0700 Subject: [PATCH] Add a Buffer::SetFX stub --- src/buffer.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- src/guidprinter.h | 26 ++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/buffer.cpp b/src/buffer.cpp index fc13680..43e7539 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -1245,9 +1245,48 @@ HRESULT STDMETHODCALLTYPE Buffer::Restore() noexcept #define PREFIX CLASS_PREFIX "SetFX" HRESULT STDMETHODCALLTYPE Buffer::SetFX(DWORD effectsCount, DSEFFECTDESC *dsFXDesc, DWORD *resultCodes) noexcept { - FIXME(PREFIX "(%p)->(%lu, %p, %p)\n", voidp{this}, effectsCount, voidp{dsFXDesc}, + TRACE(PREFIX "(%p)->(%lu, %p, %p)\n", voidp{this}, effectsCount, voidp{dsFXDesc}, voidp{resultCodes}); - return E_NOTIMPL; + + if(!(mBuffer->mFlags&DSBCAPS_CTRLFX)) + return DSERR_CONTROLUNAVAIL; + + if(effectsCount == 0) + { + /* No effects, we can do that. */ + if(dsFXDesc || resultCodes) + { + WARN("Non-null pointers for no effects (%p, %p)\n", voidp{dsFXDesc}, + voidp{resultCodes}); + return E_INVALIDARG; + } + return DS_OK; + } + + if(!dsFXDesc) + { + WARN("Missing FX descriptions\n"); + return E_INVALIDARG; + } + const auto fxdescs = std::span{dsFXDesc, effectsCount}; + const auto rescodes = std::span{resultCodes, resultCodes ? effectsCount : 0ul}; + + /* We don't handle DS8 FX. Still not sure how exactly this is supposed to + * work, surely it doesn't instantiate a unique effect processor for each + * buffer? But you may sometimes want multiple instances of the same effect + * type... + * + * Not that many apps used this API, so it's not likely a big loss. + */ + std::fill(rescodes.begin(), rescodes.end(), DSFXR_FAILED); + + std::for_each(fxdescs.begin(), fxdescs.end(), [](const DSEFFECTDESC &desc) + { + DEBUG("Unsupported effect: 0x%lx, %s\n", desc.dwFlags, + DsfxPrinter{desc.guidDSFXClass}.c_str()); + }); + + return DSERR_FXUNAVAILABLE; } #undef PREFIX diff --git a/src/guidprinter.h b/src/guidprinter.h index 5b31649..edb8545 100644 --- a/src/guidprinter.h +++ b/src/guidprinter.h @@ -23,6 +23,7 @@ struct PropidTag { }; struct DevidTag { }; struct Ds3dalgTag { }; struct FmtidTag { }; +struct DsfxTag { }; class GuidPrinter { std::array mMsg{}; @@ -83,6 +84,23 @@ class GuidPrinter { store(guid); } + void store_dsfxid(const GUID &guid) + { + if(false) { } + CHECKID(GUID_DSFX_STANDARD_CHORUS) + CHECKID(GUID_DSFX_STANDARD_COMPRESSOR) + CHECKID(GUID_DSFX_STANDARD_DISTORTION) + CHECKID(GUID_DSFX_STANDARD_ECHO) + CHECKID(GUID_DSFX_STANDARD_FLANGER) + CHECKID(GUID_DSFX_STANDARD_GARGLE) + CHECKID(GUID_DSFX_STANDARD_I3DL2REVERB) + CHECKID(GUID_DSFX_STANDARD_PARAMEQ) + CHECKID(GUID_DSFX_WAVES_REVERB) + if(mIdStr) return; + + store(guid); + } + void store_ds3dalg(const GUID &guid) { if(false) { } @@ -141,6 +159,7 @@ class GuidPrinter { GuidPrinter(PropidTag, const GUID &guid) { store_propid(guid); } GuidPrinter(Ds3dalgTag, const GUID &guid) { store_ds3dalg(guid); } GuidPrinter(FmtidTag, const GUID &guid) { store_fmtid(guid); } + GuidPrinter(DsfxTag, const GUID &guid) { store_dsfxid(guid); } GuidPrinter(const GUID *guid) { if(!guid) mIdStr = "{null}"; else store(*guid); } GuidPrinter(ClsidTag, const GUID *guid) { if(!guid) mIdStr = "{null}"; else store_clsid(*guid); } @@ -148,6 +167,7 @@ class GuidPrinter { GuidPrinter(PropidTag, const GUID *guid) { if(!guid) mIdStr = "{null}"; else store_propid(*guid); } GuidPrinter(Ds3dalgTag, const GUID *guid) { if(!guid) mIdStr = "{null}"; else store_ds3dalg(*guid); } GuidPrinter(FmtidTag, const GUID *guid) { if(!guid) mIdStr = "{null}"; else store_fmtid(*guid); } + GuidPrinter(DsfxTag, const GUID *guid) { if(!guid) mIdStr = "{null}"; else store_dsfxid(*guid); } [[nodiscard]] const char *c_str() const { return mIdStr; } @@ -189,4 +209,10 @@ class FmtidPrinter : public GuidPrinter { FmtidPrinter(T&& guid) : GuidPrinter{FmtidTag{}, std::forward(guid)} { } }; +class DsfxPrinter : public GuidPrinter { +public: + template,DsfxPrinter>,bool> = true> + DsfxPrinter(T&& guid) : GuidPrinter{DsfxTag{}, std::forward(guid)} { } +}; + #endif // GUIDPRINTER_H