Skip to content

Commit

Permalink
Avoid assuming MinGW headers don't inherit the same as MSVC
Browse files Browse the repository at this point in the history
  • Loading branch information
kcat committed Apr 18, 2023
1 parent ea903ea commit 2133c6d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 27 deletions.
13 changes: 8 additions & 5 deletions src/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,15 +182,18 @@ Buffer::Buffer(DSound8OAL &parent, bool is8, IDirectSoundBuffer *original) noexc

if(original)
{
#ifdef __MINGW32__
/* MinGW headers do not have IDirectSoundBuffer8 inherit from
* IDirectSoundBuffer, which MSVC apparently does. Reverse the cast
* done for Buffer -> IDirectSoundBuffer.
*/
Buffer *orig{static_cast<Buffer*>(ds::bit_cast<IDirectSoundBuffer8*>(original))};
#else
Buffer *orig{static_cast<Buffer*>(original)};
#endif
auto upcast = [](auto *orig)
{
if constexpr(std::is_base_of_v<std::remove_pointer_t<decltype(orig)>,Buffer>)
return static_cast<Buffer*>(orig);
else
return static_cast<Buffer*>(ds::bit_cast<IDirectSoundBuffer8*>(orig));
};
Buffer *orig{upcast(original)};
mBuffer = orig->mBuffer;

/* According to MSDN, volume isn't copied. */
Expand Down
25 changes: 14 additions & 11 deletions src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <bitset>
#include <memory>
#include <mutex>
#include <type_traits>
#include <utility>

#include <dsound.h>
Expand Down Expand Up @@ -229,17 +230,19 @@ class Buffer final : IDirectSoundBuffer8 {
DWORD getCurrentMode() const noexcept { return mImmediate.dwMode; }

template<typename T>
T as() noexcept { return static_cast<T>(this); }
T as() noexcept
{
/* MinGW headers do not have IDirectSoundBuffer8 inherit from
* IDirectSoundBuffer, which MSVC apparently does. IDirectSoundBuffer
* is a strict subset of IDirectSoundBuffer8, so the interface is ABI
* compatible.
*/
if constexpr(std::is_same_v<T,IDirectSoundBuffer*>
&& !std::is_base_of_v<IDirectSoundBuffer,Buffer>)
return ds::bit_cast<T>(static_cast<IDirectSoundBuffer8*>(this));
else
return static_cast<T>(this);
}
};

#ifdef __MINGW32__
/* MinGW headers do not have IDirectSoundBuffer8 inherit from
* IDirectSoundBuffer, which MSVC apparently does. IDirectSoundBuffer is a
* subset of IDirectSoundBuffer8, so it should be ABI-compatible.
*/
template<>
inline IDirectSoundBuffer *Buffer::as() noexcept
{ return ds::bit_cast<IDirectSoundBuffer*>(static_cast<IDirectSoundBuffer8*>(this)); }
#endif

#endif // BUFFER_H
24 changes: 13 additions & 11 deletions src/dsoundoal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <bitset>
#include <memory>
#include <mutex>
#include <type_traits>
#include <vector>

#include <dsound.h>
Expand Down Expand Up @@ -215,20 +216,21 @@ class DSound8OAL final : IDirectSound8 {
std::vector<Buffer*> &get3dBuffers() noexcept { return m3dBuffers; }

template<typename T> [[nodiscard]]
T as() noexcept { return static_cast<T>(this); }
T as() noexcept
{
/* MinGW headers do not have IDirectSound8 inherit from IDirectSound,
* which MSVC apparently does. IDirectSound is a strict subset of
* IDirectSound8, so the interface is ABI compatible.
*/
if constexpr(std::is_same_v<T,IDirectSound*>
&& !std::is_base_of_v<IDirectSound,DSound8OAL>)
return ds::bit_cast<T>(static_cast<IDirectSound8*>(this));
else
return static_cast<T>(this);
}

[[nodiscard]]
static ComPtr<DSound8OAL> Create(bool is8);
};

#ifdef __MINGW32__
/* MinGW headers do not have IDirectSound8 inherit from IDirectSound, which
* MSVC apparently does. IDirectSound is a subset of IDirectSoundBuffer, so it
* should be ABI-compatible.
*/
template<>
inline IDirectSound *DSound8OAL::as() noexcept
{ return ds::bit_cast<IDirectSound*>(static_cast<IDirectSound8*>(this)); }
#endif

#endif // DSOUNDOAL_H

0 comments on commit 2133c6d

Please sign in to comment.