summaryrefslogtreecommitdiff
path: root/src/T2DLL/T2SoundPlayer.cpp
diff options
context:
space:
mode:
authorAsh Wolf <ninji@wuffs.org>2023-06-28 22:22:32 +0100
committerAsh Wolf <ninji@wuffs.org>2023-06-28 22:22:32 +0100
commitc0c336500955a23e344651e5412c9d9d441ef4ee (patch)
tree790769c748db307cf3314f6e896e2f61c68561a2 /src/T2DLL/T2SoundPlayer.cpp
parent37e364b2c6cc7487a1c888d256a73e5337bb7189 (diff)
downloadt2win-c0c336500955a23e344651e5412c9d9d441ef4ee.tar.gz
t2win-c0c336500955a23e344651e5412c9d9d441ef4ee.zip
first pass of T2DLL
Diffstat (limited to '')
-rw-r--r--src/T2DLL/T2SoundPlayer.cpp427
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(&currentStatus);
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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(&currentStatus);
+
+ 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() {
}