void CALLBACK DownloadSync ( HSYNC handle, DWORD channel, DWORD data, void* user ) { CClientSound* pClientSound = static_cast <CClientSound*> ( user ); // Call onClientSoundFinishedDownload LUA event CLuaArguments Arguments; Arguments.PushNumber ( pClientSound->GetLength () ); pClientSound->CallEvent ( "onClientSoundFinishedDownload", Arguments, true ); }
int CLuaFunctionDefs::PlaySound3D ( lua_State* luaVM ) { SString strSound = ""; CVector vecPosition; CScriptArgReader argStream ( luaVM ); argStream.ReadString ( strSound ); argStream.ReadNumber ( vecPosition.fX ); argStream.ReadNumber ( vecPosition.fY ); argStream.ReadNumber ( vecPosition.fZ ); if ( !argStream.HasErrors() ) { CLuaMain * luaMain = m_pLuaManager->GetVirtualMachine ( luaVM ); if ( luaMain ) { CResource* pResource = luaMain->GetResource(); if ( pResource ) { SString strFilename; bool bIsURL = false; if ( CResourceManager::ParseResourcePathInput( strSound, pResource, strFilename ) ) strSound = strFilename; else bIsURL = true; // ParseResourcePathInput changes pResource in some cases e.g. an invalid resource URL - crun playSound( ":myNotRunningResource/music/track.mp3" ) // Fixes #6507 - Caz if ( pResource ) { bool bLoop = false; if ( argStream.NextIsBool ( ) ) { argStream.ReadBool ( bLoop ); } CClientSound* pSound = CStaticFunctionDefinitions::PlaySound3D ( pResource, strSound, bIsURL, vecPosition, bLoop ); if ( pSound ) { // call onClientSoundStarted CLuaArguments Arguments; Arguments.PushString ( "play" ); // Reason pSound->CallEvent ( "onClientSoundStarted", Arguments, false ); lua_pushelement ( luaVM, pSound ); return 1; } } } } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean ( luaVM, false ); return 1; }
CClientSound* CClientSoundManager::PlaySound2D ( void* pMemory, unsigned int uiLength, bool bLoop ) { CClientSound* pSound = new CClientSound ( m_pClientManager, INVALID_ELEMENT_ID ); if ( pSound->Play ( pMemory, uiLength, bLoop ) ) return pSound; delete pSound; return NULL; }
int CLuaFunctionDefs::GetSoundEffects ( lua_State* luaVM ) { CClientPlayer* pPlayer = NULL; CClientSound* pSound = NULL; CScriptArgReader argStream ( luaVM ); if ( argStream.NextIsUserDataOfType < CClientSound > ( ) ) { argStream.ReadUserData ( pSound ); } else if ( argStream.NextIsUserDataOfType < CClientPlayer > ( ) ) { argStream.ReadUserData ( pPlayer ); } else { m_pScriptDebugging->LogBadPointer ( luaVM, "sound/player", 1 ); lua_pushboolean ( luaVM, false ); return false; } if ( !argStream.HasErrors() ) { if ( pSound ) { std::map < std::string, int > iFxEffects = m_pManager->GetSoundManager()->GetFxEffects(); lua_newtable ( luaVM ); for ( std::map < std::string, int >::const_iterator iter = iFxEffects.begin(); iter != iFxEffects.end(); ++iter ) { lua_pushboolean ( luaVM, pSound->IsFxEffectEnabled ( (*iter).second ) ); lua_setfield ( luaVM, -2, (*iter).first.c_str () ); } return 1; } else if ( pPlayer ) { CClientPlayerVoice * pPlayerVoice = pPlayer->GetVoice ( ); std::map < std::string, int > iFxEffects = m_pManager->GetSoundManager()->GetFxEffects(); lua_newtable ( luaVM ); for ( std::map < std::string, int >::const_iterator iter = iFxEffects.begin(); iter != iFxEffects.end(); ++iter ) { lua_pushboolean ( luaVM, pPlayerVoice->IsFxEffectEnabled ( (*iter).second ) ); lua_setfield ( luaVM, -2, (*iter).first.c_str () ); } return 1; } } else m_pScriptDebugging->LogCustom ( luaVM, argStream.GetFullErrorMessage() ); lua_pushboolean ( luaVM, false ); return 1; }
CClientSound* CClientSoundManager::PlaySound3D ( void* pMemory, unsigned int uiLength, const CVector& vecPosition, bool bLoop ) { CClientSound* pSound = new CClientSound ( m_pClientManager, INVALID_ELEMENT_ID ); if ( pSound->Play3D ( pMemory, uiLength, bLoop ) ) { pSound->SetPosition ( vecPosition ); return pSound; } delete pSound; return NULL; }
// // Distance streaming like what is done with visible objects // void CClientSoundManager::UpdateDistanceStreaming ( const CVector& vecListenerPosition ) { // // Make a copy of the current list of sounds that are active // std::set < CClientSound* > considerMap = m_DistanceStreamedInMap; // // Mix in all sounds near enough to the listener to be heard // { // Find all entities overlapping the listener position CClientEntityResult result; GetClientSpatialDatabase()->SphereQuery ( result, CSphere( vecListenerPosition, 0 ) ); // Extract relevant types for ( CClientEntityResult::const_iterator iter = result.begin () ; iter != result.end (); ++iter ) { if ( CClientSound* pSound = DynamicCast < CClientSound > ( *iter ) ) { if ( pSound->IsSound3D() ) { // Add to consider map considerMap.insert ( pSound ); } } } } // // Step through each sound // If the sound is more than 40 units away (or in another dimension), make sure it is deactivated // If the sound is less than 20 units away, make sure it is activated // for ( std::set < CClientSound* >::iterator iter = considerMap.begin () ; iter != considerMap.end () ; ++iter ) { CClientSound* pSound = *iter; // Calculate distance to the edge of the sphere CSphere sphere = pSound->GetWorldBoundingSphere (); float fDistance = ( vecListenerPosition - sphere.vecPosition ).Length () - sphere.fRadius; if ( fDistance > 40 || m_usDimension != pSound->GetDimension () ) pSound->DistanceStreamOut (); else if ( fDistance < 20 ) pSound->DistanceStreamIn (); } }
CClientSound* CClientSoundManager::PlaySound2D ( const SString& strSound, bool bIsURL, bool bLoop ) { CClientSound* pSound = new CClientSound ( m_pClientManager, INVALID_ELEMENT_ID ); if ( bIsURL ) { pSound->PlayStream ( strSound, bLoop ); return pSound; } else if ( pSound->Play ( strSound, bLoop ) ) return pSound; delete pSound; return NULL; }
void CClientSoundManager::DoPulse ( void ) { UpdateVolume (); CClientCamera* pCamera = m_pClientManager->GetCamera(); CVector vecCameraPosition, vecPosition, vecLookAt, vecFront, vecVelocity; pCamera->GetPosition ( vecCameraPosition ); pCamera->GetFixedTarget ( vecLookAt ); vecFront = vecLookAt - vecCameraPosition; CClientPlayer* p_LocalPlayer = m_pClientManager->GetPlayerManager()->GetLocalPlayer(); if ( p_LocalPlayer ) { p_LocalPlayer->GetMoveSpeed( vecVelocity ); if ( pCamera->IsInFixedMode() ) vecPosition = vecCameraPosition; else p_LocalPlayer->GetPosition( vecPosition ); } else { // Make sure the players position at least has something (I'd be surprised if we get here though) vecPosition = vecCameraPosition; } // Update volume position and velocity from all sounds list < CClientSound* > ::iterator iter = m_Sounds.begin (); for ( ; iter != m_Sounds.end () ; ++iter ) { CClientSound* pSound = *iter; pSound->Process3D ( vecPosition, vecCameraPosition, vecLookAt ); // Delete sound if finished if ( pSound->IsFinished () ) { // call onClientSoundStopped CLuaArguments Arguments; Arguments.PushString ( "finished" ); // Reason pSound->CallEvent ( "onClientSoundStopped", Arguments, false ); g_pClientGame->GetElementDeleter()->Delete ( pSound ); } } UpdateDistanceStreaming ( vecPosition ); }
CClientSound* CClientSoundManager::PlayGTASFX3D ( eAudioLookupIndex containerIndex, int iBankIndex, int iAudioIndex, const CVector& vecPosition, bool bLoop ) { if ( !GetSFXStatus ( containerIndex ) ) return NULL; void* pAudioData; unsigned int uiAudioLength; if ( !g_pGame->GetAudioContainer ()->GetAudioData ( containerIndex, iBankIndex, iAudioIndex, pAudioData, uiAudioLength ) ) return NULL; CClientSound* pSound = PlaySound3D ( pAudioData, uiAudioLength, vecPosition, bLoop ); if ( pSound ) { CGameSettings * gameSettings = g_pGame->GetSettings (); pSound->SetVolume ( gameSettings->GetSFXVolume () / 255.0f ); } return pSound; }
CClientSound* CClientSoundManager::PlaySound3D ( const SString& strSound, bool bIsURL, const CVector& vecPosition, bool bLoop ) { CClientSound* pSound = new CClientSound ( m_pClientManager, INVALID_ELEMENT_ID ); if ( bIsURL ) { pSound->PlayStream ( strSound, bLoop, true ); pSound->SetPosition ( vecPosition ); return pSound; } else if ( pSound->Play3D ( strSound, bLoop ) ) { pSound->SetPosition ( vecPosition ); return pSound; } delete pSound; return NULL; }