From fff780818d53d96ca3a6988d16752865c0cc8a33 Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Fri, 6 Sep 2013 19:07:15 -0400 Subject: [PATCH] WinRT: made SDL_xaudio2.c compile as C code when building for WinRT XAudio2 2.8's header file, xaudio2.h, doesn't compile in plain C code for WinRT apps, not automatically at least. Initially, this file was adapted to compile as C++, however these changes are now deprecated in favor of some preprocessor based hacks that should get xaudio2.h to compile (while making sure XAudio2 still works). --- .../SDL/SDL_VS2012-WinPhone.vcxproj | 7 +- VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj | 9 +-- src/audio/xaudio2/SDL_xaudio2.c | 65 +++++++++---------- .../xaudio2/SDL_xaudio2_winrthelpers.cpp | 4 +- src/audio/xaudio2/SDL_xaudio2_winrthelpers.h | 14 +++- 5 files changed, 49 insertions(+), 50 deletions(-) diff --git a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj index 59bb72d13a626..474039e856298 100644 --- a/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj +++ b/VisualC-WinPhone/SDL/SDL_VS2012-WinPhone.vcxproj @@ -261,12 +261,7 @@ - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - + true true diff --git a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj index 2fe031891a3b6..66bdee538f5c3 100644 --- a/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj +++ b/VisualC-WinRT/SDL/SDL_VS2012-WinRT.vcxproj @@ -37,14 +37,7 @@ - - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - CompileAsCpp - + true true diff --git a/src/audio/xaudio2/SDL_xaudio2.c b/src/audio/xaudio2/SDL_xaudio2.c index c540be37f657f..0b2eea3aee453 100644 --- a/src/audio/xaudio2/SDL_xaudio2.c +++ b/src/audio/xaudio2/SDL_xaudio2.c @@ -21,37 +21,7 @@ /* WinRT NOTICE: - A number of changes were warranted to SDL's XAudio2 backend in order to - get it compiling for WinRT. - - When compiling for WinRT, XAudio2.h requires that it be compiled in a C++ - file, and not a straight C file. Trying to compile it as C leads to lots - of errors, at least with MSVC 2012 and Windows SDK 8.0, as of Nov 22, 2012. - To address this specific issue, a few changes were made to SDL_xaudio2.c: - - 1. SDL_xaudio2.c is compiled as a C++ file in WinRT builds. Exported - symbols, namely XAUDIO2_bootstrap, uses 'extern "C"' to make sure the - rest of SDL can access it. Non-WinRT builds continue to compile - SDL_xaudio2.c as a C file. - 2. A macro redefines variables named 'this' to '_this', to prevent compiler - errors (C2355 in Visual C++) related to 'this' being a reserverd keyword. - This hack may need to be altered in the future, particularly if C++'s - 'this' keyword needs to be used (within SDL_xaudio2.c). At the time - WinRT support was initially added to SDL's XAudio2 backend, this - capability was not needed. - 3. The C-style macros to invoke XAudio2's COM-based methods were - rewritten to be C++-friendly. These are provided in the file, - SDL_xaudio2_winrthelpers.h. - 4. IXAudio2::CreateSourceVoice, when used in C++, requires its callbacks to - be specified via a C++ class. SDL's XAudio2 backend was written with - C-style callbacks. A class to bridge these two interfaces, - SDL_XAudio2VoiceCallback, was written to make XAudio2 happy. Its methods - just call SDL's existing, C-style callbacks. - 5. Multiple checks for the __cplusplus macro were made, in appropriate - places. - - - A few additional changes to SDL's XAudio2 backend were warranted by API + A few changes to SDL's XAudio2 backend were warranted by API changes to Windows. Many, but not all of these are documented by Microsoft at: http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx @@ -108,14 +78,29 @@ extern "C" { #ifdef SDL_XAUDIO2_HAS_SDK +/* Check to see if we're compiling for XAudio 2.8, or higher. */ +#ifdef WINVER +#if WINVER >= 0x0602 /* Windows 8 SDK or higher? */ +#define SDL_XAUDIO2_2_8 1 +#endif +#endif + +/* The XAudio header file, when #include'd on WinRT, will only compile in C++ + files, but not C. A few preprocessor-based hacks are defined below in order + to get xaudio2.h to compile in the C/non-C++ file, SDL_xaudio2.c. + */ +#ifdef __WINRT__ +#define uuid(x) +#define DX_BUILD +#endif + #define INITGUID 1 #include /* Hidden "this" pointer for the audio functions */ #define _THIS SDL_AudioDevice *this -#ifdef __cplusplus -#define this _this +#ifdef __WINRT__ #include "SDL_xaudio2_winrthelpers.h" #endif @@ -273,10 +258,18 @@ XAUDIO2_WaitDone(_THIS) XAUDIO2_VOICE_STATE state; SDL_assert(!this->enabled); /* flag that stops playing. */ IXAudio2SourceVoice_Discontinuity(source); +#if SDL_XAUDIO2_2_8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else IXAudio2SourceVoice_GetState(source, &state); +#endif while (state.BuffersQueued > 0) { SDL_SemWait(this->hidden->semaphore); +#if SDL_XAUDIO2_2_8 + IXAudio2SourceVoice_GetState(source, &state, 0); +#else IXAudio2SourceVoice_GetState(source, &state); +#endif } } @@ -447,9 +440,15 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) stereo output to appropriate surround sound configurations instead of clamping to 2 channels, even though we'll configure the Source Voice for whatever number of channels you supply. */ +#if SDL_XAUDIO2_2_8 + result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, + XAUDIO2_DEFAULT_CHANNELS, + this->spec.freq, 0, devId, NULL, AudioCategory_GameEffects); +#else result = IXAudio2_CreateMasteringVoice(ixa2, &this->hidden->mastering, XAUDIO2_DEFAULT_CHANNELS, this->spec.freq, 0, devId, NULL); +#endif if (result != S_OK) { XAUDIO2_CloseDevice(this); return SDL_SetError("XAudio2: Couldn't create mastering voice"); diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp index aa88fd6c12d97..9c0fe0ed76562 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.cpp @@ -8,7 +8,7 @@ using Windows::Devices::Enumeration::DeviceInformation; using Windows::Devices::Enumeration::DeviceInformationCollection; #endif -HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) +extern "C" HRESULT __cdecl IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) { #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // There doesn't seem to be any audio device enumeration on Windows Phone. @@ -29,7 +29,7 @@ HRESULT IXAudio2_GetDeviceCount(IXAudio2 * ixa2, UINT32 * devcount) #endif } -HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details) +extern "C" HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details) { #if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // Windows Phone doesn't seem to have the same device enumeration APIs that diff --git a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h index 7c3ba81b1a2f5..ee5afcd45851d 100644 --- a/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h +++ b/src/audio/xaudio2/SDL_xaudio2_winrthelpers.h @@ -14,14 +14,24 @@ typedef struct XAUDIO2_DEVICE_DETAILS */ } XAUDIO2_DEVICE_DETAILS; + +#ifdef __cplusplus +extern "C" { +#endif + HRESULT IXAudio2_GetDeviceCount(IXAudio2 * unused, UINT32 * devcount); HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVICE_DETAILS * details); +#ifdef __cplusplus +} +#endif + // // C-style macros to call XAudio2's methods in C++: // - +#ifdef __cplusplus +/* #define IXAudio2_CreateMasteringVoice(A, B, C, D, E, F, G) (A)->CreateMasteringVoice((B), (C), (D), (E), (F), (G)) #define IXAudio2_CreateSourceVoice(A, B, C, D, E, F, G, H) (A)->CreateSourceVoice((B), (C), (D), (E), (F), (G), (H)) #define IXAudio2_QueryInterface(A, B, C) (A)->QueryInterface((B), (C)) @@ -38,3 +48,5 @@ HRESULT IXAudio2_GetDeviceDetails(IXAudio2 * unused, UINT32 index, XAUDIO2_DEVIC #define IXAudio2SourceVoice_Start(A, B, C) (A)->Start((B), (C)) #define IXAudio2SourceVoice_Stop(A, B, C) (A)->Stop((B), (C)) #define IXAudio2SourceVoice_SubmitSourceBuffer(A, B, C) (A)->SubmitSourceBuffer((B), (C)) +*/ +#endif // ifdef __cplusplus