mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-22 19:55:23 +00:00
13711c3036
D3 used to support Aureal 3-Dimensional sound cards, providing 3D spatial audio. The hardware and drivers is outdated, so all support in code has been removed, including UI mixer setting. Read more about A3D here: https://en.wikipedia.org/wiki/Aureal_Semiconductor#A3D
894 lines
22 KiB
C++
894 lines
22 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
--- HISTORICAL COMMENTS FOLLOW ---
|
|
|
|
* $Logfile: /DescentIII/Main/D3Launch/AudioTab.cpp $
|
|
* $Revision: 1.1.1.1 $
|
|
* $Date: 2003-08-26 03:56:51 $
|
|
* $Author: kevinb $
|
|
*
|
|
*
|
|
*
|
|
* $Log: not supported by cvs2svn $
|
|
*
|
|
* 39 9/29/99 10:39a Nate
|
|
* Aureal OEM now allows other mixers
|
|
*
|
|
* 38 8/19/99 6:13p Samir
|
|
* detect vortex1 chipsets.
|
|
*
|
|
* 37 6/09/99 2:46p Nate
|
|
* Minor changes for different builds
|
|
*
|
|
* 35 5/20/99 1:08p Samir
|
|
* fixed EAX check.
|
|
*
|
|
* 34 5/20/99 12:53p Nate
|
|
* Added GLSetup window, EAX mixer support, and CHFlight+Mouseman Mode
|
|
* options
|
|
*
|
|
* 33 4/27/99 10:41p Nate
|
|
* Added 16bit dsound support
|
|
*
|
|
* 32 3/29/99 4:34p Samir
|
|
* better checking of results from Aureal initialization.
|
|
*
|
|
* 31 3/29/99 4:25p Nate
|
|
* changed aureal check.
|
|
*
|
|
* 30 3/29/99 4:08p Samir
|
|
* check for Aureal 2.0 reflections to see if hardware is supported.
|
|
*
|
|
* 29 3/29/99 3:52p Samir
|
|
* Check for occlusions feature in Aureal after initialized.
|
|
*
|
|
* 28 3/29/99 3:21p Samir
|
|
* added aureal 2.0 check.
|
|
*
|
|
* 27 3/29/99 3:14p Nate
|
|
* Added OEM_GENERIC
|
|
*
|
|
* 26 3/04/99 12:07p Nate
|
|
* Made Software the default mixer (if it's available)
|
|
*
|
|
* 25 2/28/99 5:31p Nate
|
|
* Disabled DS3D and Aureal mixers for the Voodoo3 OEM
|
|
*
|
|
* 24 2/05/99 3:51p Nate
|
|
* Added conditional compilation directives for OEM support
|
|
*
|
|
* 23 10/23/98 6:48p Nate
|
|
* more fixes.
|
|
*
|
|
* 22 10/23/98 5:29p Nate
|
|
* Small fixes.
|
|
*
|
|
* 21 10/21/98 4:51p Nate
|
|
* More fixes.
|
|
*
|
|
* 20 10/18/98 2:43p Nate
|
|
* Dimmed D3D and Aureal Mixer options for the demo
|
|
*
|
|
* 19 10/15/98 10:54a Nate
|
|
* Added Launcher Sound toggling
|
|
*
|
|
* 18 10/14/98 5:52p Nate
|
|
* More fixes
|
|
*
|
|
* 17 10/14/98 11:37a Nate
|
|
* Added default to DS8 for Chris
|
|
*
|
|
* 16 10/13/98 3:03p Nate
|
|
* More fixes and changes.
|
|
*
|
|
* 15 10/12/98 8:16p Nate
|
|
* Commented out "old Aureal DLL" messages for now
|
|
*
|
|
* 14 10/12/98 7:13p Nate
|
|
* Fixed several bugs.
|
|
*
|
|
* 13 10/10/98 4:05p Nate
|
|
* Added detection/scanning window messages
|
|
*
|
|
* 12 10/10/98 2:33p Nate
|
|
* More fixes.
|
|
*
|
|
* 11 10/08/98 6:23p Nate
|
|
* Fixed a few bugs.
|
|
*
|
|
* 10 9/25/98 6:57p Nate
|
|
* If no card is in registry, the list box now defaults to none.
|
|
*
|
|
* 9 9/22/98 3:33p Nate
|
|
* Added conditional compiling to help system (can toggle between HTML and
|
|
* standard windows help)
|
|
*
|
|
* 8 9/21/98 5:40p Nate
|
|
* Incorporated the new HTML help system
|
|
*
|
|
* 7 9/21/98 12:12p Nate
|
|
* Changed "Soundcard" registry value name to "SoundcardName"
|
|
*
|
|
* 6 9/01/98 7:15p Nate
|
|
* Major Revision #2
|
|
*
|
|
* 5 8/31/98 6:44p Nate
|
|
* Major Revision
|
|
*
|
|
* 4 8/10/98 10:44a Nate
|
|
* Added Language selection support
|
|
*
|
|
* 3 8/05/98 4:52p Nate
|
|
* Added registry reading and writing.
|
|
*
|
|
* 2 8/05/98 11:54a Nate
|
|
* Initial Version
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
// AudioTab.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "afxpriv.h"
|
|
#include "afxext.h"
|
|
#include "D3Launch.h"
|
|
#include "D3LaunchDlg.h"
|
|
#include "AudioTab.h"
|
|
|
|
#include <windows.h>
|
|
#include <mmsystem.h>
|
|
#include <dsound.h>
|
|
#include <objbase.h>
|
|
#include <initguid.h>
|
|
|
|
#include "ia3dapi.h"
|
|
#include "ia3dutil.h"
|
|
#include "eax.h"
|
|
|
|
#include "OS_Config.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define MAX_CARDS 32
|
|
|
|
#define SBT_PRIMARY 0
|
|
|
|
// Supported sound mixers (for saving to registry)
|
|
#define SOUND_MIXER_SOFTWARE_16 0
|
|
#define SOUND_MIXER_DS_16 1
|
|
#define SOUND_MIXER_DS_8 2
|
|
#define SOUND_MIXER_DS3D_16 3
|
|
#define SOUND_MIXER_AUREAL_16 4
|
|
#define SOUND_MIXER_NONE 5
|
|
#define SOUND_MIXER_EAX 6
|
|
|
|
// Setup available mixer flags
|
|
#define SOFTWARE_MIXER 0x01
|
|
#define DS8BIT_MIXER 0x02
|
|
#define DS16BIT_MIXER 0x04
|
|
#define DS3D_MIXER 0x08
|
|
#define AUREAL_MIXER 0x10 // Unused
|
|
#define EAX_MIXER 0x20
|
|
|
|
typedef struct {
|
|
GUID guid;
|
|
LPGUID pguid;
|
|
|
|
char name[1024]; // Name of the device
|
|
UINT mixers; // Mixers supported by device
|
|
} SoundCard;
|
|
|
|
static SoundCard Cards[MAX_CARDS];
|
|
static int Num_cards;
|
|
|
|
// the callback for the DirectSound enumeration process
|
|
BOOL WINAPI dsound_enum_callback
|
|
(
|
|
GUID FAR * lpGuid,
|
|
LPSTR lpDeviceDescription,
|
|
LPSTR lpDeviceName,
|
|
LPVOID lpContext
|
|
)
|
|
{
|
|
SoundCard *card=&Cards[Num_cards++];
|
|
|
|
if ( lpGuid ) {
|
|
memmove( &card->guid, lpGuid, sizeof(GUID) );
|
|
card->pguid = &card->guid;
|
|
} else {
|
|
memset( &card->guid, 0, sizeof(GUID) );
|
|
card->pguid = NULL;
|
|
}
|
|
|
|
// Save name of device
|
|
sprintf(card->name, "%s", lpDeviceDescription);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// Creates a Primary direct sound buffer
|
|
HRESULT
|
|
CreateDSBuffer
|
|
(
|
|
LPDIRECTSOUND lpDirectSound,
|
|
int buffer_type,
|
|
LPDIRECTSOUNDBUFFER *lp_lp_dsb,
|
|
DWORD sound_bytes,
|
|
DWORD frequency,
|
|
bool f_is_stereo,
|
|
bool f_is_16_bit,
|
|
bool positional
|
|
)
|
|
{
|
|
DSBUFFERDESC dsbd;
|
|
tWAVEFORMATEX fmt;
|
|
HRESULT result;
|
|
|
|
if(frequency != 44100 && frequency != 22050 && frequency != 11025)
|
|
return 0;
|
|
|
|
if(lpDirectSound==NULL)
|
|
return 0;
|
|
|
|
// Setup the wave format
|
|
fmt.nChannels = (f_is_stereo)?2:1;
|
|
fmt.wBitsPerSample = (f_is_16_bit)?16:8;
|
|
fmt.nSamplesPerSec = ((DWORD)frequency);
|
|
fmt.nBlockAlign = fmt.nChannels*(fmt.wBitsPerSample>>3);
|
|
fmt.nAvgBytesPerSec = ((DWORD)fmt.nSamplesPerSec)*((DWORD)fmt.nBlockAlign);
|
|
fmt.wFormatTag = WAVE_FORMAT_PCM;
|
|
|
|
// Setup the secondary direct sound buffer
|
|
memset(&dsbd, 0, sizeof(dsbd));
|
|
dsbd.lpwfxFormat = (LPWAVEFORMATEX)&fmt;
|
|
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
|
dsbd.dwBufferBytes = sound_bytes;
|
|
|
|
// Setup for Software 16 bit mixer
|
|
dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
|
|
|
|
if(buffer_type != SBT_PRIMARY) return 0;
|
|
|
|
//m_primary_frequency = m_current_frequency = frequency;
|
|
//m_primary_bit_depth = fmt.wBitsPerSample;
|
|
//m_primary_alignment = fmt.nBlockAlign;
|
|
|
|
dsbd.lpwfxFormat = NULL;
|
|
dsbd.dwBufferBytes = 0;
|
|
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2;
|
|
if (positional) {
|
|
dsbd.dwFlags |= DSBCAPS_CTRL3D;
|
|
}
|
|
|
|
// Create the buffer
|
|
result = lpDirectSound->CreateSoundBuffer(&dsbd, lp_lp_dsb, 0);
|
|
|
|
if (result == DS_OK && buffer_type == SBT_PRIMARY)
|
|
{
|
|
// Succeeded. Set primary buffer to desired format.
|
|
result = (*lp_lp_dsb)->SetFormat(&fmt);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL CreativeEAXCheck(LPDIRECTSOUND lpds)
|
|
{
|
|
BOOL retval=FALSE;
|
|
DWORD properties=0;
|
|
ULONG ulAnswer=0;
|
|
LPKSPROPERTYSET lpksps = NULL;
|
|
WAVEFORMATEX wave;
|
|
DSBUFFERDESC dsbdesc;
|
|
LPDIRECTSOUNDBUFFER lpdsb=NULL;
|
|
|
|
const DWORD EAX_ENVIRONMENTS_AVAILABLE = 1,
|
|
EAX_BUFFERMIX_AVAILABLE =2;
|
|
|
|
memset(&wave, 0, sizeof(WAVEFORMATEX));
|
|
wave.wFormatTag = WAVE_FORMAT_PCM;
|
|
wave.nChannels = 1;
|
|
wave.nSamplesPerSec = 11025;
|
|
wave.wBitsPerSample = 8;
|
|
wave.nBlockAlign = wave.wBitsPerSample / 8 * wave.nChannels;
|
|
wave.nAvgBytesPerSec = wave.nSamplesPerSec * wave.nBlockAlign;
|
|
|
|
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
|
|
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
|
|
dsbdesc.dwFlags = DSBCAPS_STATIC|DSBCAPS_CTRL3D;
|
|
dsbdesc.dwBufferBytes = DSBSIZE_MIN*2;
|
|
dsbdesc.lpwfxFormat = &wave;
|
|
|
|
if ( FAILED(lpds->CreateSoundBuffer(&dsbdesc, &lpdsb, NULL)) ) {
|
|
retval = FALSE;
|
|
}
|
|
else if ( FAILED(lpdsb->QueryInterface(IID_IKsPropertySet, (LPVOID *)&lpksps)) ) {
|
|
retval = FALSE;
|
|
}
|
|
else if (FAILED(lpksps->QuerySupport(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_ALL, &ulAnswer)) ) {
|
|
retval = FALSE;
|
|
}
|
|
else {
|
|
if ( (ulAnswer & KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET) == (KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET) ) {
|
|
properties |= EAX_ENVIRONMENTS_AVAILABLE;
|
|
if (FAILED(lpksps->QuerySupport(DSPROPSETID_EAXBUFFER_ReverbProperties, DSPROPERTY_EAXBUFFER_REVERBMIX, &ulAnswer)) ) {
|
|
retval = FALSE;
|
|
}
|
|
else {
|
|
properties |= EAX_BUFFERMIX_AVAILABLE;
|
|
}
|
|
}
|
|
else {
|
|
retval = FALSE;
|
|
}
|
|
}
|
|
|
|
if (lpksps) {
|
|
lpksps->Release();
|
|
}
|
|
if (lpdsb) {
|
|
lpdsb->Release();
|
|
}
|
|
|
|
if (properties & (EAX_BUFFERMIX_AVAILABLE+EAX_ENVIRONMENTS_AVAILABLE)) {
|
|
retval = TRUE;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
|
|
// Checks capabilities of given directsound device to see which mixers
|
|
// it can handle
|
|
bool DetermineMixerOptions(LPDIRECTSOUND lpDirectSound, UINT &mixer_flags)
|
|
{
|
|
DSCAPS dscaps;
|
|
HRESULT hr;
|
|
|
|
// Default to just having DirectSound 8 bit available
|
|
mixer_flags=DS8BIT_MIXER;
|
|
|
|
dscaps.dwSize = sizeof(DSCAPS);
|
|
hr = lpDirectSound->GetCaps(&dscaps);
|
|
if(hr != DS_OK) {
|
|
return FALSE;
|
|
}
|
|
|
|
/* We have decided to remove Direct Sound mixers as an option
|
|
// Check DirectSound 8 Bit support
|
|
if(dscaps.dwFlags & DSCAPS_PRIMARY8BIT)
|
|
mixer_flags |= DS8BIT_MIXER;
|
|
else
|
|
mixer_flags &= ~DS8BIT_MIXER;
|
|
*/
|
|
// Check DirectSound 16 Bit support
|
|
if(dscaps.dwFlags & DSCAPS_PRIMARY16BIT)
|
|
mixer_flags |= DS16BIT_MIXER;
|
|
else
|
|
mixer_flags &= ~DS16BIT_MIXER;
|
|
|
|
#if (!defined(DEMO) && !defined(OEM_VOODOO3))
|
|
// Check DirectSound 3D Bit support
|
|
if(dscaps.dwMaxHw3DAllBuffers>0)
|
|
mixer_flags |= DS3D_MIXER;
|
|
else
|
|
mixer_flags &= ~DS3D_MIXER;
|
|
#endif
|
|
|
|
// Check for Software and Creative EAX support
|
|
//////////////////////////////////////////////
|
|
if(dscaps.dwFlags & DSCAPS_EMULDRIVER)
|
|
return TRUE; // In NT or bad sound card, so don't set software flag
|
|
|
|
//Set the Cooperative level AND make sure it is ok to do it
|
|
HRESULT scl_status;
|
|
scl_status = lpDirectSound->SetCooperativeLevel(pLaunchDlg->m_hWnd, DSSCL_WRITEPRIMARY);
|
|
if(scl_status != DS_OK)
|
|
return TRUE; // don't set software flag
|
|
|
|
// EAX support
|
|
if (CreativeEAXCheck(lpDirectSound)) {
|
|
mixer_flags |= EAX_MIXER;
|
|
}
|
|
|
|
// Try and create a buffer
|
|
HRESULT result;
|
|
LPDIRECTSOUNDBUFFER lp_primary_buffer;
|
|
lp_primary_buffer=NULL;
|
|
|
|
// test software
|
|
result=CreateDSBuffer(lpDirectSound, SBT_PRIMARY, &lp_primary_buffer, 0, 22050, true, true, false);
|
|
|
|
// Make sure buffer was created successfully
|
|
if(lp_primary_buffer == NULL)
|
|
return TRUE;
|
|
|
|
if(result!=DS_OK) {
|
|
lp_primary_buffer->Release();
|
|
return TRUE;
|
|
}
|
|
|
|
// Determine if we are running NT or have a bad Win95 sound card
|
|
{
|
|
DSBCAPS dsbcaps;
|
|
dsbcaps.dwSize = sizeof(DSBCAPS);
|
|
lp_primary_buffer->GetCaps(&dsbcaps);
|
|
|
|
// Is you want to see the caps, here is where -- mprintf all you want
|
|
if(!(dsbcaps.dwFlags & DSBCAPS_LOCHARDWARE))
|
|
{
|
|
lp_primary_buffer->Release();
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
// Release the buffer
|
|
lp_primary_buffer->Release();
|
|
|
|
// Device passed all four software tests, so set the flag
|
|
mixer_flags |= SOFTWARE_MIXER;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
typedef BOOL (CALLBACK *LPFN_DIRECTSOUNDENUMERATE)(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext);
|
|
typedef HRESULT (CALLBACK *LPFN_DIRECTSOUNDCREATE)(GUID FAR * lpGuid,LPDIRECTSOUND * ppDS,IUnknown FAR * pUnkOuter);
|
|
|
|
// Adds any Direct Sound devices to the list of available sound settings
|
|
void check_direct_sound()
|
|
{
|
|
int j;
|
|
HINSTANCE ds_dll_handle;
|
|
HRESULT dsrval;
|
|
LPFN_DIRECTSOUNDENUMERATE pfn_DirectSoundEnumerate;
|
|
LPFN_DIRECTSOUNDCREATE pfn_DirectSoundCreate;
|
|
LPDIRECTSOUND lpDirectSound;
|
|
|
|
ds_dll_handle = LoadLibrary("dsound.dll");
|
|
if (ds_dll_handle==NULL)
|
|
return;
|
|
|
|
// Get function pointers from DLL
|
|
pfn_DirectSoundEnumerate = (LPFN_DIRECTSOUNDENUMERATE) GetProcAddress(ds_dll_handle, "DirectSoundEnumerateA");
|
|
if (pfn_DirectSoundEnumerate==NULL) {
|
|
OutputDebugString( "Could not find DirectSoundEnumerate()\n" );
|
|
goto DSoundCleanup;
|
|
}
|
|
|
|
pfn_DirectSoundCreate = (LPFN_DIRECTSOUNDCREATE) GetProcAddress(ds_dll_handle, "DirectSoundCreate");
|
|
if (pfn_DirectSoundCreate==NULL) {
|
|
OutputDebugString( "Could not find DirectSoundCreate()\n" );
|
|
goto DSoundCleanup;
|
|
}
|
|
|
|
// Enumerate sound cards/devices on user's system
|
|
dsrval = pfn_DirectSoundEnumerate((LPDSENUMCALLBACKA)dsound_enum_callback, NULL );
|
|
if ( dsrval != DS_OK ) {
|
|
OutputDebugString( "DirectSoundEnumerate failed.\n" );
|
|
goto DSoundCleanup;
|
|
}
|
|
|
|
// Evaluate mixer capabilities for each device
|
|
for(j=1; j<Num_cards; j++) {
|
|
|
|
// No matter what, allow default mixer to be selected
|
|
Cards[j].mixers=DS8BIT_MIXER;
|
|
|
|
// Initialize Direct sound and get available mixers
|
|
if(DirectSoundCreate(Cards[j].pguid, &lpDirectSound, NULL) == DS_OK) {
|
|
// Creation succeeded.
|
|
//lpDirectSound->lpVtbl->SetCooperativeLevel(lpDirectSound, hwnd, DSSCL_NORMAL);
|
|
// .
|
|
// . Place code to access DirectSound object here.
|
|
// .
|
|
DetermineMixerOptions(lpDirectSound,Cards[j].mixers);
|
|
lpDirectSound->Release();
|
|
}
|
|
else {
|
|
OutputDebugString( "DirectSoundCreate failed.\n" );
|
|
//goto DSoundCleanup;
|
|
}
|
|
|
|
#if (!defined(DEMO) && !defined(OEM_VOODOO3))
|
|
// Try to initialize Aureal 3D sound
|
|
{
|
|
Cards[j].mixers &= ~AUREAL_MIXER;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
DSoundCleanup:
|
|
FreeLibrary(ds_dll_handle);
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAudioTab property page
|
|
|
|
IMPLEMENT_DYNCREATE(CAudioTab, CPropertyPage)
|
|
|
|
CAudioTab::CAudioTab() : CPropertyPage(CAudioTab::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CAudioTab)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
}
|
|
|
|
CAudioTab::~CAudioTab()
|
|
{
|
|
}
|
|
|
|
// Fills in Cards and Num_cards
|
|
void detect_sound_cards(int really_detect)
|
|
{
|
|
Num_cards = 0;
|
|
|
|
CString no_sound_msg;
|
|
no_sound_msg.LoadString(IDS_AUDIOTAB_NO_SOUND);
|
|
|
|
// Setup "None" card slot
|
|
strcpy(Cards[Num_cards].name, no_sound_msg);
|
|
Cards[Num_cards].mixers=0;
|
|
Cards[Num_cards].pguid=NULL;
|
|
memset( &Cards[Num_cards].guid, 0, sizeof(GUID) );
|
|
Num_cards++;
|
|
|
|
if (really_detect) {
|
|
check_direct_sound();
|
|
}
|
|
}
|
|
|
|
void CAudioTab::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CAudioTab)
|
|
DDX_Control(pDX, IDC_LAUNCHER_SND_CHECK, m_LauncherSndCheck);
|
|
DDX_Control(pDX, IDC_AUDIO_LIST, m_audio_list);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CAudioTab, CPropertyPage)
|
|
//{{AFX_MSG_MAP(CAudioTab)
|
|
ON_BN_CLICKED(IDC_BTN_AUDIO_DETECT, OnBtnAudioDetect)
|
|
ON_CBN_SELCHANGE(IDC_AUDIO_LIST, OnSelchangeAudioList)
|
|
ON_WM_HELPINFO()
|
|
ON_MESSAGE(WM_COMMANDHELP,OnCommandHelp)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CAudioTab message handlers
|
|
|
|
void CAudioTab::OnBtnAudioDetect()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
int i;
|
|
|
|
// Set the wait cursor
|
|
CWaitCursor wc;
|
|
|
|
// Display the scanning window
|
|
m_MsgDlg.m_ScanningMsg.LoadString(IDS_AUDIOTAB_SCANNING);
|
|
m_MsgDlg.m_WaitMsg.LoadString(IDS_PLEASE_WAIT_MSG);
|
|
m_MsgDlg.Create(IDD_MSG_DLG,this);
|
|
m_MsgDlg.ShowWindow(SW_SHOW);
|
|
m_MsgDlg.UpdateData(FALSE);
|
|
|
|
m_audio_list.ResetContent();
|
|
detect_sound_cards(1);
|
|
|
|
// Remove the scanning window
|
|
m_MsgDlg.DestroyWindow();
|
|
|
|
for (i=0; i<Num_cards; i++)
|
|
m_audio_list.InsertString(i, Cards[i].name);
|
|
|
|
// Set selection and available mixer settings
|
|
m_audio_list.SetCurSel(Num_cards - 1);
|
|
EnableMixerSettings(Cards[Num_cards-1].mixers);
|
|
|
|
// Automatically default to software (if available)
|
|
SetMixerButton(DetermineDefaultMixer(Num_cards-1),Cards[Num_cards-1].mixers);
|
|
}
|
|
|
|
void CAudioTab::OnOK()
|
|
{
|
|
bool ds16_supported;
|
|
|
|
int current = m_audio_list.GetCurSel();
|
|
|
|
if ((current < 0) || (current >= Num_cards)) {
|
|
current = 0;
|
|
}
|
|
|
|
// See if the chosen card supports direct sound 16 bit
|
|
if(Cards[current].mixers & DS16BIT_MIXER)
|
|
ds16_supported=TRUE;
|
|
else
|
|
ds16_supported=FALSE;
|
|
|
|
os_config_write_string(szSectionName, "SoundcardName", Cards[current].name);
|
|
|
|
int mixer_id;
|
|
mixer_id=GetMixerButton();
|
|
|
|
// For Chris, make DS8 be the mixer if user has a card selected
|
|
// (other than No sound) and no sound mixers could be detected for
|
|
// the device
|
|
if(current>0 && mixer_id==SOUND_MIXER_NONE)
|
|
mixer_id=SOUND_MIXER_DS_8;
|
|
|
|
// If user has ds16 support, and has chosen direct sound, use it
|
|
if(mixer_id==SOUND_MIXER_DS_8 && ds16_supported)
|
|
mixer_id=SOUND_MIXER_DS_16;
|
|
|
|
// Write out the default mixer
|
|
os_config_write_uint(NULL, "SoundMixer", mixer_id);
|
|
|
|
// Write out the Launcher sound setting
|
|
LauncherSoundEnabled=m_LauncherSndCheck.GetCheck();
|
|
os_config_write_uint(szSectionName, "LauncherSoundEnabled", LauncherSoundEnabled);
|
|
|
|
CPropertyPage::OnOK();
|
|
}
|
|
|
|
BOOL CAudioTab::OnInitDialog()
|
|
{
|
|
CPropertyPage::OnInitDialog();
|
|
|
|
// TODO: Add extra initialization here
|
|
char *current_card;
|
|
int i, current;
|
|
int allow_user_to_choose_ds3d = 0;
|
|
UINT mixer_id;
|
|
|
|
// Set the wait cursor
|
|
CWaitCursor wc;
|
|
|
|
// Clear the box
|
|
m_audio_list.ResetContent();
|
|
|
|
// Display the scanning window
|
|
m_MsgDlg.m_ScanningMsg.LoadString(IDS_AUDIOTAB_SCANNING);
|
|
m_MsgDlg.m_WaitMsg.LoadString(IDS_PLEASE_WAIT_MSG);
|
|
m_MsgDlg.Create(IDD_MSG_DLG,this);
|
|
m_MsgDlg.ShowWindow(SW_SHOW);
|
|
m_MsgDlg.UpdateData(FALSE);
|
|
|
|
// Detect all cards and fill the list
|
|
detect_sound_cards(1);
|
|
for (i=0; i<Num_cards; i++)
|
|
m_audio_list.InsertString(i, Cards[i].name);
|
|
|
|
// Remove the scanning window
|
|
m_MsgDlg.DestroyWindow();
|
|
|
|
// Get current card name from the registry
|
|
current_card = os_config_read_string(szSectionName, "SoundcardName", NULL);
|
|
|
|
// Get the currently selected mixer
|
|
mixer_id = os_config_read_uint(NULL, "SoundMixer", SOUND_MIXER_NONE);
|
|
|
|
current=-1;
|
|
if (current_card) {
|
|
i = m_audio_list.FindStringExact(-1, current_card);
|
|
if (i != CB_ERR)
|
|
current = i;
|
|
else {
|
|
// User's selected card could not be detected!
|
|
CString card_missing_msg, title_msg;
|
|
card_missing_msg.Format(IDS_AUDIOTAB_CARD_MISSING,current_card);
|
|
title_msg.LoadString(IDS_AUDIOTAB_WARNING);
|
|
MessageBox(card_missing_msg,title_msg, MB_OK | MB_ICONEXCLAMATION );
|
|
}
|
|
}
|
|
else if (Num_cards>0) {
|
|
current=0;
|
|
}
|
|
|
|
if (current < 0) {
|
|
current = Num_cards - 1;
|
|
mixer_id=DetermineDefaultMixer(current);
|
|
}
|
|
|
|
// If it's the first time since install, autodetect the best card
|
|
if(theApp.m_straight_to_setup) {
|
|
current=DetermineBestCard();
|
|
mixer_id=DetermineDefaultMixer(current);
|
|
}
|
|
|
|
// Set the current selection and available mixers
|
|
m_audio_list.SetCurSel(current);
|
|
EnableMixerSettings(Cards[current].mixers);
|
|
|
|
SetMixerButton(mixer_id,Cards[current].mixers);
|
|
|
|
// Set the Launcher sound check button if necessary
|
|
LauncherSoundEnabled = os_config_read_uint(szSectionName, "LauncherSoundEnabled", 1);
|
|
m_LauncherSndCheck.SetCheck(LauncherSoundEnabled);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
|
|
void CAudioTab::OnSelchangeAudioList()
|
|
{
|
|
// TODO: Add your control notification handler code here
|
|
int index;
|
|
index=m_audio_list.GetCurSel();
|
|
if(index!=CB_ERR && index<Num_cards) {
|
|
EnableMixerSettings(Cards[index].mixers);
|
|
|
|
// Automatically default to software (if available)
|
|
SetMixerButton(DetermineDefaultMixer(index),Cards[index].mixers);
|
|
}
|
|
}
|
|
|
|
|
|
// Determine the sound card with the most available mixers (for auto-detection)
|
|
int CAudioTab::DetermineBestCard(void)
|
|
{
|
|
int card_pos=0;
|
|
int j;
|
|
|
|
for(j=0;j<Num_cards;j++)
|
|
if(Cards[j].mixers >= Cards[card_pos].mixers) card_pos=j;
|
|
|
|
return(card_pos);
|
|
}
|
|
|
|
|
|
// Enables/disables mixer options according to given mixer flags
|
|
void CAudioTab::EnableMixerSettings(UINT mixers)
|
|
{
|
|
HWND hwnd;
|
|
|
|
GetDlgItem(IDC_MIXER_SOFTWARE,&hwnd);
|
|
::EnableWindow(hwnd, mixers & SOFTWARE_MIXER);
|
|
|
|
GetDlgItem(IDC_MIXER_DS8BIT,&hwnd);
|
|
::EnableWindow(hwnd, mixers & DS8BIT_MIXER);
|
|
|
|
/* We're not handling directsound 8 or 16 visually anymore
|
|
GetDlgItem(IDC_MIXER_DS16BIT,&hwnd);
|
|
::EnableWindow(hwnd, mixers & DS16BIT_MIXER);
|
|
*/
|
|
|
|
GetDlgItem(IDC_MIXER_DS3D,&hwnd);
|
|
::EnableWindow(hwnd, mixers & DS3D_MIXER);
|
|
|
|
GetDlgItem(IDC_MIXER_EAX,&hwnd);
|
|
::EnableWindow(hwnd, mixers & EAX_MIXER);
|
|
}
|
|
|
|
// selects the radio button corresponding to given registry ID
|
|
void CAudioTab::SetMixerButton(int mixer_id, UINT mixer_flags)
|
|
{
|
|
// Turn them all off
|
|
((CButton *) GetDlgItem(IDC_MIXER_SOFTWARE))->SetCheck(0);
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS16BIT))->SetCheck(0);
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS8BIT))->SetCheck(0);
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS3D))->SetCheck(0);
|
|
((CButton *) GetDlgItem(IDC_MIXER_EAX))->SetCheck(0);
|
|
|
|
// Now, check the appropriate one
|
|
switch(mixer_id) {
|
|
case SOUND_MIXER_SOFTWARE_16:
|
|
if(mixer_flags & SOFTWARE_MIXER)
|
|
((CButton *) GetDlgItem(IDC_MIXER_SOFTWARE))->SetCheck(1);
|
|
break;
|
|
|
|
// Now set and DS mixer to Default
|
|
case SOUND_MIXER_DS_16:
|
|
if(mixer_flags & DS16BIT_MIXER)
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS8BIT))->SetCheck(1);
|
|
break;
|
|
|
|
case SOUND_MIXER_DS_8:
|
|
if(mixer_flags & DS8BIT_MIXER)
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS8BIT))->SetCheck(1);
|
|
break;
|
|
|
|
case SOUND_MIXER_DS3D_16:
|
|
if(mixer_flags & DS3D_MIXER)
|
|
((CButton *) GetDlgItem(IDC_MIXER_DS3D))->SetCheck(1);
|
|
break;
|
|
case SOUND_MIXER_EAX:
|
|
if(mixer_flags & EAX_MIXER)
|
|
((CButton *) GetDlgItem(IDC_MIXER_EAX))->SetCheck(1);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Returns the registry ID for the selected radio button
|
|
int CAudioTab::GetMixerButton(void)
|
|
{
|
|
int mixer_id=SOUND_MIXER_NONE;
|
|
|
|
if ( ((CButton *) GetDlgItem(IDC_MIXER_SOFTWARE))->GetCheck() == 1 )
|
|
mixer_id=SOUND_MIXER_SOFTWARE_16;
|
|
/*
|
|
else if ( ((CButton *) GetDlgItem(IDC_MIXER_DS16BIT))->GetCheck() == 1 )
|
|
mixer_id=SOUND_MIXER_DS_16;
|
|
*/
|
|
else if ( ((CButton *) GetDlgItem(IDC_MIXER_DS8BIT))->GetCheck() == 1 )
|
|
mixer_id=SOUND_MIXER_DS_8;
|
|
else if ( ((CButton *) GetDlgItem(IDC_MIXER_DS3D))->GetCheck() == 1 )
|
|
mixer_id=SOUND_MIXER_DS3D_16;
|
|
else if ( ((CButton *) GetDlgItem(IDC_MIXER_EAX))->GetCheck() == 1 )
|
|
mixer_id=SOUND_MIXER_EAX;
|
|
|
|
return(mixer_id);
|
|
}
|
|
|
|
// Returns the default mixer for a given card index
|
|
UINT CAudioTab::DetermineDefaultMixer(int card_index)
|
|
{
|
|
int mixer_type;
|
|
|
|
// make 8 bit direct sound the generic default
|
|
mixer_type=SOUND_MIXER_DS_8;
|
|
|
|
// make sure index is valid
|
|
if(card_index<0 || card_index>=Num_cards)
|
|
return(mixer_type);
|
|
|
|
// if mixer supports software, make it the default
|
|
if(Cards[card_index].mixers & SOFTWARE_MIXER)
|
|
mixer_type=SOUND_MIXER_SOFTWARE_16;
|
|
|
|
return(mixer_type);
|
|
}
|
|
|
|
// Display the html help file
|
|
BOOL CAudioTab::OnHelpInfo(HELPINFO* pHelpInfo)
|
|
{
|
|
#ifdef USE_HTML_HELP_SYSTEM
|
|
CWaitCursor wc;
|
|
help_launch(AUDIOTAB_HELP);
|
|
return 1;
|
|
#else
|
|
return CPropertyPage::OnHelpInfo(pHelpInfo);
|
|
#endif
|
|
}
|
|
|
|
// Display the html help file
|
|
afx_msg LRESULT CAudioTab::OnCommandHelp(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#ifdef USE_HTML_HELP_SYSTEM
|
|
help_launch(AUDIOTAB_HELP);
|
|
return 1;
|
|
#else
|
|
return CPropertyPage::OnCommandHelp(wParam,lParam);
|
|
#endif
|
|
}
|
|
|