#define C_szSynchroOn "ON" #define C_szSynchroOff "OFF" /* change frame rate under 70 %*/ unsigned char g_ucSynchroLowLimit = 70; unsigned char g_ucDftSynchro = C_AutoSynchro; /* ##F=================================================================================== NAME : GLD_vSetFrameSynchro DESCRIPTION : This function set the type of synchro used with its parameter For script interpretation INPUT : Synchro ON or OFF NbTrame (0 for hysteresis system) Percent use to decrease NbTrame ========================================================================================= CREATION : Carlos Torres / 11-12-1997 =======================================================================================*/ void GLD_vSetFrameSynchro(char * szOnOff,char * szNbTrame,char * szPctLowLimit) { int iNumber; /* Synchro OFF*/ if (!stricmp(szOnOff,C_szSynchroOff)) g_ucDftSynchro = C_NoSynchro; /* Synchro ON*/ else if (!stricmp(szOnOff,C_szSynchroOn)) { iNumber = atoi(szNbTrame); /* set nb trame use for synchro*/ if ((iNumber >= C_AutoSynchro) && (iNumber <= C_MaxFrameSynchro)) g_ucDftSynchro = (unsigned char) iNumber; } /* set % low limit*/ iNumber = atoi(szPctLowLimit); if ((iNumber >= 0) && (iNumber <= 100)) g_ucSynchroLowLimit = (unsigned char) iNumber; } /* ##F=================================================================================== NAME : GLD_vIdle DESCRIPTION : for NoSynchro -> just call grSstIdle forAutosynchro -> wait a calculted number of trame Defaultsynchro -> depends on the choice set with SetFrameSynchro other -> wait the specified number of trame INPUT : Synchro choice ========================================================================================= CREATION : Carlos Torres / 11-12-1997 MODIF / 22-12-1997 change frame length evaluation =======================================================================================*/ #ifdef GLIDE void GLD_vIdle(enum Synchro eSynchro) { static short s_wTime = 0; static unsigned long s_ulFrameLength = 0; static unsigned char s_ucFrameFrequency = 3; stTimerCount C={0,0}; unsigned int uiTramePassed; unsigned char ucUsedSynchro=(eSynchro == C_DefaultSynchro)?g_ucDftSynchro:eSynchro; unsigned long ulState; /* No synchro*/ if ((ucUsedSynchro == C_NoSynchro)) { grSstIdle(); return; } /* first passage*/ if (!s_wTime) { s_wTime = TMR_fn_wCreateTimer(C_wTimerFrequencyMedium); ulState = grSstStatus(); /* mesurement of trame length*/ while (grSstVideoLine() != 0); while (grSstVideoLine() != 1); TMR_fn_wStartTimer(s_wTime); while (grSstVideoLine() != 0); while (grSstVideoLine() != 1); TMR_fn_wReadTimer(s_wTime,&C); TMR_fn_wStopTimer(s_wTime); TMR_fn_wResetTimer(s_wTime); /* Add a delta to majorate frmae length*/ s_ulFrameLength = (unsigned long)(C.m_ulLowPart*1.05); s_ulFrameLength = C.m_ulLowPart; } else { /* Auto Syncho*/ if (ucUsedSynchro == C_AutoSynchro) { /* get the last length of time for rendering*/ TMR_fn_wReadTimer(s_wTime,&C); /* length is over the previous limit -> increase Frame frequency*/ if ((C.m_ulLowPart > (s_ucFrameFrequency*s_ulFrameLength)) && (s_ucFrameFrequency < C_MaxFrameSynchro)) { s_ucFrameFrequency++; } /* length is under the Synchro Limit -> decrease Frame frequency*/ else if ((s_ucFrameFrequency > 1) && ((100*C.m_ulLowPart) < ((100*s_ucFrameFrequency - 200 + g_ucSynchroLowLimit)*s_ulFrameLength))) s_ucFrameFrequency--; ucUsedSynchro = s_ucFrameFrequency; } /* get the last length of time for rendering*/ TMR_fn_wStopTimer(s_wTime); TMR_fn_wReadTimer(s_wTime,&C); } /* compute VBL already passed during rendering*/ for (uiTramePassed=0;C.m_ulLowPart>s_ulFrameLength;uiTramePassed++,C.m_ulLowPart-=s_ulFrameLength); /* Wa it the next end of screen*/ do { /* between end of screen and VBL -> wait*/ if (uiTramePassed && (grSstVideoLine() >= (unsigned long) 480) && (uiTramePassed < ucUsedSynchro)) { while(grSstVideoLine()) ; } /* Avoid evaluation error*/ if (!grSstVideoLine() && ((C.m_ulLowPart << 1) > s_ulFrameLength)) uiTramePassed++; /* Remain RAZ*/ C.m_ulLowPart=0; while ((grSstVideoLine() < (unsigned long) 480) && (grSstVideoLine() || (uiTramePassed < ucUsedSynchro))); } while (++uiTramePassed < ucUsedSynchro); TMR_fn_wResetTimer(s_wTime); TMR_fn_wStartTimer(s_wTime); } #endif /* GLIDE */ long GLD_lComputeWaitFrameForSynchro (enum Synchro eSynchro) { static short s_wTime = 0; static unsigned char s_ucFrameFrequency = 1; stTimerCount C={0,0}; unsigned char ucUsedSynchro = (eSynchro == C_DefaultSynchro) ? g_ucDftSynchro : eSynchro; long lTramePassed , lTrameReturn; /* No synchro*/ if (ucUsedSynchro == C_NoSynchro) return 0; /* first passage*/ if (!s_wTime) { s_wTime = TMR_fn_wCreateTimer(C_wTimerFrequencyMedium); TMR_fn_wResetTimer(s_wTime); TMR_fn_wStartTimer(s_wTime); return 0; } /* Auto Synchro*/ if (ucUsedSynchro == C_AutoSynchro) { /* get the last length of time for rendering*/ TMR_fn_wReadTimer(s_wTime, &C); /* length is over the previous limit -> increase Frame frequency*/ if ( (C.m_ulLowPart > (s_ucFrameFrequency * GLI_g_ulFrameLength) ) && (s_ucFrameFrequency < C_MaxFrameSynchro)) { s_ucFrameFrequency++; } /* length is under the Synchro Limit -> decrease Frame frequency*/ else { if ( (s_ucFrameFrequency > 1) && ((100*C.m_ulLowPart) < ((100*s_ucFrameFrequency - 200 + g_ucSynchroLowLimit)*GLI_g_ulFrameLength)) ) s_ucFrameFrequency--; } ucUsedSynchro = s_ucFrameFrequency; } /* get the last length of time for rendering*/ TMR_fn_wStopTimer(s_wTime); TMR_fn_wReadTimer(s_wTime,&C); /* compute VBL already passed during rendering*/ for (lTramePassed = 0 ; C.m_ulLowPart > GLI_g_ulFrameLength; lTramePassed++, C.m_ulLowPart-=GLI_g_ulFrameLength); if (lTramePassed > s_ucFrameFrequency ) lTrameReturn = 1; else lTrameReturn = s_ucFrameFrequency - lTramePassed + 1; TMR_fn_wResetTimer(s_wTime); TMR_fn_wStartTimer(s_wTime); /*return s_ucFrameFrequency;*/ return lTrameReturn; } static unsigned short gs_wTimerForSmoothSyncro = 0xbeef; long GLD_fn_lComputeWaitFrameForSmoothSynchro() { #define C_ulFrameRateHistorySize 5 static long gas_ulFrameRateHistory[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static unsigned long ulTotalFrameRate = 0; static unsigned long ulCurrentFrame = 0; stTimerCount stDeltaTime; unsigned long ulTramePassed; unsigned long ulTrameReturn = 1; if( gs_wTimerForSmoothSyncro == 0xbeef ) { /* First time, create the timer. */ gs_wTimerForSmoothSyncro = TMR_fn_wCreateTimer(C_wTimerFrequencyMedium); TMR_fn_wResetTimer(gs_wTimerForSmoothSyncro); TMR_fn_wStartTimer(gs_wTimerForSmoothSyncro); return 1; } TMR_fn_wReadTimer(gs_wTimerForSmoothSyncro, &stDeltaTime); /* Compute duration passed for engine + rendering (rounded up) */ ulTramePassed = ( stDeltaTime.m_ulLowPart + ((GLI_g_ulFrameLength*95)/100) ) / GLI_g_ulFrameLength; /* Too slow. We don't do anything */ if( ulTramePassed > 4 ) return 1; /* Compute number of frames to wait for */ if( ulTramePassed << C_ulFrameRateHistorySize < ulTotalFrameRate ) ulTrameReturn = 1 + ((ulTotalFrameRate + (1<> C_ulFrameRateHistorySize) - ulTramePassed; /* Update frame history */ ulTotalFrameRate -= gas_ulFrameRateHistory[ulCurrentFrame]; ulTotalFrameRate += ulTramePassed; gas_ulFrameRateHistory[ulCurrentFrame] = ulTramePassed; ulCurrentFrame ++; ulCurrentFrame &= (1<