reman3/Rayman_X/cpa/tempgrp/GliGlou/Gld/DevVp1.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;
}