/* * ACM for Windows : an air combat simulator * Copyright (C) 1997 Web Simulations, Inc. * * This program is not free software, but you can redistribute it and/or * modify it under the terms of the Web Simulations End User License * dated September, 1997. A copy of this license may be found in the * LICENSE.TXT file. * * 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. * * Information describing how to contact the author can be found in the * README.TXT file. */ #include "stdafx.h" #include "acm.h" static CSoundManager *g_pSoundManager; static CStaticSoundBuffer *g_sound[NUM_SOUNDS]; #define SECTION "Sound" #define MAIN_SOUND_KEY "MainSounds" #define BACKGROUND_SOUND_KEY "BackgroundSounds" extern "C" { int WaveLoadFile( char *pszFileName, // (IN) UINT *cbSize, // (OUT) DWORD *pcSamples, // (OUT) WAVEFORMATEX **ppwfxInfo, // (OUT) BYTE **ppbData // (OUT) ); // These are glue routines to allow the original ACM code to call // the C++-based sound manager. // // borrowed from src/audio.c static char *files[] = { "engine.wav", "crash.wav", "gear_up.wav", "gear_dn.wav", "missile.wav", "cannon.wav", "crash.wav", "screetch.wav", "stall.wav", "rwr.wav", "apglock.wav" }; static BOOL bSoundsLoaded = FALSE; int initializeAudio(craft *c, viewer *v, char *p) { char szSoundPath[256]; int result = 0; if (bSoundsLoaded == FALSE) { bSoundsLoaded = TRUE; for (int i=0; iLoadWaveFile(szSoundPath) == FALSE) { TRACE(_T("Load of file \"%s\" failed\n"), szSoundPath); //delete g_sound[i]; //g_sound[i] = NULL; result = -2; } } } return result; } void shutdownAudio(craft *c, viewer *v) { } void playSound (craft *c, int id) { if (c->type == CT_PLANE) { g_sound[id]->SetCurrentPosition( 0 ); g_sound[id]->Play( FALSE ); } } void playContinuousSound (craft *c, int id) { if (c->type == CT_PLANE) { g_sound[id]->Play( TRUE ); c->vl->flow[id] = 1; } } void stopSound(craft *c, int id) { if (c->type == CT_PLANE) { g_sound[id]->Stop(); c->vl->flow[id] = 0; } } static int g_bEngineOn = 0; static double g_dLastRPM = 0.0; void setBackgroundSound (craft *c, double dThtlPercent, BOOL bABFlag, double dDynamicPressure) { BOOL bMain, bBackground; g_pSoundManager->GetSoundState (&bMain, &bBackground); if (bBackground && c->type == CT_PLANE) { if (g_bEngineOn == FALSE) { g_sound[SoundEngine]->SetVolume ( -3000 ); playContinuousSound ( c, SoundEngine ); g_bEngineOn = TRUE; } if (g_dLastRPM != c->rpm) { if (c->rpm == 0.0) { stopSound (c, SoundEngine); } else { //int dB = -40 + (int) (20.0 * c->rpm + 0.5); g_sound[SoundEngine]->SetFrequency ( (int) (c->rpm * 15000.0 + 0.5) ); } g_dLastRPM = c->rpm; } } } }; //******************************************************************* // // Now, back to C++ ... // //******************************************************************* CSoundManager::CSoundManager() { CAcmApp * pApp = (CAcmApp *) AfxGetApp(); m_lpDirectSound = NULL; m_hr = DS_OK; m_bMainSounds = pApp->GetProfileInt(SECTION, MAIN_SOUND_KEY, (int) TRUE); m_bBackgroundSounds = pApp->GetProfileInt(SECTION, BACKGROUND_SOUND_KEY, (int) TRUE); } CSoundManager::~CSoundManager() { StopBackgroundSounds(); StopMainSounds(); if (m_lpDirectSound) { m_lpDirectSound->Release(); m_lpDirectSound = NULL; } } BOOL CSoundManager::Create(void) { g_pSoundManager = this; if((m_hr = DirectSoundCreate(NULL, &m_lpDirectSound, NULL)) != DS_OK) { m_lpDirectSound = NULL; return FALSE; } if (AfxGetMainWnd()) { if (SetMainWindow() == FALSE) { return FALSE; } } return TRUE; } BOOL CSoundManager::SetMainWindow(CWnd *pWnd /* = NULL */) { if (pWnd == NULL) { pWnd = AfxGetMainWnd(); } if (m_lpDirectSound == NULL) { return FALSE; } ASSERT (pWnd); if ((m_hr = m_lpDirectSound->SetCooperativeLevel(pWnd->m_hWnd, DSSCL_NORMAL)) != DS_OK) { return FALSE; } return TRUE; } HRESULT CSoundManager::GetResultCode() { return m_hr; } CSoundBuffer::CSoundBuffer(CSoundManager *pSM /* = NULL */ ) { m_pSM = pSM; m_lpDPSB = NULL; ZeroMemory (&m_desc, sizeof(m_desc)); m_hr = DS_OK; } CSoundBuffer::~CSoundBuffer() { if (m_lpDPSB) { m_lpDPSB->Release(); m_lpDPSB = NULL; } } CStaticSoundBuffer::CStaticSoundBuffer(CSoundManager *pSM) : CSoundBuffer(pSM) { } BOOL CStaticSoundBuffer::LoadWaveFile(LPTSTR pFileName) { UINT size; unsigned char *pData; BYTE *pbData = NULL; BYTE *pbData2 = NULL; DWORD dwLength; DWORD dwLength2; if (m_pSM->m_lpDirectSound == NULL) { goto FAILURE; } if (WaveLoadFile(pFileName, &size, &m_dwSamples, &m_pFormat, &pData) != 0) { m_hr = DS_OK; goto FAILURE; } m_desc.dwSize = sizeof(DSBUFFERDESC); m_desc.dwFlags = 0; m_desc.dwFlags |= DSBCAPS_STATIC; m_desc.dwFlags |= DSBCAPS_CTRLDEFAULT | DSBCAPS_GETCURRENTPOSITION2; m_desc.dwFlags |= DSBCAPS_STICKYFOCUS; m_desc.dwBufferBytes = size; m_desc.lpwfxFormat = m_pFormat; if ((m_hr = m_pSM->m_lpDirectSound->CreateSoundBuffer( &m_desc, &m_lpDPSB, NULL )) != DS_OK) { goto FAILURE; } if ((m_hr = m_lpDPSB->Lock(0, size, &pbData, &dwLength, &pbData2, &dwLength2, 0L)) != DS_OK) { goto FAILURE; } ASSERT(pbData != NULL); memcpy(pbData, pData, size); // Ok, now unlock the buffer, we don't need it anymore. if ((m_hr = m_lpDPSB->Unlock( pbData, size, NULL, 0)) != DS_OK) { goto FAILURE; } pbData = NULL; // Set maximum volume (0 dB attenuation) and Mid-pan if ((m_hr = m_lpDPSB->SetVolume(0)) != DS_OK) { goto FAILURE; } if ((m_hr = m_lpDPSB->SetPan(0)) != DS_OK) { goto FAILURE; } return TRUE; FAILURE: if (m_lpDPSB && pbData) { m_lpDPSB->Unlock( pbData, size, NULL, 0); } if (m_lpDPSB) { m_lpDPSB->Release(); } m_lpDPSB = NULL; return FALSE; } BOOL CSoundBuffer::Play(BOOL bContinuous) { if (m_pSM->m_lpDirectSound == NULL) { return FALSE; } ASSERT (m_lpDPSB); m_hr = m_lpDPSB->Play( 0, 0, bContinuous ? DSBPLAY_LOOPING : 0 ); return (m_hr == DS_OK) ? TRUE : FALSE; } BOOL CSoundBuffer::Stop() { if (m_pSM->m_lpDirectSound == NULL) { return FALSE; } ASSERT (m_lpDPSB); if ((m_hr = m_lpDPSB->Stop()) != DS_OK) { return FALSE; } return TRUE; } HRESULT CSoundBuffer::GetResultCode() { return m_hr; } long CSoundBuffer::GetVolume() { if (m_pSM->m_lpDirectSound == NULL) { return 0; } long lResult = 0; ASSERT (m_lpDPSB); m_lpDPSB->GetVolume(&lResult); return lResult; } void CSoundBuffer::SetVolume(long lVol) { if (m_pSM->m_lpDirectSound == NULL) { return; } ASSERT (m_lpDPSB); m_lpDPSB->SetVolume(lVol); } DWORD CSoundBuffer::GetFrequency() { if (m_pSM->m_lpDirectSound == NULL) { return 0; } DWORD dwFreq; ASSERT (m_lpDPSB); m_lpDPSB->GetFrequency(&dwFreq); return dwFreq; } void CSoundBuffer::SetFrequency(DWORD dwFreq) { if (m_pSM->m_lpDirectSound == NULL) { return; } ASSERT (m_lpDPSB); m_lpDPSB->SetFrequency(dwFreq); } void CSoundBuffer::SetCurrentPosition(DWORD dwPos) { if (m_pSM->m_lpDirectSound == NULL) { return; } ASSERT (m_lpDPSB); m_lpDPSB->SetCurrentPosition(0); } void CSoundBuffer::GetStatus(DWORD * lpdwStatus) { if (m_pSM->m_lpDirectSound == NULL) { *lpdwStatus = 0; return; } ASSERT (m_lpDPSB); m_lpDPSB->GetStatus (lpdwStatus); } void CSoundManager::SetSoundState(BOOL bMain, BOOL bBackground) { CAcmApp * pApp = (CAcmApp *) AfxGetApp(); if (m_bBackgroundSounds == TRUE && bBackground == FALSE) { StopBackgroundSounds (); g_bEngineOn = FALSE; g_dLastRPM = 0.0; } if (m_bMainSounds == TRUE && bMain == FALSE) { StopMainSounds (); } m_bMainSounds = bMain; m_bBackgroundSounds = bBackground; pApp->WriteProfileInt(SECTION, MAIN_SOUND_KEY, (int) m_bMainSounds); pApp->WriteProfileInt(SECTION, BACKGROUND_SOUND_KEY, (int) m_bBackgroundSounds); } void CSoundManager::GetSoundState(BOOL * pbMain, BOOL * pbBackground) { ASSERT (pbMain); ASSERT (pbBackground); *pbMain = m_bMainSounds; *pbBackground = m_bBackgroundSounds; } void CSoundManager::StopMainSounds() { DWORD dwStatus; if (m_lpDirectSound == NULL) { return; } for (int i=0; iGetStatus(&dwStatus); if (dwStatus & DSBSTATUS_PLAYING) { g_sound[i]->Play( FALSE ); } } } } void CSoundManager::StopBackgroundSounds() { DWORD dwStatus; int i = SoundEngine; if (m_lpDirectSound == NULL) { return; } if (g_sound[i]) { g_sound[i]->GetStatus(&dwStatus); if (dwStatus & DSBSTATUS_PLAYING) { g_sound[i]->Play( FALSE ); } } }