mirror of
https://github.com/celisej567/mcpe.git
synced 2026-09-04 19:36:43 +03:00
Improve and fix crash in SoundSystemWindows
Add 3D Sound Listener, Fix crash when DirectSound fails to initialize. Add second argument to setListenerAngle. Implement setListenerAngle and setListenerPos in Minecraft.cpp (Is this a good place to put it?)
This commit is contained in:
@@ -46,7 +46,19 @@ SoundSystemWindows::SoundSystemWindows()
|
||||
printf("SoundSystemWindows failed to create primary sound buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_listener = (LPDIRECTSOUND3DLISTENER8*)calloc(1, sizeof(LPDIRECTSOUND3DLISTENER8));
|
||||
|
||||
result = m_primarybuffer->QueryInterface(IID_IDirectSound3DListener8,
|
||||
(LPVOID*)m_listener);
|
||||
m_primarybuffer->Release();
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
printf("SoundSystemWindows failed to create 3D listener\n");
|
||||
}
|
||||
|
||||
m_available = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,23 +66,57 @@ SoundSystemWindows::SoundSystemWindows()
|
||||
SoundSystemWindows::~SoundSystemWindows()
|
||||
{
|
||||
printf("Destroying SoundSystemWindows\n");
|
||||
|
||||
if (!isAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_directsound->Release();
|
||||
|
||||
//Delete sounds (Releasing directsound releases sounds for us)
|
||||
for (size_t i = 0; i < m_buffers.size(); i++)
|
||||
{
|
||||
delete m_buffers[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool SoundSystemWindows::isAvailable()
|
||||
{
|
||||
return false;
|
||||
return m_available;
|
||||
}
|
||||
|
||||
void SoundSystemWindows::setListenerPos(float x, float y, float z)
|
||||
{
|
||||
|
||||
if (!isAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
(*m_listener)->SetPosition(x, y, -z, DS3D_IMMEDIATE);
|
||||
}
|
||||
|
||||
void SoundSystemWindows::setListenerAngle(float f)
|
||||
{
|
||||
|
||||
void SoundSystemWindows::setListenerAngle(float degyaw, float degpitch)
|
||||
{
|
||||
if (!isAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float yaw = degyaw * M_PI / 180.f;
|
||||
float pitch = degpitch * M_PI / 180.f;
|
||||
|
||||
float lx = cosf(pitch) * sinf(yaw);
|
||||
float ly = -sinf(pitch);
|
||||
float lz = cosf(yaw);
|
||||
|
||||
float ux = sinf(pitch) * sinf(yaw);
|
||||
float uy = cosf(pitch);
|
||||
float uz = sinf(pitch) * cosf(yaw);
|
||||
|
||||
(*m_listener)->SetOrientation(-lx,-ly,-lz, ux,uy,uz, DS3D_IMMEDIATE);
|
||||
}
|
||||
|
||||
void SoundSystemWindows::load(const std::string& sound)
|
||||
@@ -92,6 +138,11 @@ void SoundSystemWindows::stop(const std::string& sound)
|
||||
|
||||
void SoundSystemWindows::playAt(const SoundDesc& sound, float x, float y, float z, float volume, float pitch)
|
||||
{
|
||||
//Directsound failed to initialize return to avoid crash.
|
||||
if (!isAvailable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Release sounds that finished playing
|
||||
for (size_t i = 0; i < m_buffers.size(); i++)
|
||||
@@ -110,7 +161,8 @@ void SoundSystemWindows::playAt(const SoundDesc& sound, float x, float y, float
|
||||
unsigned char* bufferPtr;
|
||||
unsigned long bufferSize;
|
||||
|
||||
int length = sound.m_pHeader->m_length*sizeof(uint16_t);
|
||||
int length = sound.m_pHeader->m_length * sound.m_pHeader->m_bytes_per_sample;
|
||||
bool is2D = sqrtf(x * x + y * y + z * z) == 0.f;
|
||||
|
||||
LPDIRECTSOUNDBUFFER* soundbuffer = (LPDIRECTSOUNDBUFFER*)calloc(1, sizeof(LPDIRECTSOUNDBUFFER));
|
||||
|
||||
@@ -126,10 +178,14 @@ void SoundSystemWindows::playAt(const SoundDesc& sound, float x, float y, float
|
||||
// Set the buffer description of the secondary sound buffer that the wave file will be loaded onto.
|
||||
DSBUFFERDESC bufferDesc;
|
||||
bufferDesc.dwSize = sizeof(DSBUFFERDESC);
|
||||
if (sound.m_header.m_channels == 1) {
|
||||
|
||||
//Because directsound does not support DSBCAPS_CTRL3D on a sound with 2 channels we can only do it on sounds with 1 channel
|
||||
if (sound.m_header.m_channels == 1)
|
||||
{
|
||||
bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRL3D;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
bufferDesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
|
||||
}
|
||||
|
||||
@@ -150,7 +206,7 @@ void SoundSystemWindows::playAt(const SoundDesc& sound, float x, float y, float
|
||||
result = tempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)soundbuffer);
|
||||
if (FAILED(result))
|
||||
{
|
||||
printf("SoundSystemWindows QueryInterface failed\n");
|
||||
printf("SoundSystemWindows tempBuffer QueryInterface failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,6 +259,32 @@ void SoundSystemWindows::playAt(const SoundDesc& sound, float x, float y, float
|
||||
}
|
||||
(*soundbuffer)->SetVolume(LONG(attenuation));
|
||||
|
||||
//Check if position is not 0,0,0 and for mono to play 3D sound
|
||||
if (!is2D && sound.m_pHeader->m_channels == 1)
|
||||
{
|
||||
LPDIRECTSOUND3DBUFFER8 object3d;
|
||||
|
||||
HRESULT hr = (*soundbuffer)->QueryInterface(IID_IDirectSound3DBuffer8,
|
||||
(LPVOID*)&object3d);
|
||||
if (FAILED(hr)) {
|
||||
printf("SoundSystemWindows QueryInterface failed for 3D Object\n");
|
||||
return;
|
||||
}
|
||||
|
||||
D3DVECTOR listenerpos;
|
||||
(*m_listener)->GetPosition(&listenerpos);
|
||||
|
||||
object3d->SetPosition(
|
||||
x,
|
||||
y,
|
||||
-z,
|
||||
DS3D_IMMEDIATE);
|
||||
|
||||
//Im not really sure what values original MCPE would use.
|
||||
object3d->SetMinDistance(0.f, DS3D_IMMEDIATE);
|
||||
object3d->SetMaxDistance(100.f, DS3D_IMMEDIATE);
|
||||
}
|
||||
|
||||
(*soundbuffer)->Play(0, 0, 0);
|
||||
m_buffers.push_back(soundbuffer);
|
||||
}
|
||||
}
|
||||
@@ -30,16 +30,16 @@ public:
|
||||
~SoundSystemWindows();
|
||||
virtual bool isAvailable();
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float f);
|
||||
virtual void setListenerAngle(float yaw, float pitch);
|
||||
virtual void load(const std::string& sound);
|
||||
virtual void play(const std::string& sound);
|
||||
virtual void pause(const std::string& sound);
|
||||
virtual void stop(const std::string& sound);
|
||||
virtual void playAt(const SoundDesc& sound, float x, float y, float z, float a, float b);
|
||||
private:
|
||||
bool m_available = false;
|
||||
IDirectSound8* m_directsound;
|
||||
IDirectSoundBuffer* m_primarybuffer;
|
||||
|
||||
LPDIRECTSOUND3DLISTENER8* m_listener;
|
||||
std::vector<LPDIRECTSOUNDBUFFER*> m_buffers;
|
||||
};
|
||||
|
||||
};
|
||||
@@ -527,6 +527,15 @@ void Minecraft::tick()
|
||||
{
|
||||
m_pTextures->tick();
|
||||
m_pParticleEngine->tick();
|
||||
|
||||
#ifndef ORIGINAL_CODE
|
||||
if (m_pMobPersp)
|
||||
{
|
||||
m_pSoundEngine->m_soundSystem.setListenerPos(m_pMobPersp->m_pos.x, m_pMobPersp->m_pos.y, m_pMobPersp->m_pos.z);
|
||||
m_pSoundEngine->m_soundSystem.setListenerAngle(m_pMobPersp->m_yaw, m_pMobPersp->m_pitch);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
if (field_D14)
|
||||
|
||||
@@ -17,9 +17,15 @@ void SoundSystem::setListenerPos(float x, float y, float z)
|
||||
{
|
||||
}
|
||||
|
||||
void SoundSystem::setListenerAngle(float f)
|
||||
#ifndef ORIGINAL_CODE
|
||||
void SoundSystem::setListenerAngle(float yaw, float pitch)
|
||||
{
|
||||
}
|
||||
#else
|
||||
void SoundSystem::setListenerAngle(float yaw)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void SoundSystem::load(const std::string& sound)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,11 @@ class SoundSystem
|
||||
public:
|
||||
virtual bool isAvailable();
|
||||
virtual void setListenerPos(float x, float y, float z);
|
||||
virtual void setListenerAngle(float f);
|
||||
#ifndef ORIGINAL_CODE
|
||||
virtual void setListenerAngle(float yaw, float pitch);
|
||||
#else
|
||||
virtual void setListenerAngle(float yaw);
|
||||
#endif
|
||||
virtual void load(const std::string& sound);
|
||||
virtual void play(const std::string& sound);
|
||||
virtual void pause(const std::string& sound);
|
||||
|
||||
Reference in New Issue
Block a user