xactengine3_7: Implement IXACT3Engine interface.

Based on patch from Ethan Lee.

Signed-off-by: Vijay Kiran Kamuju <infyquest@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Vijay Kiran Kamuju 2020-07-02 09:27:39 +02:00 committed by Alexandre Julliard
parent 255bae6046
commit 124cd264fa
4 changed files with 467 additions and 1 deletions

1
configure vendored
View File

@ -16630,6 +16630,7 @@ then
enable_x3daudio1_5=${enable_x3daudio1_5:-no}
enable_x3daudio1_6=${enable_x3daudio1_6:-no}
enable_x3daudio1_7=${enable_x3daudio1_7:-no}
enable_xactengine3_7=${enable_xactengine3_7:-no}
enable_xapofx1_1=${enable_xapofx1_1:-no}
enable_xapofx1_2=${enable_xapofx1_2:-no}
enable_xapofx1_3=${enable_xapofx1_3:-no}

View File

@ -1958,6 +1958,7 @@ then
enable_x3daudio1_5=${enable_x3daudio1_5:-no}
enable_x3daudio1_6=${enable_x3daudio1_6:-no}
enable_x3daudio1_7=${enable_x3daudio1_7:-no}
enable_xactengine3_7=${enable_xactengine3_7:-no}
enable_xapofx1_1=${enable_xapofx1_1:-no}
enable_xapofx1_2=${enable_xapofx1_2:-no}
enable_xapofx1_3=${enable_xapofx1_3:-no}

View File

@ -1,4 +1,7 @@
MODULE = xactengine3_7.dll
IMPORTS = ole32 uuid
EXTRALIBS = $(FAUDIO_LIBS)
EXTRAINCL = $(FAUDIO_CFLAGS)
C_SRCS = \
xact_dll.c

View File

