Membru Începător
Membru Începător
  • Mesaje: 12
    Membru din: 01 Mar 2025, 02:28
  • Reacții: 5
  • Mesaje utile: 0
  • Status: Pierd vremea ^.^
  • Regat: Chunjo
  • Medalii

    *Descriere:

    Effect Frame Update Optimization

    The frame controller update function, used in mesh and texture effect animations, originally relied on a fixed loop (up to 20 iterations) to simulate the passage of frames based on the accumulated elapsed time. This had several downsides:

    Inefficient CPU usage due to repeated branching.
    Limited scalability – could miss frames if elapsed time was large.
    More complex and harder-to-maintain code.

    What's Improved with the Change?

    The new logic replaces the loop with a direct calculation.
    It computes how many frames should have passed based on the total elapsed time.
    All necessary frame advancements are done at once, in a single operation.
    Looping behavior and animation end conditions are still handled properly.

    Benefits

    Lower CPU usage – avoids unnecessary loops and branching.
    Scales better – handles large time jumps (e.g., low FPS situations) more smoothly.
    Cleaner, more maintainable code.

    Summary

    This optimization improves CPU efficiency and performance of mesh and texture effect animations during low-FPS situations, resulting in smoother visual effects. It does not guarantee a stable 60 FPS but ensures frame updates are handled more efficiently and responsively.


    *Poze / Video:

    EffectLib -> FrameController.cpp

    *Link download / Code:
    Code:
      //edit PepsiZero metin2forum 
    
    #include "StdAfx.h"
    #include "FrameController.h"
    
    void CFrameController::Update(float fElapsedTime)
    {
    #ifdef ENABLE_EFFECT_UPDATE_OPTIMIZATION
    	if (!m_isActive)
    		return;
    
    	if (fElapsedTime <= 0.0f)
    		return;
    
    	if (m_fFrameTime <= 0.0f || m_dwMaxFrame == 0)
    	{
    		m_iLoopCount = 1;
    		m_dwcurFrame = 0;
    		m_fLastFrameTime = 0.0f;
    		m_isActive = FALSE;
    		return;
    	}
    
    	m_fLastFrameTime -= fElapsedTime;
    
    	if (m_fLastFrameTime >= 0.0f)
    		return;
    
    	double dAdvanceFrame = double(-m_fLastFrameTime) / double(m_fFrameTime);
    	DWORD dwAdvanceFrame;
    
    	if (!(dAdvanceFrame >= 0.0))
    	{
    		m_fLastFrameTime = m_fFrameTime;
    		return;
    	}
    
    	if (dAdvanceFrame >= 4294967295.0)
    	{
    		dwAdvanceFrame = 0xffffffff;
    		m_fLastFrameTime = 0.0f;
    	}
    	else
    	{
    		dwAdvanceFrame = DWORD(dAdvanceFrame);
    
    		double dLastFrameTime = double(m_fLastFrameTime) + double(m_fFrameTime) * double(dwAdvanceFrame);
    		if (dLastFrameTime < 0.0)
    		{
    			dLastFrameTime += double(m_fFrameTime);
    			++dwAdvanceFrame;
    		}
    
    		m_fLastFrameTime = float(dLastFrameTime);
    	}
    
    	if (dwAdvanceFrame == 0)
    		return;
    
    	if (m_dwcurFrame >= m_dwMaxFrame)
    		m_dwcurFrame = 0;
    
    	if (!m_isLoop)
    	{
    		if (dwAdvanceFrame >= m_dwMaxFrame - m_dwcurFrame)
    		{
    			m_iLoopCount = 1;
    			m_dwcurFrame = 0;
    			m_isActive = FALSE;
    			return;
    		}
    
    		m_dwcurFrame += dwAdvanceFrame;
    		return;
    	}
    
    	DWORD dwLoopCount = dwAdvanceFrame / m_dwMaxFrame;
    	DWORD dwFrame = dwAdvanceFrame % m_dwMaxFrame;
    
    	if (dwFrame >= m_dwMaxFrame - m_dwcurFrame)
    	{
    		++dwLoopCount;
    		m_dwcurFrame = dwFrame - (m_dwMaxFrame - m_dwcurFrame);
    	}
    	else
    	{
    		m_dwcurFrame += dwFrame;
    	}
    
    	if (m_iLoopCount > 0)
    	{
    		if (dwLoopCount >= DWORD(m_iLoopCount))
    		{
    			m_iLoopCount = 1;
    			m_dwcurFrame = 0;
    			m_isActive = FALSE;
    			return;
    		}
    
    		m_iLoopCount -= dwLoopCount;
    	}
    	else
    	{
    		m_iLoopCount = 0;
    	}
    #else
    	m_fLastFrameTime -= fElapsedTime;
    
    	for (int i = 0; i < 20; ++i)
    	{
    		if (m_fLastFrameTime < 0.0f)
    		{
    			m_fLastFrameTime += m_fFrameTime;
    			++m_dwcurFrame;
    
    			if (m_dwcurFrame >= m_dwMaxFrame)
    			{
    				if (m_isLoop && --m_iLoopCount!=0)
    				{
    					if (m_iLoopCount<0)
    						m_iLoopCount = 0;
    					m_dwcurFrame = 0;
    				}
    				else
    				{
    					m_iLoopCount = 1;
    					m_dwcurFrame = 0;
    					m_isActive = FALSE;
    					return;
    				}
    			}
    		}
    		else
    		{
    			break;
    		}
    	}
    #endif
    }
    
    void CFrameController::SetCurrentFrame(DWORD dwFrame)
    {
    	m_dwcurFrame = dwFrame;
    }
    
    BYTE CFrameController::GetCurrentFrame()
    {
    	return m_dwcurFrame;
    }
    
    void CFrameController::SetMaxFrame(DWORD dwMaxFrame)
    {
    	m_dwMaxFrame = dwMaxFrame;
    }
    void CFrameController::SetFrameTime(float fTime)
    {
    	m_fFrameTime = fTime;
    	m_fLastFrameTime = fTime;
    }
    void CFrameController::SetStartFrame(DWORD dwStartFrame)
    {
    	m_dwStartFrame = dwStartFrame;
    }
    
    void CFrameController::SetLoopFlag(BOOL bFlag)
    {
    	m_isLoop = bFlag;
    }
    
    void CFrameController::SetLoopCount(int iLoopCount)
    {
    	m_iLoopCount = iLoopCount;
    }
    
    void CFrameController::SetActive(BOOL bFlag)
    {
    	m_isActive = bFlag;
    }
    
    BOOL CFrameController::isActive(DWORD dwMainFrame)
    {
    	if (dwMainFrame < m_dwStartFrame)
    		return FALSE;
    
    	return m_isActive;
    }
    
    void CFrameController::Clear()
    {
    	m_isActive = TRUE;
    	m_dwcurFrame = 0;
    	m_fLastFrameTime = 0.0f;
    	m_iLoopCount = 0;
    }
    
    CFrameController::CFrameController()
    {
    	m_isActive = TRUE;
    	m_dwcurFrame = 0;
    	m_fLastFrameTime = 0.0f;
    	m_iLoopCount = 0;
    
    	m_isLoop = FALSE;
    	m_dwMaxFrame = 0;
    	m_fFrameTime = 0.0f;
    	m_dwStartFrame = 0;
    }
    CFrameController::~CFrameController()
    {
    }
    
     

    Nou Cum descarc de pe TeraBox?

    Afișează detalii Ascunde detalii
    • Este asemănător cu Mega.nz
    • Instalați-vă clientul lor de Download de aici
    • Faceți-vă un cont (vă puteți loga cu Facebook / Google / etc)
    • Nou Dacă nu vreți să descărcați clientul de Download, folosiți acest site
    • Gata! Acum puteți descărca resursele rapid & simplu.

    De ce folosim TeraBox?

    • Este gratuit
    • Primești 1TB de spațiu gratuit la orice cont creat!
    • Este ușor de folosit și varianta premium este foarte ieftină
    • Fișierele nu sunt șterse niciodată
    TeraBox logo

    Creează-ți un cont sau autentifică-te pentru a participa la discuție

    Trebuie să fii membru pentru a răspunde

    Creează-ți un cont

    Membrii pot crea subiecte noi și pot descărca resurse Metin2 Gratuit!


    Te poți înregistra sau conecta rapid utilizând contul tău de Discord, Github sau Google.

    Înregistrare

    Autentifică-te

    Înapoi la “Îmbunătățiri”

    Informații

    Utilizatori ce navighează pe acest forum: btamaduitorul, DarkGore, LSW, marius_69140, Shirodir, Trigun100, zupea și 1 vizitator

    Discord ID copiat: