El control del tiempo en cualquier tipo de programa que funcione en tiempo real es fundamental, y más en un juego, donde tenemos tiempos de fotogramas del orden de unos pocos milisegundos, y que si no calculamos bien puede provocar errores, o movimientos poco fluidos, etc…
Por regla general, se puede usar una función como GetTickCount (), que devuelve el número de milisegundos transcurridos desde el arranque del sistema, y olvidarse del tema.
El problema de GetTickCount () es que, para valores muy pequeños, no suele ser preciso, pues su resolución puede ser de hasta varios ms. En el caso de los juegos, donde un fotograma puede durar menos de 15ms, este error puede ser muy significativo.
Así que necesitamos un temporizador con una resolución mayor. Y eso es precisamente lo que nos dan QueryPerformanceCounter () y QueryPerformanceFrequency (), un método para medir el tiempo con una precisión de menos de 1ms.
QPC devuelve el valor del contador de alta precisión, y QPF su frecuencia (en nº de ciclos por segundo). Ambas usan LARGE_INTEGERs, enteros de 64 bits que dependiendo del compilador son o no soportados nativamente.
El proceso para medir el tiempo usando estas funciones es bastante sencillo:
LARGE_INTEGER a, b, frecuencia;
//Obtenemos el valor de la frecuencia
QueryPerformanceFrequency (&frecuencia);
//Tomamos la medida inicial
QueryPerformanceCounter (&a);
//CODIGO
//Tomamos la medida final
QueryPerformanceCounter (&b);
//Calculamos la diferencia, y la dividimos por la frecuencia
double segundos = (b.QuadPart - a.QuadPart) / frecuencia.QuadPart;
El campo “QuadPart” es un entero de 64 bits, y si el compilador no lo acepta habrá que trabajar en su lugar con LowPart y HighPart. En cualquier caso, yo nunca he tenido ese problema.
Otra cosa a tener en cuenta si estais adaptando desde GetTickCount () es que la frecuencia de QPF va en ciclos / segundo. Por lo que al dividir, la medida de tiempo que se obtiene viene en segundos, y no en ms como la de GetTickCount ().
Y una última observación: La frecuencia se suele calcular al principio y dejar guardada en una variable, porque se supone que no va a cambiar. Normalmente es así, pero no siempre. Pensad en los portátiles con sistemas que reducen el consumo de energía precisamente variando la frecuencia del micro, en esos casos puede que sea interesante controlar si la frecuencia ha cambiado o no.
Un sistema que funciona es tomar la medida tanto con QPC/QPF como con GetTickCount (), y comparar los resultados. Si son demasiado distintos (por ejemplo, medio segundo de diferencia entre uno y otro), entonces se puede suponer que QPC/QPF ha fallado, y sería momento de volver a calcular la nueva frecuencia.