@ -19,7 +19,12 @@
#include "config.h"
#include <stdarg.h>
#include <FACT.h>
#define NONAMELESSUNION
#define COBJMACROS
#include "initguid.h"
#include "xact3.h"
#include "rpcproxy.h"
#include "xact_classes.h"
@ -29,6 +34,457 @@ WINE_DEFAULT_DEBUG_CHANNEL(xact3);
static HINSTANCE instance;
typedef struct _XACT3EngineImpl {
IXACT3Engine IXACT3Engine_iface;
FACTAudioEngine *fact_engine;
XACT_READFILE_CALLBACK pReadFile;
XACT_GETOVERLAPPEDRESULT_CALLBACK pGetOverlappedResult;
} XACT3EngineImpl;
typedef struct wrap_readfile_struct {
XACT3EngineImpl *engine;
HANDLE file;
} wrap_readfile_struct;
static int32_t FACTCALL wrap_readfile(
void* hFile,
void* lpBuffer,
uint32_t nNumberOfBytesRead,
uint32_t *lpNumberOfBytesRead,
FACTOverlapped *lpOverlapped)
{
wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile;
return wrap->engine->pReadFile(wrap->file, lpBuffer, nNumberOfBytesRead,
lpNumberOfBytesRead, (LPOVERLAPPED)lpOverlapped);
}
static int32_t FACTCALL wrap_getoverlappedresult(
void* hFile,
FACTOverlapped *lpOverlapped,
uint32_t *lpNumberOfBytesTransferred,
int32_t bWait)
{
wrap_readfile_struct *wrap = (wrap_readfile_struct*) hFile;
return wrap->engine->pGetOverlappedResult(wrap->file, (LPOVERLAPPED)lpOverlapped,
lpNumberOfBytesTransferred, bWait);
}
static inline XACT3EngineImpl *impl_from_IXACT3Engine(IXACT3Engine *iface)
{
return CONTAINING_RECORD(iface, XACT3EngineImpl, IXACT3Engine_iface);
}
static HRESULT WINAPI IXACT3EngineImpl_QueryInterface(IXACT3Engine *iface,
REFIID riid, void **ppvObject)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IXACT3Engine)){
*ppvObject = &This->IXACT3Engine_iface;
}
else
*ppvObject = NULL;
if (*ppvObject){
IUnknown_AddRef((IUnknown*)*ppvObject);
return S_OK;
}
FIXME("(%p)->(%s,%p), not found\n", This, debugstr_guid(riid), ppvObject);
return E_NOINTERFACE;
}
static ULONG WINAPI IXACT3EngineImpl_AddRef(IXACT3Engine *iface)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
ULONG ref = FACTAudioEngine_AddRef(This->fact_engine);
TRACE("(%p)->(): Refcount now %u\n", This, ref);
return ref;
}
static ULONG WINAPI IXACT3EngineImpl_Release(IXACT3Engine *iface)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
ULONG ref = FACTAudioEngine_Release(This->fact_engine);
TRACE("(%p)->(): Refcount now %u\n", This, ref);
if (!ref)
HeapFree(GetProcessHeap(), 0, This);
return ref;
}
static HRESULT WINAPI IXACT3EngineImpl_GetRendererCount(IXACT3Engine *iface,
XACTINDEX *pnRendererCount)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%p)\n", This, pnRendererCount);
return FACTAudioEngine_GetRendererCount(This->fact_engine, pnRendererCount);
}
static HRESULT WINAPI IXACT3EngineImpl_GetRendererDetails(IXACT3Engine *iface,
XACTINDEX nRendererIndex, XACT_RENDERER_DETAILS *pRendererDetails)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%d, %p)\n", This, nRendererIndex, pRendererDetails);
return FACTAudioEngine_GetRendererDetails(This->fact_engine,
nRendererIndex, (FACTRendererDetails*) pRendererDetails);
}
static HRESULT WINAPI IXACT3EngineImpl_GetFinalMixFormat(IXACT3Engine *iface,
WAVEFORMATEXTENSIBLE *pFinalMixFormat)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%p)\n", This, pFinalMixFormat);
return FACTAudioEngine_GetFinalMixFormat(This->fact_engine,
(FAudioWaveFormatExtensible*) pFinalMixFormat);
}
static HRESULT WINAPI IXACT3EngineImpl_Initialize(IXACT3Engine *iface,
const XACT_RUNTIME_PARAMETERS *pParams)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FACTRuntimeParameters params;
TRACE("(%p)->(%p)\n", This, pParams);
memcpy(&params, pParams, sizeof(FACTRuntimeParameters));
/* FIXME: pXAudio2 and pMasteringVoice are pointers to
* IXAudio2/IXAudio2MasteringVoice objects. FACT wants pointers to
* FAudio/FAudioMasteringVoice objects. In Wine's XAudio2 implementation, we
* actually have them available, but only if you access their internal data.
* For now we can just force these pointers to NULL, as XACT simply
* generates its own engine and endpoint in that situation. These parameters
* are mostly an optimization for games with multiple XACT3Engines that want
* a single engine running everything.
* -flibit
*/
if (pParams->pXAudio2 != NULL){
FIXME("pXAudio2 parameter not supported! Falling back to NULL\n");
params.pXAudio2 = NULL;
if (pParams->pMasteringVoice != NULL){
FIXME("pXAudio2 parameter not supported! Falling back to NULL\n");
params.pMasteringVoice = NULL;
}
}
/* Force Windows I/O, do NOT use the FACT default! */
This->pReadFile = (XACT_READFILE_CALLBACK)
pParams->fileIOCallbacks.readFileCallback;
This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK)
pParams->fileIOCallbacks.getOverlappedResultCallback;
if (This->pReadFile == NULL)
This->pReadFile = (XACT_READFILE_CALLBACK) ReadFile;
if (This->pGetOverlappedResult == NULL)
This->pGetOverlappedResult = (XACT_GETOVERLAPPEDRESULT_CALLBACK)
GetOverlappedResult;
params.fileIOCallbacks.readFileCallback = wrap_readfile;
params.fileIOCallbacks.getOverlappedResultCallback = wrap_getoverlappedresult;
return FACTAudioEngine_Initialize(This->fact_engine, &params);
}
static HRESULT WINAPI IXACT3EngineImpl_ShutDown(IXACT3Engine *iface)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)\n", This);
return FACTAudioEngine_ShutDown(This->fact_engine);
}
static HRESULT WINAPI IXACT3EngineImpl_DoWork(IXACT3Engine *iface)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)\n", This);
return FACTAudioEngine_DoWork(This->fact_engine);
}
static HRESULT WINAPI IXACT3EngineImpl_CreateSoundBank(IXACT3Engine *iface,
const void* pvBuffer, DWORD dwSize, DWORD dwFlags,
DWORD dwAllocAttributes, IXACT3SoundBank **ppSoundBank)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This, pvBuffer, dwSize, dwFlags,
dwAllocAttributes, ppSoundBank);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_CreateInMemoryWaveBank(IXACT3Engine *iface,
const void* pvBuffer, DWORD dwSize, DWORD dwFlags,
DWORD dwAllocAttributes, IXACT3WaveBank **ppWaveBank)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p)->(%p, %u, 0x%x, 0x%x, %p): stub!\n", This, pvBuffer, dwSize, dwFlags,
dwAllocAttributes, ppWaveBank);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_CreateStreamingWaveBank(IXACT3Engine *iface,
const XACT_STREAMING_PARAMETERS *pParms,
IXACT3WaveBank **ppWaveBank)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p)->(%p, %p): stub!\n", This, pParms, ppWaveBank);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_PrepareInMemoryWave(IXACT3Engine *iface,
DWORD dwFlags, WAVEBANKENTRY entry, DWORD *pdwSeekTable,
BYTE *pbWaveData, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
IXACT3Wave **ppWave)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p): stub!\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_PrepareStreamingWave(IXACT3Engine *iface,
DWORD dwFlags, WAVEBANKENTRY entry,
XACT_STREAMING_PARAMETERS streamingParams, DWORD dwAlignment,
DWORD *pdwSeekTable, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
IXACT3Wave **ppWave)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p): stub!\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_PrepareWave(IXACT3Engine *iface,
DWORD dwFlags, PCSTR szWavePath, WORD wStreamingPacketSize,
DWORD dwAlignment, DWORD dwPlayOffset, XACTLOOPCOUNT nLoopCount,
IXACT3Wave **ppWave)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p): stub!\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_RegisterNotification(IXACT3Engine *iface,
const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p)->(%p): stub!\n", This, pNotificationDesc);
return E_NOTIMPL;
}
static HRESULT WINAPI IXACT3EngineImpl_UnRegisterNotification(IXACT3Engine *iface,
const XACT_NOTIFICATION_DESCRIPTION *pNotificationDesc)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
FIXME("(%p)->(%p): stub!\n", This, pNotificationDesc);
return E_NOTIMPL;
}
static XACTCATEGORY WINAPI IXACT3EngineImpl_GetCategory(IXACT3Engine *iface,
PCSTR szFriendlyName)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%s)\n", This, szFriendlyName);
return FACTAudioEngine_GetCategory(This->fact_engine, szFriendlyName);
}
static HRESULT WINAPI IXACT3EngineImpl_Stop(IXACT3Engine *iface,
XACTCATEGORY nCategory, DWORD dwFlags)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%u, 0x%x)\n", This, nCategory, dwFlags);
return FACTAudioEngine_Stop(This->fact_engine, nCategory, dwFlags);
}
static HRESULT WINAPI IXACT3EngineImpl_SetVolume(IXACT3Engine *iface,
XACTCATEGORY nCategory, XACTVOLUME nVolume)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%u, %f)\n", This, nCategory, nVolume);
return FACTAudioEngine_SetVolume(This->fact_engine, nCategory, nVolume);
}
static HRESULT WINAPI IXACT3EngineImpl_Pause(IXACT3Engine *iface,
XACTCATEGORY nCategory, BOOL fPause)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%u, %u)\n", This, nCategory, fPause);
return FACTAudioEngine_Pause(This->fact_engine, nCategory, fPause);
}
static XACTVARIABLEINDEX WINAPI IXACT3EngineImpl_GetGlobalVariableIndex(
IXACT3Engine *iface, PCSTR szFriendlyName)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%s)\n", This, szFriendlyName);
return FACTAudioEngine_GetGlobalVariableIndex(This->fact_engine,
szFriendlyName);
}
static HRESULT WINAPI IXACT3EngineImpl_SetGlobalVariable(IXACT3Engine *iface,
XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE nValue)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%u, %f)\n", This, nIndex, nValue);
return FACTAudioEngine_SetGlobalVariable(This->fact_engine, nIndex, nValue);
}
static HRESULT WINAPI IXACT3EngineImpl_GetGlobalVariable(IXACT3Engine *iface,
XACTVARIABLEINDEX nIndex, XACTVARIABLEVALUE *nValue)
{
XACT3EngineImpl *This = impl_from_IXACT3Engine(iface);
TRACE("(%p)->(%u, %p)\n", This, nIndex, nValue);
return FACTAudioEngine_GetGlobalVariable(This->fact_engine, nIndex, nValue);
}
static const IXACT3EngineVtbl XACT3Engine_Vtbl =
{
IXACT3EngineImpl_QueryInterface,
IXACT3EngineImpl_AddRef,
IXACT3EngineImpl_Release,
IXACT3EngineImpl_GetRendererCount,
IXACT3EngineImpl_GetRendererDetails,
IXACT3EngineImpl_GetFinalMixFormat,
IXACT3EngineImpl_Initialize,
IXACT3EngineImpl_ShutDown,
IXACT3EngineImpl_DoWork,
IXACT3EngineImpl_CreateSoundBank,
IXACT3EngineImpl_CreateInMemoryWaveBank,
IXACT3EngineImpl_CreateStreamingWaveBank,
IXACT3EngineImpl_PrepareWave,
IXACT3EngineImpl_PrepareInMemoryWave,
IXACT3EngineImpl_PrepareStreamingWave,
IXACT3EngineImpl_RegisterNotification,
IXACT3EngineImpl_UnRegisterNotification,
IXACT3EngineImpl_GetCategory,
IXACT3EngineImpl_Stop,
IXACT3EngineImpl_SetVolume,
IXACT3EngineImpl_Pause,
IXACT3EngineImpl_GetGlobalVariableIndex,
IXACT3EngineImpl_SetGlobalVariable,
IXACT3EngineImpl_GetGlobalVariable
};
void* XACT_Internal_Malloc(size_t size)
{
return CoTaskMemAlloc(size);
}
void XACT_Internal_Free(void* ptr)
{
return CoTaskMemFree(ptr);
}
void* XACT_Internal_Realloc(void* ptr, size_t size)
{
return CoTaskMemRealloc(ptr, size);
}
static HRESULT WINAPI XACT3CF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj)
{
if(IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IClassFactory))
{
*ppobj = iface;
return S_OK;
}
*ppobj = NULL;
WARN("(%p)->(%s, %p): interface not found\n", iface, debugstr_guid(riid), ppobj);
return E_NOINTERFACE;
}
static ULONG WINAPI XACT3CF_AddRef(IClassFactory *iface)
{
return 2;
}
static ULONG WINAPI XACT3CF_Release(IClassFactory *iface)
{
return 1;
}
static HRESULT WINAPI XACT3CF_CreateInstance(IClassFactory *iface, IUnknown *pOuter,
REFIID riid, void **ppobj)
{
HRESULT hr;
XACT3EngineImpl *object;
TRACE("(%p)->(%p,%s,%p)\n", iface, pOuter, debugstr_guid(riid), ppobj);
*ppobj = NULL;
if(pOuter)
return CLASS_E_NOAGGREGATION;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
if(!object)
return E_OUTOFMEMORY;
object->IXACT3Engine_iface.lpVtbl = &XACT3Engine_Vtbl;
FACTCreateEngineWithCustomAllocatorEXT(
0,
&object->fact_engine,
XACT_Internal_Malloc,
XACT_Internal_Free,
XACT_Internal_Realloc
);
hr = IXACT3Engine_QueryInterface(&object->IXACT3Engine_iface, riid, ppobj);
if(FAILED(hr)){
HeapFree(GetProcessHeap(), 0, object);
return hr;
}
return hr;
}
static HRESULT WINAPI XACT3CF_LockServer(IClassFactory *iface, BOOL dolock)
{
TRACE("(%p)->(%d): stub!\n", iface, dolock);
return S_OK;
}
static const IClassFactoryVtbl XACT3CF_Vtbl =
{
XACT3CF_QueryInterface,
XACT3CF_AddRef,
XACT3CF_Release,
XACT3CF_CreateInstance,
XACT3CF_LockServer
};
static IClassFactory XACTFactory = { &XACT3CF_Vtbl };
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, void *pReserved)
{
TRACE("(%p, %d, %p)\n", hinstDLL, reason, pReserved);
@ -50,8 +506,13 @@ HRESULT WINAPI DllCanUnloadNow(void)
HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
{
FIXME("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
if (IsEqualGUID(rclsid, &CLSID_XACTEngine37))
{
TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
return IClassFactory_QueryInterface(&XACTFactory, riid, ppv);
}
FIXME("Unknown class %s\n", debugstr_guid(rclsid));
return CLASS_E_CLASSNOTAVAILABLE;
}