Allegro puede establecer varias funciones virtuales de temporización, todas funcionando a diferentes velocidades.
Bajo DOS reprogramará el reloj contínuamente para asegurarse de que todas se llaman en el momento adecuado. Dado que estas rutinas alteran el chip de temporización de bajo nivel, estas rutinas no deben usarse con otras rutinas de temporización del DOS, como la rutina uclock() del djgpp.
En otras plataformas están implementados usando hilos, que corren de forma paralela al hilo principal. Por lo tanto las rutinas de llamada instaladas con temporizadores no bloquearán al hilo principal cuando sean llamadas, por lo que podría necesitar dispositivos de sincronización apropiados (ej: semáforos, mutexes, etc) cuando acceda a datos compartidos por el hilo principal y su rutina de temporización. (Por ahora Allegro no provee este tipo de dispositivos de sincronización.)
int install_timer();
Instala el controlador de temporización de Allegro. Debe hacer esto antes
de instalar cualquier rutina de temporización propia, e incluso antes de
visualizar el puntero del ratón, reproducir una animación FLI, reproducir
música MIDI y usar cualquiera de las rutinas GUI. Devuelve cero con éxito,
o un número negativo si hubo problemas (pero puede decidir si quiere
verificar el valor de retorno de esta función, dado que es muy poco
probable que pueda fallar).
Relacionado con: remove_timer, install_int.void remove_timer();
Relacionado con: install_timer, allegro_exit.int install_int(void (*proc)(), int speed);
Relacionado con: install_timer, remove_int, install_int_ex.int install_int_ex(void (*proc)(), int speed);
Si no queda espacio para un temporizador nuevo, install_int_ex() devolverá un número negativo, o cero de otro modo. Sólo puede haber 16 temporizadores a la vez, y algunas partes de Allegro (código GUI, rutinas para visualizar el puntero del ratón, rest(), el reproductor de ficheros FLI o MIDI) necesitan instalar sus propios temporizadores, por lo que debería evitar usar muchos a la vez.SECS_TO_TIMER(secs) - pase el número de segundos entre cada tick MSEC_TO_TIMER(msec) - pase el número de milisegundos entre cada tick BPS_TO_TIMER(bps) - pase el número de ticks por segundo BPM_TO_TIMER(bpm) - pase el número de ticks por minuto
Su función será llamada por el controlador de interrupciones de Allegro y no directamente por el procesador, por lo que puede ser una función normal en C, y no necesita ninguna función de envoltura. Sin embargo tenga en cuenta que será llamada en contexto de interrupción, lo que impone muchas restricciones sobre lo que puede hacer en ella. No debería usar grandes cantidades de pila, no puede hacer llamadas al sistema operativo o usar funciones de la biblioteca de C, o contener código con operaciones en coma flotante, y debe ejecutarse rápidamente. No intente hacer cosas complicadas con su temporizador: como regla general debería ajustar un par de valores y actuar en consecuencia de éstos dentro de su bucle de control principal.
En un entorno DOS en modo protegido como djgpp, la memoria es virtualizada y puede ser paginada a disco. Debido a la no-reentrancia del DOS, si una paginación al disco ocurre dentro de su función de temporización, el sistema morirá de forma dolorosa, por lo que debe asegurarse de bloquear (lock) toda la memoria (de código y datos) que sea modificada dentro de su rutina de temporización. Allegro bloqueará todo lo que use, pero usted es responsable de bloquear su rutina de temporización. Las macros LOCK_VARIABLE(variable), END_OF_FUNCTION(nombre_de_funcion), y LOCK_FUNCTION(nombre_de_funcion) pueden ser usadas para simplificar esta tarea. Por ejemplo, si quiere que su temporizador incremente una variable de contador, debería escribir:
y en su código de inicio debería bloquear la memoria de esta manera:volatile int contador; void mi_temporizador() { contador++; } END_OF_FUNCTION(mi_temporizador);
Obviamente esto puede ser extraño si usa estructuras de datos complicadas y llama otras funciones desde su temporizador, por lo que debería crear sus temporizadores tan simples como pueda.LOCK_VARIABLE(contador); LOCK_FUNCTION(mi_temporizador);
Relacionado con: install_timer, remove_int, install_int.void remove_int(void (*proc)());
Relacionado con: install_int, install_int_ex.int install_param_int(void (*proc)(void *), void *param, int speed);
Relacionado con: install_timer, remove_param_int, install_param_int_ex, install_int.int install_param_int_ex(void (*proc)(void *), void *param, int speed);
Relacionado con: install_timer, remove_param_int, install_param_int, install_int_ex.void remove_param_int(void (*proc)(void *), void *param);
Relacionado con: install_param_int, install_param_int_ex, remove_int.int timer_can_simulate_retrace()
Relacionado con: timer_simulate_retrace, timer_is_using_retrace.void timer_simulate_retrace(int enable);
- Nunca use el simulador de retrazo en modos SVGA. Funcionará con algunas tarjetas, pero no en otras, y tiene conflictos con la mayoría de las implementaciones VESA. La simulación de retrazo sólo es fiable en el modo 13 de la VGA y en el modo-X.
- La simulación de retrazo no funciona bajo win95, porque win95 devuelve basura cuando intento leer el tiempo transcurrido del PIT. Si alguien sabe cómo solucionar esto, ¡que por favor me mande un email!
- La simulación de retrazo conlleva mucha espera del controlador de temporización con las interrupciones desactivadas. Esto reducirá la velocidad del sistema de forma significante, y podría causar estática el reproducir sonidos con tarjetas SB 1.0 (ya que no soportan la auto-inicialización DMA: las SB 2.0 y superiores funcionarán bien).
Considerando todos estos problemas, se aconsejaría no depender del simulador de retrazo vertical. Si está trabajando en modo-X, y no le importa que su programa funcione bajo win95, está bien, pero sería buena idea dejar al usuario la posibilidad de desactivarlo.
La simulación de retrazo debe ser activada antes de usar las funciones de triple buffer en resoluciones del modo-X. Esto puede ser útil también como una simple detección de retrazo, ya que leer vsync() puede hacer que ignore algún retrazo de vez en cuando si justo una interrupción de sonido o temporización ocurre a la vez. Cuando la simulación de retrazo está activada, vsync() comprobará la variable retrace_count en vez de leer los registros de la VGA, para que no pierda ningún retrazo incluso si está siendo enmascarado por otras interrupciones.
Relacionado con: enable_triple_buffer, install_timer, retrace_count, retrace_proc, request_scroll, vsync, timer_can_simulate_retrace, timer_is_using_retrace.int timer_is_using_retrace()
Relacionado con: timer_simulate_retrace, timer_can_simulate_retrace.extern volatile int retrace_count;
La velocidad del retrazo depende del modo gráfico. En el modo 13h y resoluciones en modo-X de 200/400 líneas hay 70 retrazos por segundo, y en modos-X de 240/480 líneas hay 60. Puede ser tan bajo como 50 (en modo 376x282) o tan alto como 92 (en modo 400x300).
Relacionado con: timer_simulate_retrace, retrace_proc.extern void (*retrace_proc)();
Relacionado con: _set_color, timer_simulate_retrace, timer_is_using_retrace, retrace_count.void rest(long time);
Relacionado con: install_timer, rest_callback.void rest_callback(long time, void (*callback)())
Relacionado con: install_timer, rest.