Programación en Lenguaje Ensamblador

-El Verdadero Lenguaje de las Máquinas-

Nuevos Informes del Minijuego en Ensamblador

–Llamadas a API en ASM y Game Loop–

Como no tengo un tema fijo del que hablar y llevo demasiado tiempo sin escribir va uno de estos infames informes que no llevan a ningún lado, y para no fastidiar con las quejas de siempre voy a comenzar por platicarles de como va mi clon en ensamblador de Clash at Demonhead y mostrales esta “Picture Semi related”.


Referencia API en ensamblador

De acuerdo, cuando comencé el proyecto estaba buscando una mejor manera de organizar el código para no enredarme como en proyectos pasados y fue cuando me topé con la joyita del Draw de OpenOffice, en estos días he jugado mucho con él y estoy aprovechando para hacer algunos dibujos que ayuden a programa en ASM de manera mas eficiente. Por ejemplo, ahora en lugar de consultar la ayuda de las funciones del Windows como se muestra en la Microsoft Developer Network (que está escrita en formato C++) estoy creando un recopilado de algunas de las funciones mas utilizadas de la API en el formato de llamada en ensamblador, es decir una serie de instrucciones PUSH, un CALL indirecto y luego recoger el valor de retorno en el acumulador. Cada hoja explica una llamada a función o una estructura diferente y está dibujada de modo que los tipos de datos (casi en su totalidad enteros de 32 bits) sean intuitivos. Con explicaciones incluidas y algunas marcas de información rápida como a que DLL pertenecen y si incluyen una versión unicode. Por cierto, antes de que me pidan un link para atesorar un documento tan util como este y nunca lo usen les tengo que advertir que NO pienso hacer un recopilado de todas las funciones de las API’s sino solo de aquellas que vaya necesitando a lo largo de este proyecto. Conforme vaya haciéndolo voy a subir esos datos en formato de imagen a este blog y cuando junte una buena cantidad puede que haga un PDF mas o menos presentable para su descarga.

Explicando el Game Loop

El siguiente punto luego de terminar de representar el mínimo de información de programación Windows en un formato “Assembly Friendly” y antes de entrar en complicaciones con inicializaciones raras quiero arreglar un detalle que se relaciona directamente con la programación de videojuegos. Verán, el mas elemental de los elementos de un videojuego y esto va desde los antiguos jueguitos de arcade de la década de los setentas hasta las mas avanzadas consolas de la actualidad es un ciclo que permite la interacción continua. Algunos simplemente se refieren a el como el MAINLOOP o GAMELOOP. Para que me entiendan, es exactamente lo mismo que cuando uno juega uno de esos juegos de mesa en los que los jugadores toman turnos para lanzar un dado y mover una ficha sobre un tablero. Como por ejemplo el Monopoly, el Juego de la Oca o Serpientes y Escaleras. En estos juegos se tiene un ciclo infinito que termina unicamente cuando alguien gana o dejan de jugar. Si las tiradas de dados se hacen con la suficiente velocidad, digamos unas 60 veces por segundo y al final de cada ronda(entiendase ronda cuando todos han usado su turno para lanzar el dado) se toma una foto de la posición final de las fichas el observador tendrá la impresión de que estas se mueven de manera simultanea. Esto por supuesto es la misma ilusión que nos causa la animación tradicional o el cine y es importante porque una computadora no comprende el concepto de interactividad y se limita solo a ejecutar instrucciones una tras otra de manera secuencial.

El problema es que este ciclo tan importante no es tan sencillo de implementar en un sistema como Windows por una peculiar razón: ¡Las aplicaciones de Windows tienen su propio Game Loop! Y esa no es la peor parte sino que debido al sistema multitarea de los procesadores de Intel que de por si funciona como otro Game Loop implementado por hardware, si uno codifica un Game Loop de la manera tradicional como lo haría con una aplicación del antiguo MS-DOS puede acabar por trabar la aplicación y tendría que recurrir al Task Manager para poder cerrarla a la fuerza en el mejor de los casos. Cuando uno hace un juego para un sistema como Windows lo mas importante es sincronizar el propio Game Loop del juego con el propio Game Loop de las aplicaciones de Windows. Pero primero veamos un poco sobre el Game Loop de Windows.

El Game Loop de Windows

Una de las cosas que distinguíeron a Windows del antiguo MS-DOS fue que era “orientado a eventos” en lugar de ser orientado a comandos. Esta capacidad para detectar eventos en el momento que ocurren y reaccionar ante ellos viene dado por ese Game Loop. Pues en toda aplicación interactiva de Windows en alguna parte hay un ciclo de mensajes que se ejecuta una y otra vez hasta que recibe el mensaje que le dice a la aplicación que debe de terminar. Una aplicación Windows normalmente recurre a una llamada a GetMessage para obtener el mensaje y actuar en consecuencia. El primer problema es que GetMessage se queda esperando a que le llegue un mensaje y no hace nada hasta que este no llega, esto es bueno para una aplicación cualquiera pues permite que el sistema operativo aproveche los recursos en otra cosa pero en un juego esto no sirve. Para poder hacer un GameLoop fluido es necesario usar otra función llamada PeekMessage.

A diferencia de la función anterior, PeekMessage no se queda esperando a que le llegue un mensaje para actuar sino que se asoma a la entrada de mensajes y solo si ve que hay uno en espera va y lo toma, de lo contrario sigue con su camino. Es decir que no se detiene a esperar a que el mensaje llegue como lo hace GetMessage. Obviamente manejar una aplicación con PeekMessage requiere una programación mucho mas avanzada a la que no vale la pena recurrir a menos que el programa tenga que estar al pendiente de muchas otras cosas que no provengan directamente del ciclo de mensajes. Sin duda la parte de la sincronización del ciclo de mensajes de Windows y el Game Loop merece por lo menos una entrada exhaustiva y bien documentada.

Y mas por venir…

¿Y luego que sigue? Pues acabando la sincronización del game loop y el ciclo de mensajes conseguir leer entradas y desplegar datos en pantalla, por suerte el mismo Windows ya nos da todo eso sin mayor problema, la parte dificil sería domesticar las funciones COM de la misma manera que se hizo con la API. Por suerte esto ya lo había hecho hace un par de años y solo es cuestión de que explique con dibujitos su funcionamiento y luego lo reprograme. De momento no me atrevo a aventurar nada mas porque no se con que otra cosa me pueda encontrar en el camino. Por cierto, creo que estos últimos detalles son suficientes para terminar aquella serie de videos del Poor Programmer que dejé inconclusa hace ya tantos meses. Necesito apresurarme porque no quiero que este sencillo proyecto se me frustre como tantos otros. Pues al menos por lo que queda del mes tendré todos los recursos materiales y disposición para poder avanzar en este humilde proyecto, pues a partir de febrero puede que las cosas vuelvan a ponerse tan difíciles para mi como ya es costumbre. Por no mencionar que apenas con estas temperaturas invernales las computadoras trabajan sin dar demasiados problemas.

enero 10, 2011 - Posted by | Uncategorized | , , ,

4 comentarios »

  1. Te recomiendo que lo hagas con OpenGl e implementes rutinas 2D asi te ahorras mucho trabajo sobre el render y demas cosas, ademas no llevaria dependecias.

    Comentarios por StrongCod3r | enero 10, 2011 | Responder

    • Ahora que mencionas OpenGL, creo que voy a transformar los llamados de funcion al igual que estoy haciendo con la API de Windows. Al parecer es posible obtener informacion de hardware muy valiosa con unas pocas llamadas a OpenGL. Es increible que sea mucho mas dificil convertir un formato de llamada de C++ a ASM que implementar una de estas llamadas en el propio ensamblador

      Comentarios por asm86 | enero 10, 2011 | Responder

  2. hey mario.. por que en la paguina nuhalli… pones que vas a utilizar.. c++ siendo que supuesta mente es lo peor para vos?? es solo curiosidad.. acoso el juego no puede se completamente en asm.. asi de paso nos aclaras dudas.. =)

    Comentarios por Pavon | enero 14, 2011 | Responder

    • Creo que esta es una de esas situaciones donde hay que recurrir al «no es lo que tu piensas» o «no era yo». Veras, ese proyecto de Nahualli es en realidad un espejo de un mismo proyecto que se esta cocinando aqui. El proyecto que es netamente de este blog no solo va a ser programado completamente en ASM sino que yo mismo me voy a encargar de todos los aspectos desde la programacion hasta el retoque de los botones de las interfaces pasando por el modelado y el game design, temas de los que no se tanto como de ensamblador. Ese es mi reto personal y no quiero que nadie me ayude.

      Por el contrario, el proyecto de Nahualli es mucho mas abierto, lo unico que ambos comparten son los algoritmos basicos y algunos aspectos de la programacion de Windows. Los integrantes de ese grupo de desarrollo apenas estan saliendo de la adolescencia y muchos de ellos apenas llevan uno o dos semestres de alguna de esas nuevas carreras de desarrollo de videojuegos. Si les digo que todo el juego va a ser 100% en ASM van a salir corriendo. En ese proyecto ‘abierto’ ellos tienen oportunidad de hacer lo que mejor hace cada quien sin meterse en dificultades. De todas formas este malentendido merece que escriba una nota completa en este mismo blog que voy a comenzar a escribir en cuanto termine de escribir este comentario

      Comentarios por asm86 | enero 14, 2011 | Responder


Deja un comentario