[C++] Remove FPS Limit Using DirectX StepTimer

  • Konuyu açan Konuyu açan hasanmacit
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 25
  • Gösterim Gösterim 848
dosyalar güncellendi ekleyenler
1765821594471.webp
bu iki dosyayı kontrol etsin. networkstreamdaki değişikliği geri alın ve alttaki dosyayı da kontrol edin bir de gametype.cppde var

öneri veren @Adalet ve @Toranaga 'ya teşekkürler
 
Son düzenleme:
Ben uzmanlığı kazanana kadar dosyqlar kaybolmasın amin, eline sağlık hasan ım. Mt2'ye lazımdı böyle bir şey, inş 0.1 saniyede warp da gelir bir gün
 
Loop dongusundeki seslerde tutarlilik icin ActorInstanceMotion cpp deki SoundInstancelarin loop dongulerinin tekrarladigi yeri horse icin 0.50 - 0.65 arasi yapilabilir. Playerlar icin ise 0.23 - 0.30 arasi yaparak tekrarlama ve ses sekmelerini duzeltebilirsiniz(deneme yanilmayla daha iyi bir deger yakalayabilirsiniz). Ek olarak serverdaki ELK timer i istemciye bildiren kisimlari da mevcut timer a gore optimize etmeniz gerekiyor. Yoksa bazi durumlarda Sync, sectree sorunlari ve -kordinat sorunlari olabilir.
 
Loop dongusundeki seslerde tutarlilik icin ActorInstanceMotion cpp deki SoundInstancelarin loop dongulerinin tekrarladigi yeri horse icin 0.50 - 0.65 arasi yapilabilir. Playerlar icin ise 0.23 - 0.30 arasi yaparak tekrarlama ve ses sekmelerini duzeltebilirsiniz(deneme yanilmayla daha iyi bir deger yakalayabilirsiniz). Ek olarak serverdaki ELK timer i istemciye bildiren kisimlari da mevcut timer a gore optimize etmeniz gerekiyor. Yoksa bazi durumlarda Sync, sectree sorunlari ve -kordinat sorunlari olabilir.
akşam bir bakınayım
 
Ses sorunu için mevcut kodların mantığı karakterler üzerindeki tam kontrol için yetersiz kalıyor.
SoundManager.cpp içindeki;
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, BOOL bCheckFrequency)
{
    if (0.0f == GetSoundVolume())
        return;

    if (bCheckFrequency) // bu kontrol steptimer sonrası beklendiği gibi çalışmıyor ve yetersiz kalıyor
    ....
        ...
}

Aşağıda bu mantığı biraz değiştiren düzenlemeler paylaşıyorum. Bu düzenleme mob veya karakter sesleri üzerinde tam kontrol sahibi olmamızı sağlayıp bu sorunu en sağlıklı şekilde çözecektir. Eğer dosyalarınızda seslerle alakalı harici düzenlemeler varsa bu düzenlemede ekstra değişiklikler yapmanız gerekebilir.

SoundManager.h:

Bul:
C++:
Genişlet Daralt Kopyala
void PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, BOOL bCheckFrequency = FALSE);
Değiştir:
C++:
Genişlet Daralt Kopyala
void PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, float fLimitCheckTime = -1.0f);

Bul:
C++:
Genişlet Daralt Kopyala
void UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, BOOL bCheckFrequency = FALSE);
Değiştir:
C++:
Genişlet Daralt Kopyala
void UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, float fLimitCheckTime = -1.0f);

SoundManager.cpp:

Bul:
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, BOOL bCheckFrequency)
{
    if (0.0f == GetSoundVolume())
        return;

    // ¾î´À Á¤µµÀÇ ÃÖÀûȰ¡ ÇÊ¿äÇÒ ¼öµµ ÀÖ´Ù - [levites]
    if (bCheckFrequency)
    {
        static float s_fLimitDistance = 5000 * 5000;
        float fdx = (fx - m_fxPosition) * (fx - m_fxPosition);
        float fdy = (fy - m_fyPosition) * (fy - m_fyPosition);

        if (fdx + fdy > s_fLimitDistance)
            return;

        std::map<std::string, float>::iterator itor = m_PlaySoundHistoryMap.find(c_szFileName);
        if (m_PlaySoundHistoryMap.end() != itor)
        {
            float fTime = itor->second;
            if (DX::StepTimer::instance().GetTotalSeconds() - fTime < 0.3f)
            {
                //Tracef("¶È°°Àº ¼Ò¸®°¡ 0.3ÃÊ ³»¿¡ ´Ù½Ã Ç÷¹ÀÌ %s\n", c_szFileName);
                return;
            }
        }

        m_PlaySoundHistoryMap.erase(c_szFileName);
        m_PlaySoundHistoryMap.insert(std::map<std::string, float>::value_type(c_szFileName, DX::StepTimer::instance().GetTotalSeconds()));
    }
    ...
    //Aşağısı aynı kalır
}
Değiştir:
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, float fLimitCheckTime)
{
    if (0.0f == GetSoundVolume())
        return;

    std::string strFileName;
    StringPath(c_szFileName, strFileName);

    if (fLimitCheckTime > 0.0f)
    {
        static float s_fLimitDistance = 5000 * 5000;
        float fdx = (fx - m_fxPosition) * (fx - m_fxPosition);
        float fdy = (fy - m_fyPosition) * (fy - m_fyPosition);

        if (fdx + fdy > s_fLimitDistance)
            return;

        std::map<std::string, float>::iterator itor = m_PlaySoundHistoryMap.find(strFileName);

        float fCurTime = (float)DX::StepTimer::instance().GetTotalSeconds();

        if (m_PlaySoundHistoryMap.end() != itor)
        {
            float fTime = itor->second;
            if (fCurTime - fTime < fLimitCheckTime)
            {
                return;
            }
        }

        m_PlaySoundHistoryMap[strFileName] = fCurTime;
    }
    ...
    // Aşağısı aynı kalır
}

Bul:
C++:
Genişlet Daralt Kopyala
void CSoundManager::UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, BOOL bCheckFrequency)
{
    for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i)
    {
        const NSound::TSoundInstance& c_rSoundInstance = c_pSoundInstanceVector->at(i);
        if (c_rSoundInstance.dwFrame == dwcurFrame)
        {
            //Tracenf("PLAY SOUND %s", c_rSoundInstance.strSoundFileName.c_str());
            PlayCharacterSound3D(fx, fy, fz, c_rSoundInstance.strSoundFileName.c_str(), bCheckFrequency);
        }
    }
}
Değiştir:
C++:
Genişlet Daralt Kopyala
void CSoundManager::UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, float fLimitCheckTime)
{
    for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i)
    {
        const NSound::TSoundInstance& c_rSoundInstance = c_pSoundInstanceVector->at(i);
        if (c_rSoundInstance.dwFrame == dwcurFrame)
        {
            //Tracenf("PLAY SOUND %s", c_rSoundInstance.strSoundFileName.c_str());
            PlayCharacterSound3D(fx, fy, fz, c_rSoundInstance.strSoundFileName.c_str(), fLimitCheckTime);
        }
    }
}

SoundInstance3D.cpp içinde bul:
C++:
Genişlet Daralt Kopyala
void CSoundInstance3D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const
{
    if (!m_pSoundData)
        return;

    DWORD dwCurTime = ELTimer_GetMSec();

    if (dwCurTime - m_pSoundData->GetPlayTime() < dwPlayCycleTimeLimit)
        return;

    m_pSoundData->SetPlayTime(dwCurTime);

    AIL_set_3D_sample_loop_count(m_sample, iLoopCount);
    AIL_start_3D_sample(m_sample);
}

Aşağıdaki gibi ilgili kısmı yoruma çevirin:
C++:
Genişlet Daralt Kopyala
void CSoundInstance3D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const
{
    if (!m_pSoundData)
        return;

    /* // gereksiz
    DWORD dwCurTime = ELTimer_GetMSec();

    if (dwCurTime - m_pSoundData->GetPlayTime() < dwPlayCycleTimeLimit)
        return;

    m_pSoundData->SetPlayTime(dwCurTime);
    */

    AIL_set_3D_sample_loop_count(m_sample, iLoopCount);
    AIL_start_3D_sample(m_sample);
}

ActorInstanceMotion.cpp içinde bulun:
C++:
Genişlet Daralt Kopyala
void CActorInstance::__MotionEventProcess(BOOL isPC)
{
    if (isAttacking())
    {
        DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
        for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
        {
            MotionEventProcess();
            SoundEventProcess(!isPC);
        }
    }
    else
    {
        MotionEventProcess();
        SoundEventProcess(!isPC);

        ++m_kCurMotNode.dwcurFrame;
    }
}

Komple değiştirin:
C++:
Genişlet Daralt Kopyala
void CActorInstance::__MotionEventProcess(BOOL isPC)
{
    float fSoundLimit = isPC ? 0.25f : 0.35f;
    // Burası artık yönetim noktasıdır. Burada her türlü özelleştirme ve
    // sorgulama yaparak karakterlere özgü ses değeri ayarlayabilirsiniz.
    // Örneğin:
    // if (GetRace() == 20118) // Yırtıcı Aslan'a özel değer
    //    fSoundLimit = 0.55f;

    if (isAttacking())
    {
        DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
        for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
        {
            MotionEventProcess();
            SoundEventProcess(fSoundLimit);
        }
    }
    else
    {
        MotionEventProcess();
        SoundEventProcess(fSoundLimit);

        ++m_kCurMotNode.dwcurFrame;
    }
}

Dipnot: g_fGameFPS değeri 60.0f olmalıdır.
 
Ses sorunu için mevcut kodların mantığı karakterler üzerindeki tam kontrol için yetersiz kalıyor.
SoundManager.cpp içindeki;
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, BOOL bCheckFrequency)
{
    if (0.0f == GetSoundVolume())
        return;

    if (bCheckFrequency) // bu kontrol steptimer sonrası beklendiği gibi çalışmıyor ve yetersiz kalıyor
    ....
        ...
}

Aşağıda bu mantığı biraz değiştiren düzenlemeler paylaşıyorum. Bu düzenleme mob veya karakter sesleri üzerinde tam kontrol sahibi olmamızı sağlayıp bu sorunu en sağlıklı şekilde çözecektir. Eğer dosyalarınızda seslerle alakalı harici düzenlemeler varsa bu düzenlemede ekstra değişiklikler yapmanız gerekebilir.

SoundManager.h:

Bul:
C++:
Genişlet Daralt Kopyala
void PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, BOOL bCheckFrequency = FALSE);
Değiştir:
C++:
Genişlet Daralt Kopyala
void PlayCharacterSound3D(float fx, float fy, float fz, const char * c_szFileName, float fLimitCheckTime = -1.0f);

Bul:
C++:
Genişlet Daralt Kopyala
void UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, BOOL bCheckFrequency = FALSE);
Değiştir:
C++:
Genişlet Daralt Kopyala
void UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector * c_pSoundInstanceVector, float fLimitCheckTime = -1.0f);

SoundManager.cpp:

Bul:
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, BOOL bCheckFrequency)
{
    if (0.0f == GetSoundVolume())
        return;

    // ¾î´À Á¤µµÀÇ ÃÖÀûȰ¡ ÇÊ¿äÇÒ ¼öµµ ÀÖ´Ù - [levites]
    if (bCheckFrequency)
    {
        static float s_fLimitDistance = 5000 * 5000;
        float fdx = (fx - m_fxPosition) * (fx - m_fxPosition);
        float fdy = (fy - m_fyPosition) * (fy - m_fyPosition);

        if (fdx + fdy > s_fLimitDistance)
            return;

        std::map<std::string, float>::iterator itor = m_PlaySoundHistoryMap.find(c_szFileName);
        if (m_PlaySoundHistoryMap.end() != itor)
        {
            float fTime = itor->second;
            if (DX::StepTimer::instance().GetTotalSeconds() - fTime < 0.3f)
            {
                //Tracef("¶È°°Àº ¼Ò¸®°¡ 0.3ÃÊ ³»¿¡ ´Ù½Ã Ç÷¹ÀÌ %s\n", c_szFileName);
                return;
            }
        }

        m_PlaySoundHistoryMap.erase(c_szFileName);
        m_PlaySoundHistoryMap.insert(std::map<std::string, float>::value_type(c_szFileName, DX::StepTimer::instance().GetTotalSeconds()));
    }
    ...
    //Aşağısı aynı kalır
}
Değiştir:
C++:
Genişlet Daralt Kopyala
void CSoundManager::PlayCharacterSound3D(float fx, float fy, float fz, const char* c_szFileName, float fLimitCheckTime)
{
    if (0.0f == GetSoundVolume())
        return;

    std::string strFileName;
    StringPath(c_szFileName, strFileName);

    if (fLimitCheckTime > 0.0f)
    {
        static float s_fLimitDistance = 5000 * 5000;
        float fdx = (fx - m_fxPosition) * (fx - m_fxPosition);
        float fdy = (fy - m_fyPosition) * (fy - m_fyPosition);

        if (fdx + fdy > s_fLimitDistance)
            return;

        std::map<std::string, float>::iterator itor = m_PlaySoundHistoryMap.find(strFileName);

        float fCurTime = (float)DX::StepTimer::instance().GetTotalSeconds();

        if (m_PlaySoundHistoryMap.end() != itor)
        {
            float fTime = itor->second;
            if (fCurTime - fTime < fLimitCheckTime)
            {
                return;
            }
        }

        m_PlaySoundHistoryMap[strFileName] = fCurTime;
    }
    ...
    // Aşağısı aynı kalır
}

