Este documento contiene las descripciones de las funciones del programa.
inicializa_mensajes_de_error(void);Description
Inicializa las variables del sistema de errores. El sistema
de errores se basa en lo siguiente: cuando se quiere dar un mensaje normal
al usuario, se muestra en pantalla o se usan las rutinas de logging. Sin
embargo, cuando hay un error grave, es posible que además el sistema no
esté en un estado adecuado como para mostrarlo. Por eso, se almacena el
mensaje de error en un array estático, y al finalizar el programa se
muestran todos de golpe, en orden de ocurrencia.
Se usa un array estático, ya que así no puede dar fallo el malloc para
reservar memoria para la cadena del mensaje (cosa que sí puede pasar con
el sistema de logging), y para que la inicialización del propio sistema
de errores no pueda fallar.
eprintf(char *msg, ...);Description
Rutina de parámetros variables tipo printf, que almacena en
un array estático un mensaje que será visualizado al salir del programa.
Primero convierte la lista de parámetros en una cadena (buf), para luego
almacenar esa cadena buf en el array, en la posicion adecuada.
NOTA: si el programa llena la tabla de errores, se produciría un desborde
con el siguiente, por lo que el programa aborta inmediatamente y sale con
exit(valor_error).
Example
if (retorno != 0) { eprintf ("Error al volver de la rutina, retorno %d", retorno); return retorno; }
muestra_mensajes_de_error(void);Description
Esta función muestra los mensajes de error que se han ido
acumulando, en orden de ocurrencia.
Atención: se debe usar sólo cuando ya se ha salido del modo gráfico,
es decir, desde finaliza_programa.
dibujar_pelota(DATOS_JUEGO *datos);Description
Dibuja la pelota en las coordenadas x_p e y_p. Esas mismas coordenadas se guardan en una lista al llamar a marca_zona_borrado para su posterior sobreescritura antes del siguiente redibujado.
dibujar_raqueta(DATOS_JUEGO *datos);Description
Dibuja la raqueta en la coordenada x_r. Esa misma coordenada se guarda en una lista al llamar a marca_zona_borrado para su posterior sobreescritura antes del siguiente redibujado
dibujar_marcador(BITMAP *bmp, DATOS_JUEGO *datos);Description
Imprime los puntos y las vidas en unas coordenadas fijas de la pantalla
dibujar_ladrillos(DATOS_JUEGO *datos, int x1, int y1, int x2, int y2);Description
Dibuja los ladrillos en una pantalla virtual dependiendo del mapa de ladrillos. Para ello transformamos las coordenadas lógicas del bitmap de ladrillos en coordenadas físicas para ajustar el tamaño de los ladrillos en la pantalla. También marcamos los bordes de cada ladrillo, comprobando que el color del ladrillo sea diferente. Se le pasa la estructura de datos y la zona de ladrillos que hay que redibujar.
dibuja_pantalla(DATOS_JUEGO *datos);Description
Función que llama a las funciones de dibujado y redibujado de la raqueta y la pelota en bmp(pantalla virtual) y el marcador en la pantalla. Vsync evita que se produzca parpadeo en la pantalla. Blit transfiere todo lo que se ha dibujado en bmp a la pantalla. Recupera_zonas_pantalla redibuja en la pantalla la pelota y la raqueta.
inicializa_motor_grafico(void);Description
Inicializamos los módulos gráficos de dibujado y redibujado del juego. 1º configuramos la resolución de la pantalla, establecemos los márgenes de la zona de la pantalla a la que transferimos el bitmap bmp y finalmente inicializamos las listas de borrado de coordenadas lógicas y físicas y la tabla de colores para los ladrillos.
Return Value
Devuelve 0 si se realizó todo con éxito, distinto de 0 en caso contrario.
inicia_tabla_de_colores(void);Description
Rellena el array de colores con la información adecuada para que el juego dibuje bien los ladrillos.
finaliza_motor_grafico(void);Description
Llama a destruye_lista_borrado que "limpia" las listas de coordenadas físicas y lógicas.
dibuja_marco_pantalla(BITMAP *bmp);Description
Dibuja los contornos de la pantalla en los que no se dibujará nada de la pantalla virtual.
obten_escalado_optimo(void);Description
Función que obtiene el escalado óptimo para dibujar la pantalla en un tamaño adecuado.
Return Value
Devuelve 0 si la resolución de pantalla actual es demasiado pequeña. Devuelve 1 o más para indicar el escalado óptimo.
color_ladrillo_diferente(DATOS_JUEGO *datos, int x, int y, int col);Description
Función que comprueba si el ladrillo de la posición x e y es del mismo color que le pasamos como parámetro.
Return Value
Devuelve 0 si el ladrillo es del mismo color; 1 en caso contrario o en caso de que las coordenadas no estén dentro de la pantalla.
escribe_texto(BITMAP *bmp, FONT *font, int x, int y, int w, int h, int color_texto, int color_fondo, char *texto, ...);Description
Función que envuelve a _escribe_texto, permitiendo pasar un número de parámetros variables para formatear cadenas. Se pasa: el bitmap de destino, el tipo de letra, la posición x, y en coordenadas de pantalla físicas, el ancho,alto físico, y el color. Si el color es negativo, el texto será transparente.
Example
escribe_texto (screen, font, 0, 0, 100, 20, 12, -1, "Tengo %d años", 5);
_escribe_texto(BITMAP *bmp, FONT *font, int x, int y, int w, int h, int color_texto, int color_fondo, char *texto);Description
Función que crea un bitmap temporal, imprime el texto, y reescala ese bitmap en el destino. Acepta parámetros como los de escribe_texto. Sólo se llama internamente.
init_hiscore(void);Description
Inicializa el sistema de errores, rellenando la tabla con valores predefinidos y creando el fichero de records.
shutdown_hiscore(void);Description
Función que guarda en el fichero de récords los records actuales.
draw_entry_box(BITMAP *bmp, int which);Description
Función de ayuda de score_table que muestra una caja enmarcada con un cursor para introducir el nombre del jugador en la tabla de récords. Se le pasa un puntero a BITMAP y la posición en la tabla donde será dibujada la caja.
score_table(int score);Description
Función de tabla de récords. Se le pasa un parámetro que es
la puntuación del jugador tras jugar una partida. La función determina
si la puntuación no es suficiente para inscribirse. En este caso,
simplemente muestra la tabla de récords hasta que se pulse una tecla.
Si se ha superado un récord, se muestra la tabla de récords con un espacio
enmarcado y un cursor parpadeante. Es ahora cuando el usuario simplemente
teclea su nombre y aparecerá en los récords.
incrementar_ticks(void);Description
Incrementa el contador de ticks. Esta función se ejecuta como una interrupción a la velocidad que nosotros indiquemos mediante install_int_ex. La función debe hacer cuanto menos mejor para no "chupar" recursos a la CPU.
incrementar_secs(void);Description
Incrementa el contador de segundos. Esta función se ejecuta como una interrupción a la velocidad que nosotros indiquemos mediante install_int_ex. La función debe hacer cuanto menos mejor para no "chupar" recursos a la CPU.
inicializa_programa(int argc, char *argv []);Description
Esta función se encarga de poner en orden todo lo relacionado con el juego. Primero inicializa algunas funciones de allegro, teclado e interrupciones. A continuación lee la linea de comando en busca de parámetros útiles, marcando diferentes bits de estados en la bandera global. Luego, intenta entrar en un modo gráfico, desde el cual ya es posible mostrar mensajes de una forma portable en cualquier plataforma. Excepto la decodificación de la linea de comando, y el acto de entrar en modo gráfico, el resto del programa puede usar el modo gráfico para mostrar mensajes, ya sea de forma propia o mediante lprintf.
Return Value
(int) Devuelve cero con éxito, cualquier otro número si la rutina considera que el programa no debería continuar su ejecución, por error grave.
finaliza_programa(void);Description
Esta función finaliza todo el juego, liberando memoria, escribiendo ficheros (si es necesario), y devolviendo al ordenador a un modo aceptable para el usuario (es decir, usable). Es la función que hay que llamar antes de salir, para asegurarnos de que no queda ningún cabo suelto. Si se necesita hacer una salida de emergencia con exit (num_error), es recomendable llamar antes a esta función.
decodifica_linea_de_comandos(int argc, char *argv []);Description
Recorre la linea de argumentos intentando entenderlos, activando ciertas variables de estado globales. Si es necesario leer parámetros o algo así, los lee en formato ASCII y los convierte a UTF-8.
Return Value
(int) Devuelve cero con éxito, o cualquier otro número cuando la función cree que el programa no merece continuar, por error grave.
entra_en_modo_grafico(void);Description
Funcion mínima que intenta entrar en un modo gráfico seguro, para al menos poder seguir la ejecución del programa. Entra en una resolución 'no determinada' (cuidado con SCREEN_W y SCREEN_H), y siendo posiblemente el modo de 8 bits, ajusta la paleta. Tras esto, limpia la pantalla a color blanco, para que las letras se impriman en negro. Si el bit BIT_CAMBIO_RES está activo, muestra un menú de selección para elegir una resolución de pantalla.
Return Value
(int) Cero con éxito, cualquier otro número con fracaso. En este caso, el programa DEBE abortar, ya que es vital entrar en modo gráfico.
sal_del_modo_grafico(void);Description
Pequeña función que hace de intermediaria con el hardware. Pone el modo texto (o grafico) anterior a la ejecucion del programa.
lee_configuracion_del_fichero_cfg(void);Description
Especifica el fichero .cfg que se usará para salvar algunos datos del juego, como resolución, fichero logging, etc. Lee automáticamente del fichero algunos datos y los usa si es necesario, como por ejemplo el de un fichero logging especifico.
muestra_ayuda_linea_de_comando(void);Description
Esta función es llamada desde finaliza_programa si el bit BIT_SHOW_HELP fue activada antes. Se supone que se está en modo texto y se quiere ver la ayuda rápida del programa. Mediante allegro_message se imprime lo pedido.
carga_nivel(DATOS_JUEGO *datos, int *nivel);Description
Función que carga el mapa de ladrillos que sigue a continuación, comprobando previamente que existe siguiente nivel, parando el juego mediante la activación de los flags correspondientes si no existen más mapas de ladrillos.
Return Value
Devuelve 1 si el mapa de ladrillos se cargó con éxito; 0 en caso contrario.
inicializa_datos_fijos(DATOS_JUEGO *datos);Description
Inicializa los datos que tienen que permanecer constantes al principio de cada partida.
inicializa_datos_nivel(DATOS_JUEGO *datos);Description
Función que inicializa los datos y coordenadas al valor que deben tener al principio de cada nivel.
bucle_juego(DATOS_JUEGO *datos);Description
Función en la que se hacen las llamadas que inicializan los datos y se llama a la función "núcleo" que ejecuta el bucle principal del juego.
Return Value
Devuelve 0 si todo se llevó a cabo con éxito. Distinto de 0 en caso contrario.
procesa_juego(DATOS_JUEGO *datos);Description
Función "núcleo" que realiza el bucle del juego hasta que se activen o el BIT_GAME_OVER, o el BIT_SALIR_DE_JUEGO. Dentro del bucle se realizan todos los chequeos correspondientes a las reglas del juego, el bucle lógico y el redibujado de los elementos en pantalla.
juego(void);Description
Función principal del juego. Se diferencia de main por varias razones, siendo la más importante que el ordenador ya está "aislado" o "abstraído" por Allegro y demás funciones. Es decir, aquí ya estamos en un modo gráfico útil, con variables inicializadas, no hace falta llamar finaliza_programa desde ninguna parte (se hace desde fuera), etc. Además, esto controla principalmente los menús y el bucle del juego.
Return Value
(int) Cero si el juego se ejecutó con éxito, otro número si hubo problemas.
inicializa_datos_juego(void);Description
Función que crea una estructura DATOS_JUEGO y la pone a cero.
Return Value
(DATOS_JUEGO*) Puntero a estructura. NULL si hubo problemas.
destruye_datos_juego(DATOS_JUEGO *datos);Description
Función que destruye una estructura de DATOS_JUEGO antes creada por inicializa_datos_juego.
carga_mapa_ladrillos(char *texto);Description
Carga en memoria un fichero gráfico que contiene el mapa de ladrillos. Pasar como parámetro el nombre del fichero gráfico a cargar. El fichero gráfico debe estar a una profundidad de color de 8 bits (256 colores), y debe tener un mínimo de tamaño de RES_LOGICA_X / TAM_CELDA por RES_LOGICA_Y / TAM_CELDA (que actualmente equivale a una imágen de 52x40). En otras palabras: si la imágen es más grande, sólo se usará la esquina superior izquierda, el resto será descartado.
Return Value
(BITMAP *) Devuelve puntero al mapa de ladrillos o NULL si hubo fallo.
dibuja_menu(void);Description
Función que muestra el menú con las opciones en pantalla.
inicializa_listas_borrado(void);Description
Función que crea las listas lógica y física que almacenan las coordenadas de los elementos en pantalla para su borrado y redibujado.
Return Value
0 si se crean las listas con éxito; distinto de 0 en caso contrario.
destruye_lista_borrado(void);Description
Función que destruye las listas lógica y física de borrado y redibujado de los elementos.
limpia_lista_borrado(LISTA_BORRADO *lista);Description
Función que vacía una lista lógica de elementos. Se llama cuando ya se ha procesado una lista y para la siguiente pasada se requiere tener la lista limpia.
marca_zona_borrado(LISTA_BORRADO *lista, int x, int y, int w, int h);Description
Esta función será usada por las rutinas gráficas para indicar que una zona de pantalla ha sido sobreescrita, y será necesario redibujarla en el siguiente frame. Se usa por ejemplo desde las funciones que dibujan la pelota o la raqueta. Se le pasan las coordenadas lógicas de la pantalla virtual.
recupera_zonas_borrado(DATOS_JUEGO *datos);Description
Esta función recorre la lista de zonas marcadas para borrar, y por cada una de ellas llama a la de redibujado de ladrillos. Al acabar llama a limpia_lista_borrado, para el próximo borrado.
recupera_zonas_pantalla(BITMAP *bmp, DATOS_JUEGO *datos);Description
Esta función recorre la lista de zonas marcadas para dibujar, y por cada una de ellas llama a la de redibujado del bitmap bmp en pantalla. Al acabar llama a limpia_lista_borrado, para el próximo redibujado.
inicializa_logging(unsigned long max_mensajes);Description
Esta función prepara el módulo de logging del programa. Dado
que este juego no es una aplicacion crítica, y a que puede ser útil para
la depuración/seguimiento del programa por cualquier persona, incluso
ajena al proyecto, se usará un sistema de listas enlazadas que almacenarán
una cola de mensajes variable, que puede ser impresa en pantalla, o
almacenada en un fichero, etc...
Si la inicializacion tiene éxito, se hacen unos lprintfs con la fecha
de comienzo de logging. Se pasa como parámetro el numero máximo de
mensajes que se quiere tener en la lista enlazada. Si se pasa cero, se
asumirá un valor de uno. Se recomiendan valores de entre 50 y 200.
Return Value
(int) Cero con éxito, positivo en caso contrario
finaliza_logging(void);Description
Esta función libera la memoria usada por los mensajes de logging. Debe ser llamada antes de salir del juego, para garantizar la limpieza de memoria.
libera_mensajes_log(void);Description
Esta función libera la memoria usada por los mensajes que estan en la lista enlazada, sin destruir los terminadores.
destruye_mensaje_log(MENSAJE *men);Description
Esta función destruye un mensaje de la cadena, reenlazándola después si es posible con sus vecinos.
lprintf(char *msg, ...);Description
función para hacer logging. Añade un mensaje más a la cadena
de mensajes por el final. Si esta especificado globalmente, añade el
mensaje automáticamente a un fichero de texto especificado por la variable
path_fichero_log. El mensaje de logging no se mostrará a no ser que el
programa esté mostrando los diversos mensajes en alguna zona de la
pantalla, manualmente. Además, si el bit de logging no esta activado, la
petición sera descartada sin mostrar error alguno.
Si se usa \n a mitad de una cadena, ésta será troceada y en realidad se
crearán dos mensajes o más. Esta función es en realidad un "filtro"
para crea_mensaje, que trata la cadena y la trocea si es necesario. Para
crear una línea vacía, no basta con \n, hay que poner al menos un espacio
como carácter. Tras añadir el mensaje, llama a
elimina_excedente_lista_log. No hace falta acabar los mensajes con \n,
porque el último \n es automatico.
Example
lprintf ("Partida iniciada.\nMemoria restante libre %d", mem_bytes_libres);
crea_mensaje_log(char *texto);Description
Esta es la rutina que hace el trabajo sucio de lprintf. Se le pasan cadenas de texto sin caracteres \n, y crea en memoria el objeto de la lista enlazada con el texto, y añade el mensaje a un fichero de logging en caso de que esa opción estuviese activada. Es una función interna, no usar directamente.
comprueba_validez_fichero_log(char *nombre_fichero);Description
Comprueba si nombre_fichero es un fichero de log que se puede usar, y ajusta la variable path_fichero_log en consecuencia. Esta rutina llama siempre a eprintf si hay algun inconveniente, como que ya hay un fichero log siendo usado (solo puede haber uno). Si no hay problemas, se activa el BIT_LOG_A_FICHERO. Se presupone que el texto del fichero _YA_ se pasa como UTF-8, y NO ASCII. Tener cuidado con eso. Si el nombre del fichero de logging es NULL, se desactivan los logs.
Return Value
(int) Cero con éxito, un numero positivo con error.
elimina_excedente_lista_log(void);Description
Esta función va eliminando mensajes de la lista enlazada, siempre y cuando el número total sea mayor o igual al numero máximo de mensajes permitidos en la lista. Función interna.
imprime_informacion_sistema(unsigned char salida_lprintf);Description
Función genérica que muestra información sobre el sistema gracias a las variables de Allegro. Puede ser llamada para mostrar la información en una pantalla de texto (antes o tras un modo gráfico), o para mandar la información al sistema de logging. Para hacer esto último, el parámetro de la función debe ser distinto de cero.
Example
int main (void) { allegro_init(); imprime_informacion_sistema (0); return 0; }
hay_colision(DATOS_JUEGO *datos, fixed dx, fixed dy);Description
Esta función es genérica para detectar las colisiones tanto de los bordes de la pantalla como de la raqueta como de los ladrillos. Acepta como parámetros la posición de pantalla que hay que comprobar.
Return Value
(int) Cero si no hubo colisión. Cualquier otro número con colisión.
detectar_colision_pelota(fixed *dx, fixed *dy, DATOS_JUEGO *datos, int volver);Description
Detecta si la pelota colisiona con los laterales de la pantalla, la parte superior de ésta, o con la raqueta, en cuyo caso cambiará de dirección evitando salirse de la pantalla. Aparte de modificar los valores de dx y dy, también hay que modificar el ángulo de datos, para que desde fuera el cambio de dirección afecte al bucle de desplazamiento.
avanza_pelota(DATOS_JUEGO *datos);Description
Función compleja que tiene como tarea mover la pelota en
la dirección indicada por el ángulo y la longitud. Lo que hace la función
es 'trocear' la longitud en pequeños incrementos de un pixel e ir
comprobando las colisiones en cada segmento. De esta forma nos evitamos
saltar paredes y las colisiones serán visualmente perfectas, aunque siempre
habrá errores despreciables en los cálculos.
La función va moviendo la pelota, y por cada segmento llama a la función
detectar_colision_pelota, que determina las colisiones usando los
incrementos dx y dy.
detectar_muerte_pelota(DATOS_JUEGO *datos);Description
Detecta si la pelota se "escapa" por el límite inferior de la pantalla, en cuyo caso activará la variable parar_juego.
detectar_colision_raqueta(DATOS_JUEGO *datos);Description
Detecta si la raqueta a llegado a los límites izquierdo o derecho de la pantalla. => Si la raqueta llega a los extremos izquierdo o derecho de la pantalla el incremento de la raqueta no variará.
mover_raqueta(DATOS_JUEGO *datos);Description
Mueve la raqueta incrementando/decrementando x_r con dr según sea esta positiva o negativa.
bucle_logico(DATOS_JUEGO *datos);Description
Función que recibe *datos y llama a todas las funciones de detección de colisiones, y a las de mover la raqueta y la pelota.
recoge_entrada_usuario(DATOS_JUEGO *datos);Description
Detecta si el usuario pulsa las teclas que mueven la raqueta, en cuyo caso incrementará/decrementará la variable dr, que mueve la raqueta a izquierda o a derecha según sea esta positiva o negativa. Si el usuario pulsa ESC, incrementará la variable parar_juego.
elimina_ladrillo(DATOS_JUEGO *datos, int col_x, int col_y, int col);Description
Esta función elimina un ladrillo del mapa tras una colisión. Se le pasa la posición x, y en coordenadas lógicas ya divididas por TAM_CELDA, y entonces se comprobará realmente si había un ladrillo. Se usa recursividad para eliminar los ladrillos adyacentes simulando una función de rellenado gráfico con el color cero.
comprueba_si_quedan_ladrillos(DATOS_JUEGO *datos);Description
Esta función recorre con un bucle doble anidado el mapa de ladrillos e incrementa la variable parar_juego si es necesario, indicando además mediante el bit BIT_SIGUIENTE_NIVEL si se acabó el nivel con éxito.
colision_pelota_raqueta(DATOS_JUEGO *datos, fixed desplazamiento);Description
Detecta si habrá colisión horizontal con la pelota. Esto se hace simplemente mirando si el rectángulo de la raqueta sobreescribe al de la pelota.
Return Value
(int) cero si no hubo colisión.
main(int argc, char *argv []);Description
Función principal de todo programa C. Esta función llama a inicializa_programa, que prepara el programa para ser ejecutado. Luego, pasa el control al bucle principal del juego. Cuando vuelve, finaliza el programa y se libera la memoria del juego.
Return Value
(int) Cero con éxito, otro valor si hubo algún fallo.