diff options
author | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
---|---|---|
committer | Ash Wolf <ninji@wuffs.org> | 2023-06-28 22:22:32 +0100 |
commit | c0c336500955a23e344651e5412c9d9d441ef4ee (patch) | |
tree | 790769c748db307cf3314f6e896e2f61c68561a2 /src/T2DLL/T2SoundPlayer.cpp | |
parent | 37e364b2c6cc7487a1c888d256a73e5337bb7189 (diff) | |
download | t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.tar.gz t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.zip |
first pass of T2DLL
Diffstat (limited to '')
-rw-r--r-- | src/T2DLL/T2SoundPlayer.cpp | 427 |
1 files changed, 408 insertions, 19 deletions
diff --git a/src/T2DLL/T2SoundPlayer.cpp b/src/T2DLL/T2SoundPlayer.cpp index 7abc2a6..8c06ec9 100644 --- a/src/T2DLL/T2SoundPlayer.cpp +++ b/src/T2DLL/T2SoundPlayer.cpp @@ -1,74 +1,463 @@ +#include "GlobalFunc.h" #include "T2SoundPlayer.h" +#include "T2TowerDoc.h" +#include "T2TowerMainView.h" +#include "Wave.h" -/*static*/ const AFX_MSGMAP* __stdcall T2SoundPlayer::_GetBaseMessageMap() { -} +BEGIN_MESSAGE_MAP(T2SoundPlayer, CWnd) + ON_MESSAGE(MM_MCINOTIFY, OnMCINotify) +END_MESSAGE_MAP() -/*virtual*/ const AFX_MSGMAP* T2SoundPlayer::GetMessageMap() const { -} +T2SoundPlayer::T2SoundPlayer(CWnd* inParentWnd, IDirectSound* inDirectSound) { + mDirectSound = inDirectSound; + mItemList = new T2SoundObjItemList; + mCurrentCDTrack = 0; + + MCI_OPEN_PARMS mciParms; + memset(&mciParms, 0, sizeof(mciParms)); + + mciParms.lpstrDeviceType = (LPSTR) MCI_DEVTYPE_CD_AUDIO; + + CString theName; + theName.Format("%s:", GetInstallSourceDrive()); + CString theAlias; + theAlias = "T2CD"; -T2SoundPlayer::T2SoundPlayer(CWnd*, IDirectSound*) { + mciParms.lpstrElementName = theName; + mciParms.lpstrAlias = theAlias; + + mciSendCommand(0, MCI_OPEN, MCI_WAIT | MCI_OPEN_SHAREABLE | MCI_OPEN_ELEMENT | MCI_OPEN_ALIAS | MCI_OPEN_TYPE_ID | MCI_OPEN_TYPE, (DWORD) &mciParms); + + CRect rect(0, 0, 1, 1); + CString theClass = AfxRegisterWndClass(CS_NOCLOSE); + + Create(theClass, "", WS_CHILD, rect, inParentWnd, 9999); + + mSEMask = 0xFFFFFFFF; + mIsSoundOn = true; + mIsFadeOut = false; } /*virtual*/ T2SoundPlayer::~T2SoundPlayer() { + StopCD(); + + CString cmd; + cmd.Format("close %s", "T2CD"); + mciSendString(cmd, NULL, 0, NULL); + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + DeleteSound(item->mName); + } + + delete mItemList; } -void T2SoundPlayer::AddSound(const CString&, SOUNDPRIORITY, const CString&) { +void T2SoundPlayer::AddSound(const CString& inName, SOUNDPRIORITY inPriority, const CString& inPath) { + if (!mDirectSound) + return; + + T2SoundObjItem *item = new T2SoundObjItem; + CWave wave(inPath); + + if (LoadSound(item, inName, wave, false)) { + item->mSourceKind = T2SoundObjItem::FileSource; + item->mPath = inPath; + item->mPriority = inPriority; + mItemList->AddTail(item); + } else { + delete item; + } } -void T2SoundPlayer::AddSound(const CString&, SOUNDPRIORITY, unsigned int, HINSTANCE) { +void T2SoundPlayer::AddSound(const CString& inName, SOUNDPRIORITY inPriority, unsigned int inResID, HINSTANCE inModule) { + if (!mDirectSound) + return; + + if (FindResource(inModule, MAKEINTRESOURCE(inResID), "WAVE")) { + T2SoundObjItem *item = new T2SoundObjItem; + CWave wave(inResID, inModule); + + if (LoadSound(item, inName, wave, false)) { + item->mSourceKind = T2SoundObjItem::ResSource; + item->mResID = inResID; + item->mModuleHandle = inModule; + item->mPriority = inPriority; + mItemList->AddTail(item); + } else { + delete item; + } + } } -int T2SoundPlayer::LoadSound(T2SoundObjItem*, const CString&, CWave&, int) { +BOOL T2SoundPlayer::LoadSound(T2SoundObjItem* inItem, const CString& inName, CWave& inWave, BOOL inReloadFlag) { + if (!inReloadFlag) { + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + if (item->mName == inName) + return false; + } + } + + inItem->mName = inName; + + BYTE *waveDataPtr; + DWORD waveDataLength = inWave.GetDataLen(); + + WAVEFORMATEX waveFormat; + inWave.GetFormat(waveFormat); + + DSBUFFERDESC desc; + memset(&desc, 0, sizeof(DSBUFFERDESC)); + desc.dwSize = sizeof(DSBUFFERDESC); + desc.dwFlags = DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLDEFAULT; + desc.dwBufferBytes = waveDataLength; + desc.lpwfxFormat = &waveFormat; + + mDirectSound->CreateSoundBuffer(&desc, &inItem->mDSBuffers[0], NULL); + + inItem->mDSBuffers[0]->Lock(0, waveDataLength, &waveDataPtr, &waveDataLength, NULL, NULL, 0); + waveDataLength = inWave.GetData(waveDataPtr, waveDataLength); + inItem->mDSBuffers[0]->Unlock(waveDataPtr, waveDataLength, NULL, 0); + + inItem->mPlayedAt[0] = GetTickCount(); + + for (int i = 1; i < 4; i++) { + mDirectSound->DuplicateSoundBuffer(inItem->mDSBuffers[0], &inItem->mDSBuffers[i]); + inItem->mPlayedAt[i] = GetTickCount(); + } + + return true; } -void T2SoundPlayer::DeleteSound(const CString&) { +void T2SoundPlayer::DeleteSound(const CString& inName) { + if (!mDirectSound) + return; + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + POSITION prev = pos; + T2SoundObjItem *item = mItemList->GetNext(pos); + + if (item->mName == inName) { + mItemList->RemoveAt(prev); + for (int i = 3; i >= 0; i--) { + if (item->mDSBuffers[i]) + item->mDSBuffers[i]->Release(); + } + + delete item; + break; + } + } } void T2SoundPlayer::DeleteSoundAll() { + if (!mDirectSound) + return; + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + DeleteSound(item->mName); + } + + mItemList->RemoveAll(); } -void T2SoundPlayer::Play(const CString&, unsigned int, unsigned int, POINT*, PLAYMODE, int) { +void T2SoundPlayer::Play(const CString& inName, unsigned int inMask, unsigned int inFlags, POINT* inPt, PLAYMODE inPlayMode, int inVolume) { + if (!mDirectSound) + return; + + if (!mIsSoundOn || (inMask & mSEMask) == 0) + return; + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + if (item->mName == inName) { + DWORD currentStatus; + int index; + + if (inPlayMode == PlayMode_0 || inPlayMode == PlayMode_1 || inPlayMode == PlayMode_3) { + index = 0; + } else if (inPlayMode == PlayMode_2) { + for (index = 0; index < 4; index++) { + item->mDSBuffers[index]->GetStatus(¤tStatus); + if (!(currentStatus & DSBSTATUS_PLAYING)) + break; + } + + if (index == 4) { + // all slots full, pick the oldest sound to replace + DWORD oldest = GetTickCount(); + index = 0; + for (int i = 0; i < 4; i++) { + if (item->mPlayedAt[i] < oldest) { + index = i; + oldest = item->mPlayedAt[i]; + } + } + } + } + + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_BUFFERLOST) { + for (int i = 3; i >= 0; i--) + item->mDSBuffers[i]->Restore(); + + CWave *wave; + if (item->mSourceKind == T2SoundObjItem::FileSource) + wave = new CWave(item->mPath); + else + wave = new CWave(item->mResID, item->mModuleHandle); + + LoadSound(item, item->mName, *wave, true); + } + + int pan = 0; + if (inPt) { + CRect rect; + GetCurrentT2TowerDoc()->GetTowerMainView()->tmv_vf140(rect); + + POINT centerPt = rect.CenterPoint(); + float x = ((float) (inPt->x - centerPt.x) / (float) ((rect.right - rect.left) / 2)); + x *= 0.5; + if (x < 0.0) + pan = -10000.0f * -x; + else + pan = 10000.0f * x; + } + + BOOL play = false; + if (inPlayMode == PlayMode_0 || inPlayMode == PlayMode_3) { + if (!(currentStatus & DSBSTATUS_PLAYING)) + play = true; + } else if (inPlayMode == PlayMode_1 || inPlayMode == PlayMode_2) { + if (currentStatus & DSBSTATUS_PLAYING) { + item->mDSBuffers[index]->Stop(); + item->mDSBuffers[index]->SetCurrentPosition(0); + } + play = true; + } + + if (play) { + int volume = ((inVolume * 10000) / 100) - 10000; + if (!mIsFadeOut || (inFlags & SoundFlags_10000)) + item->mDSBuffers[index]->SetVolume(volume); + else + item->mDSBuffers[index]->SetVolume(-10000); + + item->mDSBuffers[index]->SetPan(pan); + item->mDSBuffers[index]->Play(0, 0, inPlayMode == PlayMode_3); + } + + item->mPlayedAt[index] = GetTickCount(); + break; + } + } } -void T2SoundPlayer::Stop(const CString&) { +void T2SoundPlayer::Stop(const CString& inName) { + if (!mDirectSound) + return; + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + + if (item->mName == inName) { + for (int index = 0; index < 4; index++) { + DWORD currentStatus; + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) { + item->mDSBuffers[index]->Stop(); + item->mDSBuffers[index]->SetCurrentPosition(0); + } + } + } + } } void T2SoundPlayer::StopAll() { + if (!mDirectSound) + return; + + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + + for (int index = 0; index < 4; index++) { + DWORD currentStatus; + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) { + item->mDSBuffers[index]->Stop(); + item->mDSBuffers[index]->SetCurrentPosition(0); + } + } + } } -void T2SoundPlayer::SetVolume(const CString&, int) { +void T2SoundPlayer::SetVolume(const CString& inName, int inVolume) { + if (!mDirectSound) + return; + + int volume = ((inVolume * 10000) / 100) - 10000; + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + + if (item->mName == inName) { + for (int index = 0; index < 4; index++) { + DWORD currentStatus; + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) + item->mDSBuffers[index]->SetVolume(volume); + } + } + } } -void T2SoundPlayer::SetSoundOn(int) { +void T2SoundPlayer::SetSoundOn(BOOL inSoundOn) { + mIsSoundOn = inSoundOn; + + if (!inSoundOn) { + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + DWORD currentStatus; + + for (int index = 0; index < 4; index++) { + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) { + item->mDSBuffers[index]->Stop(); + item->mDSBuffers[index]->SetCurrentPosition(0); + } + } + } + } } void T2SoundPlayer::FadeOut() { + mIsFadeOut = true; + + DWORD time = GetTickCount(); + while (GetTickCount() == time) {} + + int i = 0; + while (i <= 10) { + int volume = 0 - ((i * 10000) / 10); + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + DWORD currentStatus; + + for (int index = 0; index < 4; index++) { + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) + item->mDSBuffers[index]->SetVolume(volume); + } + } + + time = GetTickCount(); + while ((GetTickCount() - time) < 50) { + MSG msg; + PeekMessage(&msg, NULL, 0, 0, 0); + } + + i++; + } } void T2SoundPlayer::FadeIn() { + mIsFadeOut = false; + + DWORD time = GetTickCount(); + while (GetTickCount() == time) {} + + int i = 0; + while (i <= 10) { + int volume = ((i * 10000) / 10) - 10000; + POSITION pos = mItemList->GetHeadPosition(); + while (pos) { + T2SoundObjItem *item = mItemList->GetNext(pos); + DWORD currentStatus; + + for (int index = 0; index < 4; index++) { + item->mDSBuffers[index]->GetStatus(¤tStatus); + + if (currentStatus & DSBSTATUS_PLAYING) + item->mDSBuffers[index]->SetVolume(volume); + } + } + + time = GetTickCount(); + while ((GetTickCount() - time) < 50) { + MSG msg; + PeekMessage(&msg, NULL, 0, 0, 0); + } + + i++; + } } -void T2SoundPlayer::PlayCDTrack(int, int) { +void T2SoundPlayer::PlayCDTrack(int inTrack, BOOL inFlag) { + if (inFlag) + mCurrentCDTrack = inTrack; + else + mCurrentCDTrack = 0; + + CString cmd; + cmd.Format("status %s length track %d", "T2CD", inTrack); + + char returnString[20]; + MCIERROR err = mciSendString(cmd, returnString, 20, NULL); + + cmd.Format("play %s from %02d:00:00:00 to %02d:%s notify", "T2CD", inTrack, inTrack, returnString); + err = mciSendString(cmd, NULL, 0, *this); } void T2SoundPlayer::StopCD() { -} + mCurrentCDTrack = 0; -long T2SoundPlayer::OnMCINotify(unsigned int, long) { + CString cmd; + cmd.Format("stop %s", "T2CD"); + mciSendString(cmd, NULL, 0, NULL); } -/*static*/ const AFX_MSGMAP T2SoundPlayer::messageMap { -} +LRESULT T2SoundPlayer::OnMCINotify(WPARAM wParam, LPARAM lParam) { + if (wParam == MCI_NOTIFY_SUCCESSFUL || wParam == MCI_NOTIFY_ABORTED) { + if (mCurrentCDTrack) + PlayCDTrack(mCurrentCDTrack, true); + } -/*static*/ const AFX_MSGMAP_ENTRY* const T2SoundPlayer::_messageEntries { + return 0; } + + T2SoundObjItem::T2SoundObjItem() { + mName = ""; + + for (int i = 0; i < 4; i++) { + mDSBuffers[i] = NULL; + mPlayedAt[i] = GetTickCount(); + } } T2SoundObjItem::~T2SoundObjItem() { } + + T2SoundObjItemList::T2SoundObjItemList() { } |