248 lines
7.9 KiB
C
248 lines
7.9 KiB
C
#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) - 1) >> C_ulFrameRateHistorySize)
|
|
- ulTramePassed;
|
|
|
|
/* Update frame history */
|
|
ulTotalFrameRate -= gas_ulFrameRateHistory[ulCurrentFrame];
|
|
ulTotalFrameRate += ulTramePassed;
|
|
gas_ulFrameRateHistory[ulCurrentFrame] = ulTramePassed;
|
|
ulCurrentFrame ++;
|
|
ulCurrentFrame &= (1<<C_ulFrameRateHistorySize) - 1;
|
|
|
|
return (long)ulTrameReturn;
|
|
} |