mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-23 12:08:56 +00:00
841 lines
23 KiB
C++
841 lines
23 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
|
|
|
|
struct SoundCard {
|
|
GUID guid;
|
|
LPGUID pguid;
|
|
|
|
char name[1024]; // Name of the device
|
|
UINT mixers; // Mixers supported by device
|
|
};
|
|
|
|
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
|
|
}
|