home *** CD-ROM | disk | FTP | other *** search
/ Game Audio Programming / GameAudioProgramming.iso / Extras / Sensaura / SDK1.0 / data1.cab / Example_Files / DS3DDemo / Source / sensaura.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-13  |  8.8 KB  |  231 lines

  1. /*
  2.     Company:            Sensaura
  3.     Copyright:          (C) 1998
  4.  
  5.     File Name:            sensaura.cpp
  6.     File Description:    Source file for implementation of Sensaura DirectSound functions
  7.     Author:                Adam Philp
  8.     File Version:        1.01.000
  9.     Last Update:        30-OCT-98
  10.  
  11.     Target Compiler:    Microsoft Visual C++ Version 5.0
  12. */
  13.  
  14. ///////////////////////    Included files ////////////////////////////////////////////////////////////
  15.  
  16. #include <windows.h>
  17.  
  18. #include "sensaura.h"    // Header file containing global function declarations and GUID
  19. #include "directx.h"    // DirectX error handling functions and macros
  20. #include "resource.h"    // Wave audio and bitmap resources for Sensaura splash screen & jingle
  21. #include "debug.h"        // Debugging support macros and functions
  22.  
  23. ///////////////////////    Local functions ///////////////////////////////////////////////////////////
  24.  
  25. /*
  26.     Function:            SensauraSplash
  27.     Description:        Display Sensaura logo bitmap and play grooooooovy Sensaura jingle.
  28.     Parameters:            pDS - pointer to the DirectSound object to use for playing the jingle
  29.                         hInstance - application instance handle
  30. */
  31.  
  32. void SensauraSplash(LPDIRECTSOUND pDS, HINSTANCE hInstance)
  33. {
  34.     LPSTR                pSplashName = "Sensaura 3D Positional Audio";
  35.     WNDCLASS            wc = { CS_DBLCLKS, DefWindowProc, 0, 0, 
  36.                         hInstance, NULL, NULL, NULL, NULL, pSplashName };
  37.     BITMAP                bmSplash;
  38.     PAINTSTRUCT            ps;
  39.     HWND                hwndSplash = NULL;
  40.     HDC                    hdc, hdcMemory;
  41.     HBITMAP                hbmSplash = NULL;
  42.     HGDIOBJ                hgdiOld;
  43.     LPDIRECTSOUNDBUFFER    pPrimary = NULL, pJingle = NULL;
  44.     DSBUFFERDESC        dsbd = { sizeof(dsbd), DSBCAPS_PRIMARYBUFFER, 0, 0, NULL };
  45.     WAVEFORMATEX        wfx;
  46.     DWORD                dwStatus;
  47.  
  48.     ASSERT(pDS);    
  49.                                         // Get the Sensaura logo bitmap
  50.     hbmSplash = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_SPLASH));
  51.     if(hbmSplash == NULL) 
  52.         goto PLAY_JINGLE;
  53.                                         // Get its dimensions
  54.     if (!GetObject(hbmSplash, sizeof(BITMAP), (void*)&bmSplash)) 
  55.         goto PLAY_JINGLE;
  56.  
  57.     if(!RegisterClass(&wc))                // Register a class for our splash window
  58.         goto PLAY_JINGLE;
  59.                                         // Create the splash window
  60.     hwndSplash = CreateWindowEx(WS_EX_TOPMOST,
  61.                                 pSplashName,
  62.                                 pSplashName,
  63.                                 WS_POPUP|WS_VISIBLE,
  64.                                 (GetSystemMetrics(SM_CXSCREEN)-bmSplash.bmWidth)/2,      
  65.                                 (GetSystemMetrics(SM_CYSCREEN)-bmSplash.bmHeight)/2,     
  66.                                 bmSplash.bmWidth, bmSplash.bmHeight,      
  67.                                 NULL, NULL, hInstance, NULL);
  68.     if(hwndSplash == NULL)
  69.         goto PLAY_JINGLE;
  70.     
  71.     hdc = BeginPaint(hwndSplash, &ps);    // Paint the logo in the window
  72.     hdcMemory = CreateCompatibleDC(hdc);
  73.     hgdiOld = SelectObject(hdcMemory, hbmSplash);
  74.  
  75.     BitBlt(hdc, 0, 0, bmSplash.bmWidth, bmSplash.bmHeight, hdcMemory, 0, 0, SRCCOPY);
  76.  
  77.     SelectObject(hdcMemory, hgdiOld);
  78.     DeleteDC(hdcMemory);
  79.     EndPaint(hwndSplash, &ps);
  80.     
  81.     ShowWindow(hwndSplash, SW_NORMAL);    // Display the window on the screen
  82.     UpdateWindow(hwndSplash);
  83.  
  84. PLAY_JINGLE:                            // Play the groooooovy Sensaura jingle    
  85.                                         // Create a primary buffer first
  86.     TRY_DS(pDS->SetCooperativeLevel(GetForegroundWindow(), DSSCL_EXCLUSIVE))
  87.     TRY_DS(pDS->CreateSoundBuffer(&dsbd, &pPrimary, NULL))
  88.                                         // Create an object containing the wav file data
  89.     pJingle = CreateDSBufferFromResource(pDS, 
  90.                                          DSBCAPS_GLOBALFOCUS, 
  91.                                          MAKEINTRESOURCE(IDR_WAVE_JINGLE));
  92.     if(pJingle == NULL)
  93.         goto DS_ERROR;
  94.     TRY_DS(pJingle->GetFormat(&wfx, sizeof(WAVEFORMATEX), NULL))    // Get the format of the WAV data
  95.     TRY_DS(pPrimary->SetFormat(&wfx))    // Set the primary buffer to the WAV data format
  96.     TRY_DS(pJingle->Play(0, 0, 0))        // Play the file ...
  97.     do                                    // ... and wait for it to finish 
  98.     {
  99.         TRY_DS(pJingle->GetStatus(&dwStatus))
  100.     }
  101.     while(dwStatus);
  102.  
  103. DS_ERROR:                                
  104.     RELEASE(pJingle)                    // Destroy everything we created to play the file
  105.     RELEASE(pPrimary)
  106.     if(hwndSplash)                        // Destroy everything we created to display the logo
  107.         DestroyWindow(hwndSplash);
  108.     if(hbmSplash)
  109.         DeleteObject(hbmSplash);
  110.     UnregisterClass(pSplashName, hInstance);    
  111. }
  112.  
  113. /*
  114.     Function:            SensauraQuerySupport
  115.     Description:        Test whether a property set interface supports Sensaura properties
  116.     Parameters:            pKsPropertySet - pointer to property set interface to test
  117.                         propid - ID of the property in the Sensaura property set to test
  118.     Return value:        A combination of flags depending on the level of support:
  119.                         KSPROPERTY_SUPPORT_GET if the value of the property can be retrieved
  120.                         KSPROPERTY_SUPPORT_SET if the value of the property can be altered
  121. */
  122.  
  123. ULONG SensauraQuerySupport(LPKSPROPERTYSET pKsPropertySet, ULONG propid)
  124. {
  125.     ULONG support;
  126.  
  127.     ASSERT(pKsPropertySet);
  128.     if(pKsPropertySet->QuerySupport(DSPROPSETID_DirectSoundSensaura, propid, &support) != DS_OK)
  129.         return 0;
  130.     return support;
  131. }
  132.  
  133. /*
  134.     Function:            IsSensaura
  135.     Description:        Check whether a DirectSound object supports    the Sensaura property set
  136.     Parameters:            pDS - Pointer to the DirectSound object to check        
  137.     Return value:        TRUE if the property set is supported, FALSE otherwise
  138. */
  139.  
  140. bool IsSensaura(LPDIRECTSOUND pDS)
  141. {
  142.     LPDIRECTSOUNDBUFFER pBuffer = NULL;
  143.     LPKSPROPERTYSET        pKsPropertySet = NULL;
  144.     DSBUFFERDESC        dsbd = {sizeof(dsbd), DSBCAPS_PRIMARYBUFFER, 0, 0, NULL};
  145.     bool                bIsSensaura = false;
  146.  
  147.     ASSERT(pDS);
  148.                                         
  149.     TRY_DS(pDS->SetCooperativeLevel(GetForegroundWindow (), DSSCL_NORMAL))
  150.                                         // Create a primary buffer
  151.     TRY_DS(pDS->CreateSoundBuffer(&dsbd, &pBuffer, NULL))
  152.                                         // Query our primary buffer for property sets
  153.     if(pBuffer->QueryInterface(IID_IKsPropertySet, (void**)&pKsPropertySet) == DS_OK)
  154.                                         // Query property sets for Sensaura version numbers
  155.         if(SensauraQuerySupport(pKsPropertySet, 0) == (KSPROPERTY_SUPPORT_GET|KSPROPERTY_SUPPORT_SET))
  156.             bIsSensaura = true;
  157.  
  158. DS_ERROR:                                                                
  159.     RELEASE(pKsPropertySet)                // We're done with the property set interface ...
  160.     RELEASE(pBuffer)                    // ... and the primary buffer
  161.     return bIsSensaura;
  162. }
  163.  
  164. /*
  165.     Function:            SensauraDSEnumCallback
  166.     Description:        DirectSoundEnumerate callback function.  For each enumerated sound card, 
  167.                         create a DirectSound object.  If it supports Sensaura return a pointer to 
  168.                         the object via pvContext and tell DirectSoundEnumerate to stop.  Otherwise, 
  169.                         destroy the DirectSound object.
  170.     Parameters:            pGuid - GUID for the sound card to test        
  171.                         pvContext -    pointer to allow DirectSound object to be passed back
  172.     Returns:            FALSE to stop enumeration. TRUE to continue enumeration
  173. */
  174.  
  175. BOOL CALLBACK SensauraDSEnumCallback(LPGUID pGuid, LPCSTR, LPCSTR, LPVOID pvContext)
  176. {
  177.     LPDIRECTSOUND* ppDS = (LPDIRECTSOUND*)pvContext;
  178.     ASSERT(ppDS);
  179.                                         // Create DirectSound object for this GUID
  180.     TRY_DS(DirectSoundCreate(pGuid,    ppDS, NULL))    
  181.     if(IsSensaura(*ppDS))                // Is it a Sensaura card? 
  182.         return FALSE;                    // Yes, so stop enumerating
  183.  
  184. DS_ERROR:                                // No, it's not a Sensaura card ...
  185.     RELEASE((*ppDS))                    // ... so destroy the DirectSound object ...
  186.     return TRUE;                        // ... and carry on enumerating
  187. }
  188.  
  189. ///////////////////////    Global functions //////////////////////////////////////////////////////////
  190.  
  191. /*
  192.     Function:            SensauraCreate
  193.     Description:        Wrapper around standard DirectSoundCreate function.  Determines whether a
  194.                         pukka Sensaura sound card is being used.  Tries to create a    Sensaura 
  195.                         DirectSound object.  If it can't it creates a non-Sensaura DirectSound 
  196.                         object for the default card.
  197.     Parameters:            ppDS - address to fill with the address of the DirectSound object created.
  198.                         Filled with NULL if an error occurs.
  199.                         hInstance - application instance handle
  200.                         bSearchCards - If true, searches for a Sensaura equipped sound card. If
  201.                         false, the default card is used, whether or not it has Sensaura.
  202.     Returns value:        true if a Sensaura DirectSound object was created.    false if a 
  203.                         non-Sensaura DirectSound object was created or an error    occurred.
  204. */
  205.  
  206. bool SensauraCreate(LPDIRECTSOUND* ppDS, HINSTANCE hInstance, bool bSearchCards)
  207. {
  208.     ASSERT(ppDS);
  209.  
  210.     if(bSearchCards)                     // Do we want to check all installed cards ?
  211.     {
  212.         if(DirectSoundEnumerate(SensauraDSEnumCallback, (LPVOID)ppDS) == DS_OK)
  213.         {                                // Found a Sensaura card ?
  214.                                         // Yes, so do Sensaura splash bitmap and jingle
  215.             SensauraSplash(*ppDS, hInstance);        
  216.             return true;                // A Sensaura DirectSound object was created
  217.         }
  218.     }
  219.                                         // Create a DirectSound object for the default card
  220.     TRY_DS(DirectSoundCreate(NULL, ppDS, NULL))
  221.     if(IsSensaura(*ppDS))                 // Is it a Sensaura card ?
  222.     {                                    // Yes, so do Sensaura splash bitmap and jingle
  223.         SensauraSplash(*ppDS, hInstance);    
  224.         return true;                    // A Sensaura DirectSound object was created
  225.     }
  226.     return false;                        // Return false if DirectSound object is not Sensaura
  227.  
  228. DS_ERROR:                                // An error occurred
  229.     *ppDS = NULL;                        // Ensure that the DirectSound pointer contains NULL
  230.     return false;
  231. }