Bul:
C++:
Genişlet Daralt Kopyala
void CSoundManager::UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, BOOL bCheckFrequency)
{
    for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i)
    {
        const NSound::TSoundInstance& c_rSoundInstance = c_pSoundInstanceVector->at(i);
        if (c_rSoundInstance.dwFrame == dwcurFrame)
        {
            //Tracenf("PLAY SOUND %s", c_rSoundInstance.strSoundFileName.c_str());
            PlayCharacterSound3D(fx, fy, fz, c_rSoundInstance.strSoundFileName.c_str(), bCheckFrequency);
        }
    }
}
Değiştir:
C++:
Genişlet Daralt Kopyala
void CSoundManager::UpdateSoundInstance(float fx, float fy, float fz, DWORD dwcurFrame, const NSound::TSoundInstanceVector* c_pSoundInstanceVector, float fLimitCheckTime)
{
    for (DWORD i = 0; i < c_pSoundInstanceVector->size(); ++i)
    {
        const NSound::TSoundInstance& c_rSoundInstance = c_pSoundInstanceVector->at(i);
        if (c_rSoundInstance.dwFrame == dwcurFrame)
        {
            //Tracenf("PLAY SOUND %s", c_rSoundInstance.strSoundFileName.c_str());
            PlayCharacterSound3D(fx, fy, fz, c_rSoundInstance.strSoundFileName.c_str(), fLimitCheckTime);
        }
    }
}

SoundInstance3D.cpp içinde bul:
C++:
Genişlet Daralt Kopyala
void CSoundInstance3D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const
{
    if (!m_pSoundData)
        return;

    DWORD dwCurTime = ELTimer_GetMSec();

    if (dwCurTime - m_pSoundData->GetPlayTime() < dwPlayCycleTimeLimit)
        return;

    m_pSoundData->SetPlayTime(dwCurTime);

    AIL_set_3D_sample_loop_count(m_sample, iLoopCount);
    AIL_start_3D_sample(m_sample);
}

Aşağıdaki gibi ilgili kısmı yoruma çevirin:
C++:
Genişlet Daralt Kopyala
void CSoundInstance3D::Play(int iLoopCount, DWORD dwPlayCycleTimeLimit) const
{
    if (!m_pSoundData)
        return;

    /* // gereksiz
    DWORD dwCurTime = ELTimer_GetMSec();

    if (dwCurTime - m_pSoundData->GetPlayTime() < dwPlayCycleTimeLimit)
        return;

    m_pSoundData->SetPlayTime(dwCurTime);
    */

    AIL_set_3D_sample_loop_count(m_sample, iLoopCount);
    AIL_start_3D_sample(m_sample);
}

ActorInstanceMotion.cpp içinde bulun:
C++:
Genişlet Daralt Kopyala
void CActorInstance::__MotionEventProcess(BOOL isPC)
{
    if (isAttacking())
    {
        DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
        for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
        {
            MotionEventProcess();
            SoundEventProcess(!isPC);
        }
    }
    else
    {
        MotionEventProcess();
        SoundEventProcess(!isPC);

        ++m_kCurMotNode.dwcurFrame;
    }
}

Komple değiştirin:
C++:
Genişlet Daralt Kopyala
void CActorInstance::__MotionEventProcess(BOOL isPC)
{
    float fSoundLimit = isPC ? 0.25f : 0.35f;
    // Burası artık yönetim noktasıdır. Burada her türlü özelleştirme ve
    // sorgulama yaparak karakterlere özgü ses değeri ayarlayabilirsiniz.
    // Örneğin:
    // if (GetRace() == 20118) // Yırtıcı Aslan'a özel değer
    //    fSoundLimit = 0.55f;

    if (isAttacking())
    {
        DWORD dwNextFrame = DWORD(GetAttackingElapsedTime() * g_fGameFPS);
        for (; m_kCurMotNode.dwcurFrame < dwNextFrame; ++m_kCurMotNode.dwcurFrame)
        {
            MotionEventProcess();
            SoundEventProcess(fSoundLimit);
        }
    }
    else
    {
        MotionEventProcess();
        SoundEventProcess(fSoundLimit);

        ++m_kCurMotNode.dwcurFrame;
    }
}

Dipnot: g_fGameFPS değeri 60.0f olmalıdır.
eyw kral akşam githuba ekleyeyim
 
Geri
Üst