__int64 freq=0, dernier=0, avantBlit=0, apresBlit=0, derSeconde=0;
unsigned int skip=0, modeAttente=2, vSync=0, skipMax=20;
char *titreFenetre;
__int64 dernierMF;

#define VSYNC_ACTIVEE 1
#define MODE_PRECIS 2

void TitreFenetre(char *titre)		{
	titreFenetre=titre;
	if (titre)
		SetWindowText(hConsole,titre);
}

void SkipMaximum(int nombre)		{
	skipMax=nombre;
}

void ModeAttente(int attente, int vsync)		{
	modeAttente=attente;
	vSync=vsync&1;
//	modePrecis=vsync>>1;
}

void InitTimer()		{
	QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
	QueryPerformanceCounter((LARGE_INTEGER*)&dernier);
	derSeconde=dernier;
}

void ReinitTimer()		{
	QueryPerformanceCounter((LARGE_INTEGER*)&dernier);
	dernierMF=dernier;
}

void DebutMesureFramerate()		{
	QueryPerformanceCounter((LARGE_INTEGER*)&dernierMF);
}

void FinMesureFramerate(HWND hWnd, int tempsMax)		{
	static int mod=0, frameRate=0, sommeTemps=0, sommeBlits=0;
	char str[100];
	__int64 courant, ticks;
	ticks = (__int64)freq / 1000000;

	frameRate++;
	QueryPerformanceCounter((LARGE_INTEGER*)&courant);
	sommeTemps+=(int)((courant - dernierMF)/ticks);
	sommeBlits+=(int)((apresBlit-avantBlit)/ticks);

	if ((courant-derSeconde)>=freq)		{
		derSeconde=courant;
		if (!titreFenetre)		{
			sprintf(str,"%i+%i us; %i FPS; %i%%",sommeTemps/frameRate,sommeBlits/frameRate,frameRate,(100*((sommeTemps+sommeBlits)/frameRate))/tempsMax);
			SetWindowText(hWnd,str);
		}
		frameRate=sommeTemps=sommeBlits=0;
	}
}

int AttendSyncPrecise(int temps)		{
	__int64 courant, ticks;
	ticks = (__int64)temps * freq / 1000000;
	QueryPerformanceCounter((LARGE_INTEGER*)&courant);
	if ((courant - dernier) < ticks)		{		//On est à temps?
		skip=0;
		while((courant - dernier) < ticks)		{
//			if ((courant - dernier)>freq/1000)
//				Sleep(1);
			Sleep(0);
			if ((courant - dernier)<ticks)	Sleep(0);
			QueryPerformanceCounter((LARGE_INTEGER*)&courant);
		}
		dernier+=ticks;
	}
	else	{										//On a du retard
		if (modeAttente==2)		{
			dernier=courant;
			return 0;
		}
		dernier+=ticks;
		if ((courant - dernier) >= ticks*skipMax)		{
			dernier=courant;
			skip=0;
		}
		else		{
			if ((courant - dernier) >= ((modeAttente==0)?(ticks):(freq/1000)))			//Le retard est très important?
				skip=1;
			else							//En retard, mais un tout petit peu. Ca ne vaut pas la peine de skipper => On n'attend pas pour gagner un peu.
				skip=0;
		}

	}
	return skip;
}

/*
int AttendSyncPrecise(int temps)		{
	__int64 courant, ticks;
	ticks = (__int64)temps * freq / 1000000;
	QueryPerformanceCounter((LARGE_INTEGER*)&courant);
	if ((courant - dernier) < ticks)		{		//On est à temps?
		skip=0;
		while((courant - dernier) < ticks)		{
//			if ((courant - dernier)>freq/1000)
//				Sleep(1);
			QueryPerformanceCounter((LARGE_INTEGER*)&courant);
		}
		dernier+=ticks;
	}
	else	{										//On a du retard
		if (modeAttente==2)		{
			dernier=courant;
			return 0;
		}
		dernier+=ticks;
		if ((courant - dernier) >= ticks*skipMax)		{
			dernier=courant;
			skip=0;
		}
		else		{
			if ((courant - dernier) >= ((modeAttente==0)?(ticks):(freq/1000)))			//Le retard est très important?
				skip=1;
			else							//En retard, mais un tout petit peu. Ca ne vaut pas la peine de skipper => On n'attend pas pour gagner un peu.
				skip=0;
		}

	}
	return skip;
}

*/

int AttendSyncFreq(int freq)		{
	int i=0;
	if (!skip)
		FinMesureFramerate(hConsole,1000000/freq);
	if (!skip)		{
#ifdef UTILISER_DIRECTX
		if (vSync)
			IDirectDraw_WaitForVerticalBlank(lpDD,DDWAITVB_BLOCKBEGIN,0);
#endif
		QueryPerformanceCounter((LARGE_INTEGER*)&avantBlit);
		AfficheEcran();
		QueryPerformanceCounter((LARGE_INTEGER*)&apresBlit);
	}
	i=AttendSyncPrecise(1000000/freq);
	QueryPerformanceCounter((LARGE_INTEGER*)&dernierMF);
//	if (!i)
	return i;
}

int AttendSync(int temps)		{
	__int64 courant, ticks;
	ticks = (__int64)temps * freq / 1000;
	QueryPerformanceCounter((LARGE_INTEGER*)&courant);
	if ((courant - dernier) < ticks)		{		//On est à temps?
		skip=0;
		while((courant - dernier) < ticks)		{
			QueryPerformanceCounter((LARGE_INTEGER*)&courant);
		}
		dernier+=ticks;
	}
	else	{										//On a du retard
		if (modeAttente==2)		{
			dernier=courant;
			return 0;
		}
		dernier+=ticks;
		if ((courant - dernier) >= ((modeAttente==0)?(ticks):(freq/1000)))			//Le retard est très important?
			skip=1;
		else							//En retard, mais un tout petit peu. Ca ne vaut pas la peine de skipper => On n'attend pas pour gagner un peu.
			skip=0;
	}
	return skip;
}
