Module: wine Branch: master Commit: 1ac80a99dd8ffa92e1822a71168030d2cd0bf802 URL: https://gitlab.winehq.org/wine/wine/-/commit/1ac80a99dd8ffa92e1822a71168030d...
Author: Giovanni Mascellani gmascellani@codeweavers.com Date: Thu Jul 7 15:15:05 2022 +0200
xactengine3_7/tests: Test notifications when loading a wave bank.
"The King of Fighters '98 Ultimate Match Final Edition" depends on this behavior. At least, the build I have is; it seems other builds are not.
Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com
---
dlls/xactengine3_7/tests/xact3.c | 171 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+)
diff --git a/dlls/xactengine3_7/tests/xact3.c b/dlls/xactengine3_7/tests/xact3.c index 623a1c97db8..1b27eb9aa19 100644 --- a/dlls/xactengine3_7/tests/xact3.c +++ b/dlls/xactengine3_7/tests/xact3.c @@ -28,6 +28,7 @@
#include "initguid.h" #include "xact3.h" +#include "xact3wb.h"
DEFINE_GUID(IID_IXACT3Engine30, 0x9e33f661, 0x2d07, 0x43ec, 0x97, 0x04, 0xbb, 0xcb, 0x71, 0xa5, 0x49, 0x72); DEFINE_GUID(IID_IXACT3Engine31, 0xe72c1b9a, 0xd717, 0x41c0, 0x81, 0xa6, 0x50, 0xeb, 0x56, 0xe8, 0x06, 0x49); @@ -90,11 +91,181 @@ static void test_interfaces(void) } }
+static WCHAR *gen_xwb_file(void) +{ + static const WAVEBANKENTRY entry = + { + .Format = + { + .wFormatTag = WAVEBANKMINIFORMAT_TAG_ADPCM, + .nChannels = 2, + .nSamplesPerSec = 22051, + .wBlockAlign = 48, + }, + }; + static const WAVEBANKDATA bank_data = + { + .dwFlags = WAVEBANK_TYPE_STREAMING, + .dwEntryCount = 1, + .szBankName = "test", + .dwEntryMetaDataElementSize = sizeof(entry), + .dwEntryNameElementSize = WAVEBANK_ENTRYNAME_LENGTH, + .dwAlignment = 0x800, + }; + static const WAVEBANKHEADER header = + { + .dwSignature = WAVEBANK_HEADER_SIGNATURE, + .dwVersion = XACT_CONTENT_VERSION, + .dwHeaderVersion = WAVEBANK_HEADER_VERSION, + .Segments = + { + [WAVEBANK_SEGIDX_BANKDATA] = + { + .dwOffset = sizeof(header), + .dwLength = sizeof(bank_data), + }, + [WAVEBANK_SEGIDX_ENTRYMETADATA] = + { + .dwOffset = sizeof(header) + sizeof(bank_data), + .dwLength = sizeof(entry), + }, + }, + }; + static WCHAR path[MAX_PATH]; + DWORD written; + HANDLE file; + + GetTempPathW(ARRAY_SIZE(path), path); + lstrcatW(path, L"test.xwb"); + + file = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(file != INVALID_HANDLE_VALUE, "Cannot create file %s, error %ld\n", + wine_dbgstr_w(path), GetLastError()); + + WriteFile(file, &header, sizeof(header), &written, NULL); + ok(written == sizeof(header), "Cannot write header\n"); + + WriteFile(file, &bank_data, sizeof(bank_data), &written, NULL); + ok(written == sizeof(bank_data), "Cannot write bank data\n"); + + WriteFile(file, &entry, sizeof(entry), &written, NULL); + ok(written == sizeof(entry), "Cannot write entry\n"); + + CloseHandle(file); + + return path; +} + +struct notification_cb_data +{ + XACTNOTIFICATIONTYPE type; + IXACT3WaveBank *wave_bank; + BOOL received; + DWORD thread_id; +}; + +static void WINAPI notification_cb(const XACT_NOTIFICATION *notification) +{ + struct notification_cb_data *data = notification->pvContext; + DWORD thread_id = GetCurrentThreadId(); + + data->received = TRUE; + ok(notification->type == data->type, + "Unexpected notification type %u\n", notification->type); + ok(notification->waveBank.pWaveBank == data->wave_bank, "Unexpected wave bank %p instead of %p\n", + notification->waveBank.pWaveBank, data->wave_bank); + ok(thread_id == data->thread_id, "Unexpected thread id %#lx instead of %#lx\n", thread_id, data->thread_id); +} + +static void test_notifications(void) +{ + struct notification_cb_data prepared_data = { 0 }, destroyed_data = { 0 }; + XACT_NOTIFICATION_DESCRIPTION notification_desc = { 0 }; + XACT_STREAMING_PARAMETERS streaming_params = { 0 }; + XACT_RUNTIME_PARAMETERS params = { 0 }; + IXACT3Engine *engine; + WCHAR *filename; + unsigned int i; + HANDLE file; + DWORD state; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_XACTEngine, NULL, CLSCTX_INPROC_SERVER, &IID_IXACT3Engine, (void **)&engine); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG) /* Win 10 v1507 */, "Cannot create engine, hr %#lx\n", hr); + + if (hr == REGDB_E_CLASSNOTREG) + { + win_skip("XACT not supported\n"); + return; + } + + params.lookAheadTime = XACT_ENGINE_LOOKAHEAD_DEFAULT; + params.fnNotificationCallback = notification_cb; + + hr = IXACT3Engine_Initialize(engine, ¶ms); + ok(hr == S_OK, "Cannot initialize engine, hr %#lx\n", hr); + + prepared_data.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + prepared_data.thread_id = GetCurrentThreadId(); + notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKPREPARED; + notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; + notification_desc.pvContext = &prepared_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + destroyed_data.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED; + destroyed_data.thread_id = GetCurrentThreadId(); + notification_desc.type = XACTNOTIFICATIONTYPE_WAVEBANKDESTROYED; + notification_desc.flags = XACT_FLAG_NOTIFICATION_PERSIST; + notification_desc.pvContext = NULL; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + /* Registering again overrides pvContext, but each notification + * class has its own pvContext. */ + notification_desc.pvContext = &destroyed_data; + hr = IXACT3Engine_RegisterNotification(engine, ¬ification_desc); + ok(hr == S_OK, "Cannot register notification, hr %#lx\n", hr); + + filename = gen_xwb_file(); + + file = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + ok(file != INVALID_HANDLE_VALUE, "Cannot open file\n"); + + streaming_params.file = file; + streaming_params.packetSize = 0x800; + hr = IXACT3Engine_CreateStreamingWaveBank(engine, &streaming_params, &prepared_data.wave_bank); + ok(hr == S_OK, "Cannot create a streaming wave bank, hr %#lx\n", hr); + destroyed_data.wave_bank = prepared_data.wave_bank; + + for (i = 0; i < 10 && !prepared_data.received; i++) + { + IXACT3Engine_DoWork(engine); + Sleep(1); + } + + hr = IXACT3WaveBank_GetState(prepared_data.wave_bank, &state); + ok(hr == S_OK, "Cannot query wave bank state, hr %#lx\n", hr); + ok(state == XACT_WAVEBANKSTATE_PREPARED, "Wave bank is not in prepared state, but in %#lx\n", state); + + todo_wine ok(prepared_data.received, "The 'wave bank prepared' notification was never received\n"); + ok(!destroyed_data.received, "The 'wave bank destroyed' notification was received too early\n"); + + IXACT3WaveBank_Destroy(prepared_data.wave_bank); + todo_wine ok(destroyed_data.received, "The 'wave bank destroyed' notification was never received\n"); + + CloseHandle(file); + IXACT3Engine_Release(engine); + + DeleteFileW(filename); +} + START_TEST(xact3) { CoInitialize(NULL);
test_interfaces(); + test_notifications();
CoUninitialize(); }