예제 #1
0
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;
}
예제 #3
0
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;
}
예제 #5
0
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;

}
예제 #6
0
//
// 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 ();
    }
}
예제 #7
0
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;
}
예제 #8
0
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 );
}
예제 #9
0
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;
}
예제 #10
0
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;
}