home *** CD-ROM | disk | FTP | other *** search
- /*
- Company: Sensaura
- Copyright: (C) 1998
-
- File Name: sensaura.cpp
- File Description: Source file for implementation of Sensaura DirectSound functions
- Author: Adam Philp
- File Version: 1.01.000
- Last Update: 30-OCT-98
-
- Target Compiler: Microsoft Visual C++ Version 5.0
- */
-
- /////////////////////// Included files ////////////////////////////////////////////////////////////
-
- #include <windows.h>
-
- #include "sensaura.h" // Header file containing global function declarations and GUID
- #include "directx.h" // DirectX error handling functions and macros
- #include "resource.h" // Wave audio and bitmap resources for Sensaura splash screen & jingle
- #include "debug.h" // Debugging support macros and functions
-
- /////////////////////// Local functions ///////////////////////////////////////////////////////////
-
- /*
- Function: SensauraSplash
- Description: Display Sensaura logo bitmap and play grooooooovy Sensaura jingle.
- Parameters: pDS - pointer to the DirectSound object to use for playing the jingle
- hInstance - application instance handle
- */
-
- void SensauraSplash(LPDIRECTSOUND pDS, HINSTANCE hInstance)
- {
- LPSTR pSplashName = "Sensaura 3D Positional Audio";
- WNDCLASS wc = { CS_DBLCLKS, DefWindowProc, 0, 0,
- hInstance, NULL, NULL, NULL, NULL, pSplashName };
- BITMAP bmSplash;
- PAINTSTRUCT ps;
- HWND hwndSplash = NULL;
- HDC hdc, hdcMemory;
- HBITMAP hbmSplash = NULL;
- HGDIOBJ hgdiOld;
- LPDIRECTSOUNDBUFFER pPrimary = NULL, pJingle = NULL;
- DSBUFFERDESC dsbd = { sizeof(dsbd), DSBCAPS_PRIMARYBUFFER, 0, 0, NULL };
- WAVEFORMATEX wfx;
- DWORD dwStatus;
-
- ASSERT(pDS);
- // Get the Sensaura logo bitmap
- hbmSplash = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SPLASH));
- if(hbmSplash == NULL)
- goto PLAY_JINGLE;
- // Get its dimensions
- if (!GetObject(hbmSplash, sizeof(BITMAP), (void*)&bmSplash))
- goto PLAY_JINGLE;
-
- if(!RegisterClass(&wc)) // Register a class for our splash window
- goto PLAY_JINGLE;
- // Create the splash window
- hwndSplash = CreateWindowEx(WS_EX_TOPMOST,
- pSplashName,
- pSplashName,
- WS_POPUP|WS_VISIBLE,
- (GetSystemMetrics(SM_CXSCREEN)-bmSplash.bmWidth)/2,
- (GetSystemMetrics(SM_CYSCREEN)-bmSplash.bmHeight)/2,
- bmSplash.bmWidth, bmSplash.bmHeight,
- NULL, NULL, hInstance, NULL);
- if(hwndSplash == NULL)
- goto PLAY_JINGLE;
-
- hdc = BeginPaint(hwndSplash, &ps); // Paint the logo in the window
- hdcMemory = CreateCompatibleDC(hdc);
- hgdiOld = SelectObject(hdcMemory, hbmSplash);
-
- BitBlt(hdc, 0, 0, bmSplash.bmWidth, bmSplash.bmHeight, hdcMemory, 0, 0, SRCCOPY);
-
- SelectObject(hdcMemory, hgdiOld);
- DeleteDC(hdcMemory);
- EndPaint(hwndSplash, &ps);
-
- ShowWindow(hwndSplash, SW_NORMAL); // Display the window on the screen
- UpdateWindow(hwndSplash);
-
- PLAY_JINGLE: // Play the groooooovy Sensaura jingle
- // Create a primary buffer first
- TRY_DS(pDS->SetCooperativeLevel(GetForegroundWindow(), DSSCL_EXCLUSIVE))
- TRY_DS(pDS->CreateSoundBuffer(&dsbd, &pPrimary, NULL))
- // Create an object containing the wav file data
- pJingle = CreateDSBufferFromResource(pDS,
- DSBCAPS_GLOBALFOCUS,
- MAKEINTRESOURCE(IDR_WAVE_JINGLE));
- if(pJingle == NULL)
- goto DS_ERROR;
- TRY_DS(pJingle->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL)) // Get the format of the WAV data
- TRY_DS(pPrimary->SetFormat(&wfx)) // Set the primary buffer to the WAV data format
- TRY_DS(pJingle->Play(0, 0, 0)) // Play the file ...
- do // ... and wait for it to finish
- {
- TRY_DS(pJingle->GetStatus(&dwStatus))
- }
- while(dwStatus);
-
- DS_ERROR:
- RELEASE(pJingle) // Destroy everything we created to play the file
- RELEASE(pPrimary)
- if(hwndSplash) // Destroy everything we created to display the logo
- DestroyWindow(hwndSplash);
- if(hbmSplash)
- DeleteObject(hbmSplash);
- UnregisterClass(pSplashName, hInstance);
- }
-
- /*
- Function: SensauraQuerySupport
- Description: Test whether a property set interface supports Sensaura properties
- Parameters: pKsPropertySet - pointer to property set interface to test
- propid - ID of the property in the Sensaura property set to test
- Return value: A combination of flags depending on the level of support:
- KSPROPERTY_SUPPORT_GET if the value of the property can be retrieved
- KSPROPERTY_SUPPORT_SET if the value of the property can be altered
- */
-
- ULONG SensauraQuerySupport(LPKSPROPERTYSET pKsPropertySet, ULONG propid)
- {
- ULONG support;
-
- ASSERT(pKsPropertySet);
- if(pKsPropertySet->QuerySupport(DSPROPSETID_DirectSoundSensaura, propid, &support) != DS_OK)
- return 0;
- return support;
- }
-
- /*
- Function: IsSensaura
- Description: Check whether a DirectSound object supports the Sensaura property set
- Parameters: pDS - Pointer to the DirectSound object to check
- Return value: TRUE if the property set is supported, FALSE otherwise
- */
-
- bool IsSensaura(LPDIRECTSOUND pDS)
- {
- LPDIRECTSOUNDBUFFER pBuffer = NULL;
- LPKSPROPERTYSET pKsPropertySet = NULL;
- DSBUFFERDESC dsbd = {sizeof(dsbd), DSBCAPS_PRIMARYBUFFER, 0, 0, NULL};
- bool bIsSensaura = false;
-
- ASSERT(pDS);
-
- TRY_DS(pDS->SetCooperativeLevel(GetForegroundWindow (), DSSCL_NORMAL))
- // Create a primary buffer
- TRY_DS(pDS->CreateSoundBuffer(&dsbd, &pBuffer, NULL))
- // Query our primary buffer for property sets
- if(pBuffer->QueryInterface(IID_IKsPropertySet, (void**)&pKsPropertySet) == DS_OK)
- // Query property sets for Sensaura version numbers
- if(SensauraQuerySupport(pKsPropertySet, 0) == (KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET))
- bIsSensaura = true;
-
- DS_ERROR:
- RELEASE(pKsPropertySet) // We're done with the property set interface ...
- RELEASE(pBuffer) // ... and the primary buffer
- return bIsSensaura;
- }
-
- /*
- Function: SensauraDSEnumCallback
- Description: DirectSoundEnumerate callback function. For each enumerated sound card,
- create a DirectSound object. If it supports Sensaura return a pointer to
- the object via pvContext and tell DirectSoundEnumerate to stop. Otherwise,
- destroy the DirectSound object.
- Parameters: pGuid - GUID for the sound card to test
- pvContext - pointer to allow DirectSound object to be passed back
- Returns: FALSE to stop enumeration. TRUE to continue enumeration
- */
-
- BOOL CALLBACK SensauraDSEnumCallback(LPGUID pGuid, LPCSTR, LPCSTR, LPVOID pvContext)
- {
- LPDIRECTSOUND* ppDS = (LPDIRECTSOUND*)pvContext;
- ASSERT(ppDS);
- // Create DirectSound object for this GUID
- TRY_DS(DirectSoundCreate(pGuid, ppDS, NULL))
- if(IsSensaura(*ppDS)) // Is it a Sensaura card?
- return FALSE; // Yes, so stop enumerating
-
- DS_ERROR: // No, it's not a Sensaura card ...
- RELEASE((*ppDS)) // ... so destroy the DirectSound object ...
- return TRUE; // ... and carry on enumerating
- }
-
- /////////////////////// Global functions //////////////////////////////////////////////////////////
-
- /*
- Function: SensauraCreate
- Description: Wrapper around standard DirectSoundCreate function. Determines whether a
- pukka Sensaura sound card is being used. Tries to create a Sensaura
- DirectSound object. If it can't it creates a non-Sensaura DirectSound
- object for the default card.
- Parameters: ppDS - address to fill with the address of the DirectSound object created.
- Filled with NULL if an error occurs.
- hInstance - application instance handle
- bSearchCards - If true, searches for a Sensaura equipped sound card. If
- false, the default card is used, whether or not it has Sensaura.
- Returns value: true if a Sensaura DirectSound object was created. false if a
- non-Sensaura DirectSound object was created or an error occurred.
- */
-
- bool SensauraCreate(LPDIRECTSOUND* ppDS, HINSTANCE hInstance, bool bSearchCards)
- {
- ASSERT(ppDS);
-
- if(bSearchCards) // Do we want to check all installed cards ?
- {
- if(DirectSoundEnumerate(SensauraDSEnumCallback, (LPVOID)ppDS) == DS_OK)
- { // Found a Sensaura card ?
- // Yes, so do Sensaura splash bitmap and jingle
- SensauraSplash(*ppDS, hInstance);
- return true; // A Sensaura DirectSound object was created
- }
- }
- // Create a DirectSound object for the default card
- TRY_DS(DirectSoundCreate(NULL, ppDS, NULL))
- if(IsSensaura(*ppDS)) // Is it a Sensaura card ?
- { // Yes, so do Sensaura splash bitmap and jingle
- SensauraSplash(*ppDS, hInstance);
- return true; // A Sensaura DirectSound object was created
- }
- return false; // Return false if DirectSound object is not Sensaura
-
- DS_ERROR: // An error occurred
- *ppDS = NULL; // Ensure that the DirectSound pointer contains NULL
- return false;
- }