Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Mas del Minijuego en Ensamblador: Input, Gameloop y Gráficas

–Funcionalidad básica y como abrir archivos de sprites–

Cualquiera que sepa algo de dibujo a lapiz o que haya convivido con dibujantes está familiarizado con una rueda con una cruz en medio que se supone va a ser un rostro, con unas lineas pálidas y en apariencia sin sentido que nada parecen tener que ver con la obra final y que incluso se borran cuando esta ha sido terminada. Cuando uno contempla a uno de estos verdaderos artistas (no aquellos que en su vida han dibujado solo con papel y lapiz) a veces suele aburrirse al verlos durante minutos o incluso horas trabajando con estas lineas que parecen no tener propósito. Hasta que de pronto, en lo que parece ser una ligera distracción el dibujo comienza a tomar formas reconocibles y es solo durante esos últimos minutos en los que la obra parece haber sido hecha de principio a fin. Incluso puede darnos la impresión de que el artista ya ha terminado su trabajo aun antes de dar los últimos detalles que hacen que la obra se vea verdaderamente completa.

toma externa

Esta pequeña historia sobre dibujos viene por dos razones, la primera es porque mucha gente se me ha acercado preguntando como dibujar tal o cual cosa con ensamblador y la segunda es por lo que llevo del desarrollo del minijuego. Cualquier persona que no sepa nada de programación no le parecerá demasiado impresionante la primera imagen que acompaña a esta entrada y la verdad es que lo único que puede verse del juego es una ventana blanca con un numerito hexadecimal en la esquina. Esta entrada es una respuesta para ambas interrogantes, así que voy a comentarles que es lo que este minijuego ha avanzado y lo que esos numeritos significan.

Monitoreo del Gameloop en Tiempo Real

La última vez que subí una nota de lo que llevaba del minijuego estaba discutiendo como mantener el gameloop a velocidad constante sin importar el desempeño de la PC donde se ejecutara. Por cierto, confundí el nombre de la función del timer del windows, no es timegettime sino GetTickCount. Aunque sospecho que existen otros timers mucho mas precisos. Para poder monitorear las reacciones del gameloop en tiempo real fue necesario desplegar un contador en la esquina de la ventana. La función de la API de Windows para desplegar texto que es mas cercana al hardware es TextOut, aunque como solo puede desplegar cadenas ascii para mostrar el contador de ciclos del gameloop había que convertir el valor binario a una cadena ascii con una función que ya discutí hace tiempo en este mismo blog.

Input Básico, Entrada de Teclado y Memoria Virtual

Cuando el ciclo ya estaba controlado era hora de darle interacción con el usuario. Como solución provisional se usó la función de la API de Windows GetKeyboardState, esta función aunque no da tanto control sobre la entrada de datos como la da el DirectInput si brinda un control bastante fiable basado en un concepto llamado Teclado Virtual. A nivel interno, Windows ve el teclado, el ratón y las combinaciones de teclas como si fueran un solo dispositivo. Cuando uno llama GetKeyboardState la da como argumento una posición de memoria de un buffer de 256 bytes de longitud. Cada una de estas posiciones representa una de estas teclas virtuales, aunque solo usa dos de los 8 bits: El bit 0 se alterna como un switch cada vez que se oprime mientras que el bit 7 se mantiene en uno mientras la tecla está siendo presionada y se pone en cero cuando ha sido liberada. En este caso, dentro del gameloop hay una parte en la que se lee este array de 256 bytes, se evalúa la posición 27 (1B hexadecimal) que representa la tecla ESC y si el bit mas alto está encendido se activa la variable que indica el fin del programa. Esta misma rutina puede modificarse para manejar un control bastante avanzado pero no se compara con las prestaciones que ofrece DirectInput.

Cuando estuvo el ciclo ya dominado lo siguiente era abrir un archivo de imagen y meterlo en un buffer de memoria virtual. El buffer de memoria virtual se puede obtener llamando a VirtualAlloc. Esta función puede darnos buffers de memoria en teoría tan grandes como 4GB pero tampoco vamos a desperdiciar recursos. El asunto comenzó cuando me puse a investigar sobre cual era el formato gráfico mas sencillo para este minijuego. Obviamente no voy a usar archivos JPG porque además de que son sumamente complicados de abrir en ensamblador este minijuego no va a usar sprites fotográficos. Originalmente tenía pensado usar el antiguo formato PCX pero revisando mis viejos documentos encontré que tenía mucho mejor información sobre el formato TGA. Pero antes de entrar en detalle sobre el formato TGA voy a hacer algunos comentarios ofensivos sobre esto de los archivos gráficos.

avance hasta hoy

Archivos de Imagen en Ensamblador: Mito y Realidad

Existe una falsa creencia sobre el manejo de imágenes en programación de que el desplegar un archivo de imagen es algo que toma tan solo una o dos instrucciones. Esto es lo que creen sobre todo gente que viene de ambientes de desarrollo web o que aprendió a “programar” haciendo scripting y no con un lenguaje de programación de verdad. No es muy diferente a los programadores de “alto nivel” que cuando llegan al ensamblador lo primero que preguntan es cual es el OpCode del “Print”. La verdad es la siguiente: Desplegar un archivo de imagen en ASM requiere algunos cientos de lineas. Y aunque todas las imágenes en esencia son un una matriz bidimensional de pixeles existen varios sistemas para almacenar estas matrices en archivos binarios lineales y cada uno es especialmente bueno para un propósito. Por ejemplo los famosos JPG fueron diseñados con el comportamiento de la luz en fotografía en mente mientras que los GIF y PNG se crearon para comprimir dibujos con colores puros y continuos como los usados en animación tradicional. Los famosos BMP de Microsoft parecen ineficientes pero son los que mas fielmente representan los datos de las imágenes porque no tienen pérdida y mas allá de los pixeles existen archivos gráficos vectoriales y combinaciones de ambos conocidas como meta archivos gráficos. Entonces el proceso para abrir un archivo de imagen en ASM (o cualquier lenguaje de programación de verdad) es primero cargar el archivo binario a la memoria y reconstruirlo en esa matriz bidimensional de pixeles, cosa que solo podremos hacer si conocemos como se codifica la información dentro de estos archivos. Bueno, ahora que ha quedado claro lo que es abrir imágenes en ASM voy a seguir hablando del TGA.

TGA o “TARGA” es un formato creado por una antigua empresa de computadoras llamada TrueVision de la que no he sabido nada desde la década de 1990, este formato es extremadamente simple y puede comprimir archivos de dibujo usando la codificación RLE (Run Length Encoding), existen muchas versiones pero la que nos interesa es la conocida como versión 2 que es capaz de desplegar color verdadero de 24 bits (poco mas de 16 millones de colores) sin compresión. Con las técnicas adecuadas podría hacerse un juego muy completo que ocupara menos de 10 megas y si se echa mano del RLE puede que el juego completo no pase de uno o dos (incluyendo el ejecutable que hasta ahora no ha superado los 6000 bytes) y aunque los TGA pueden llegar incluir una gran cantidad de información es posible mantenerlos a un mínimo al grado de que solo cuenten con una cabecera de 18 bytes con información para su reconstrucción y luego los datos de la imagen sin codificar. En próximas notas detallaré como desplegar un archivo de imagen y la mejor manera de manejer sprites usando solo ensamblador. Pero por ahora solo queda decirles algo sobre la primera foto:

Los números que aparecen en esa caja de diálogo son ni mas ni menos que ¡Un archivo TGA cargado en memoria! Todas esas F son valores de pixeles blancos en uno de los extremos de la imagen y los 18 primeros bytes (cada par de cifras representa 8 bits) son el encabezado que contiene toda la información para decodificarlo como ancho, altura, bits por pixel, tipo de compresión y orden en que se deben de dibujar los pixeles. Ya solo me falta inicializar el modo de video y la primera fase del desarrollo del minijuego que es el I/O básico habrá concluido tal y como lo indica el mapa de desarrollo de la segunda imagen. De momento voy a detener aquí la nota porque aún queda mucho por contar en este pequeño desarrollo.

febrero 16, 2011 - Posted by | Uncategorized | , ,

1 comentario »

  1. sigo impresionado

    voy hasta aqui

    pero ya quiero practicar jejeje

    Comentario por Roberto Carlos | abril 15, 2011 | Responder


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: