Category: Proyectos


Siempre había tenido curiosidad por la programación gráfica en las tres dimensiones, pero los comentarios de la gente que me hablaba de ello hacían que decidiera aplazar mi inmersión en el tema e incluso olvidarme de ello. Curiosamente todos esos comentarios coincidían en que tanto OpenGL como DirectX eran APIs difíciles de aprender y para las que había que tener un conocimiento muy fuerte de las matemáticas.

Pues bien, os diré que todo depende de lo que quieras hacer. Mostrar una simple figura geométrica y rotarla es muy sencillo. Pero si ya quieres desplegar mallas más complejas, con texturas, mapas de normales y especulares, iluminación y cámara, el asunto se torna un poco más complicado y laborioso. Pero si bien es cierto que tanto OpenGL como DirectX pueden asustar con sólo echar un pequeño vistazo a la documentación o a algún ejemplo de cierto calado, realmente, para hacer cosas básicas (y no tan básicas) lo más importante no es conocer dichas APIs, sino los conceptos, su funcionamiento interno, y tener una pequeña base de álgebra lineal y física. Después, el aprender una u otra biblioteca a un nivel que te permita hacer algo curioso se hace inmensamente más llevadero.

Comencé a estudiar OpenGL, ya que Android e iOS lo utilizan, y, ya que me ponía a aprender algo, debía valorar qué usos y aplicaciones prácticas poder darle de cara a un posible futuro profesional (el desarrollo para dispositivos móviles lleva tiempo en pleno boom). Pero una oferta de trabajo interesante como programador de videojuegos para Windows me hizo interrumpir mis avances con OpenGL y pasarme a DirectX con la finalidad de crear una aplicación 3D que me sirviera de muestra, tal y como pedían en la oferta. Así pues en más o menos un mes conseguí hacer esto:

La aplicación hace uso de la biblioteca libre Assimp para la carga de los modelos y escenarios, de DirectX 9.0c para el trabajo sucio y de los shaders para el renderizado final, concepto que también se me tornaba oscuro hasta hace poco (¡lo importante que es hacerse con un buen libro!).

Aún me queda mucho por aprender; La programación gráfica es un océano de técnicas, conceptos y conocimientos multidisciplinares. Pero la parte más complicada, que es empezar y asentar los conocimientos fundamentales y más comunes, ya está conseguida.

Anuncios

El título lo dice todo. La segunda parte del videojuego, Elvira: The Jaws of Cerberus, contaba con traducción al castellano, pero éste, el primer Elvira, no. Y además en aquel momento, allá por el 2005, ni siquiera la scene de traducción indie se había decidido a meterle mano. Como primer RPG con el que disfruté de verdad, no podía dejar pasar la oportunidad para marcarme un nuevo reto y sacar provecho y desarrollar de forma simultánea algunas de mis muchas facetas.

El trabajo que me llevó fue duro al principio. Sobre todo porque quería hacerlo bien. Previamente había hecho algún pinito con editores hexadecimales y desensambladores para pequeños arreglos puntuales. Pero para este proyecto tuve que sacar el armamento pesado de ingeniería inversa y dedicarme a tiempo completo en cuerpo y alma a ello, tanto, que conseguí terminarlo en poco más de un mes.

Busqué el texto en los archivos con un editor hexadecimal. No todo él se encontraba en un único archivo binario a partir del cual se cargara dinámicamente durante el juego. También el ejecutable incorporaba cadenas de texto estáticas, es decir, hardcoded. De hecho contenía todas las cadenas correspondientes a los cuadros de diálogo emergentes del videojuego, como los de la pausa o los de salvar y cargar la partida.

Pero quedaba muy mal traducir sólo los diálogos de los personajes y los cuadros de diálogo emergentes, dejando en inglés el resto de la interfaz gráfica de usuario y el poco texto que aparecía en ciertas imágenes del juego. Como ya he dicho, quería hacerlo bien, y considero que la coherencia es imprescindible en un trabajo de mínima calidad. Para descubrir qué codificación tenían los archivos .VGA (obviamente eran los de las imágenes) es donde entró en juego el maravilloso desensamblador (IDA Pro). Desensamblando completamente el ejecutable me llevé una sorpresa que me hizo entender muchos detalles de la programación de antaño. Culpa de los programadores, culpa del compilador, el caso es que había un caos importante en la organización, estructura y secuencia del código ensamblador, con numeroso código redundante o llamadas a procedimientos que no venían a cuento. Esto hizo que me llevara más tiempo de lo debido dar con el algoritmo de descompresión de las imágenes, el cual al final resulto tener cierta similitud con el RLE.

El siguiente paso, lógicamente, fue la programación, Turbo C++ en mano, de las dos herramientas imprescindibles para llevar a cabo toda la traducción. Primeramente una herramienta que extrajera los textos del archivo binario en un archivo de texto plano y que introdujera de nuevo en el binario la traducción realizada, modificando en consecuencia la cabecera  de éste debido a la mayor o menor longitud de las cadenas de texto una vez traducidas al castellano. Y segundo, una herramienta que descomprimiera las imágenes, las guardara en formato crudo para poder editarlas con un programa de dibujo, y las comprimiera de nuevo con el mismo algoritmo empleado por Elvira. Por otro lado, las pocas cadenas de texto contenidas en el ejecutable tuve que traducirlas directamente con el editor hexadecimal y siempre buscando la mismas longitudes de cadena que las originales, pues de lo contrario, las posiciones relativas de textos y código cambiarían y el ejecutable no cargaría. La alternativa de recompilar suponía un arduo trabajo que no compensaba para unas pocas cadenas y no daba garantías de que todo funcionara correctamente después. Esto se traduce en que, aunque se comprenda perfectamente, probablemente habrá palabras puntuales que no sean las más adecuadas y naturales para la frase (por ejemplo, “y entra” en lugar de “e introduce” en la siguiente captura).

Del mismo modo también consideré contraproducente investigar más en profundidad para localizar dónde se encontraba la fuente de texto para editarla y añadirle los caracteres propios del castellano, las tildes y la eñe. Pero sí pensé, si llegaba a buen puerto con lo que hasta el momento me había propuesto, hacerlo en un futuro; pues de lo contrario sabía que siempre me quedaría una sensación de haber hecho el trabajo a medias. Cosa que no es así con la traducción del texto del ejecutable para la versión EGA del juego, también incluida. Salvo contadas personas que específicamente prefieran jugarlo en 16 colores por algún tipo de nostalgia especial para ellos, es evidente que la inmensa mayoría preferirán jugarlo en VGA, a 256 colores. Por tanto, salvo que exista petición expresa de alguien sobre la traducción del ejecutable EGA, no tengo pensado en principio llevarla a cabo en ningún momento. Además, se puede disfrutar igualmente del juego en EGA y en castellano, con la única salvedad de que los cuadros de diálogo emergentes y algún detalle más estarán en inglés.

A excepción del desensamblado y copia del resultado final, de lo cual guardaba frecuentemente copias de seguridad, casi todo el material creado y empleado para esta traducción lo guardaba en el disco duro del PC en el que trabajaba. Un Pentium 166 con el sistema operativo MS-DOS instalado para no depender de emuladores que pudieran falsear el correcto funcionamiento de lo que iba haciendo. Desgraciadamente, debido a un estúpido descuido mío, un día tuve la mala suerte de ver como este disco duro de repente no se encendía, con la correspondiente pérdida que ello supuso. No obstante, mi experiencia me indica que se trata de la controladora lo que falla, y aunque se trata de un disco antiguo (Fujitsu M1624TAU), tengo localizados varios vendedores de segunda mano que disponen de él o de la misma controladora que éste utiliza (CA20318-B21X). La pega es que, aun siendo tan antiguo y de segunda mano, su precio no es barato. Pero sí tengo claro que algún día trataré de recuperarlo o en su defecto, de volver a crear las herramientas mencionadas para quitarme esa espinita que supone lo que quedó pendiente. Además, mis recuerdos, mi experiencia y conocimientos ampliados desde entonces lo hará mucho más fácil.

Mientras tanto, los que dispongáis del juego podréis disfrutarlo en castellano con sólo solicitarme un parche que creé para tal efecto.

Tanto tenía mi cabeza puesta en la informática y el desarrollo de software ya en mi primer año de Universidad, que prácticamente me centré más en facilitar el entretenimiento de los usuarios del aula de ordenadores que en las asignaturas de la propia carrera (Ingeniería Industrial).

En aquel momento ya existía un chat creado en años anteriores por un alumno, que funcionaba bien dentro de sus limitaciones, pues no era en tiempo real y requería presionar la tecla ‘Enter’ para actualizarlo con los nuevos mensajes que iba escribiendo la gente. Digamos que era un chat pasivo. Además carecía de interfaz de usuario, no se sabía qué usuarios había conectados en cada momento y tras cada dichosa pulsación de tecla se producía un parpadeo importante y molesto debido al método de refresco de pantalla basado en limpiar y escribir todo de nuevo.

Así pues se me ocurrió mejorar notablemente esta situación creando yo mismo y desde cero un nuevo chat que diera más comodidad. Así de paso aprendía un poco sobre Unix, sistema que hasta entonces conocía de oídas. Me hice con el que para mí está entre los mejores libros de programación en Unix: “Unix programación avanzada” de Francisco Manuel Márquez García (creo que prácticamente monopolicé el préstamo de dicho libro en la biblioteca de la escuela). Con él aprendí el funcionamiento elemental de Unix y los recursos que ofrecía de cara a mi objetivo. En concreto los métodos IPC del System V: colas de mensajes, semáforos y memoria compartida. También quería hacerlo bonito dentro de las limitaciones de los terminales de texto monocromo tipo VT100 con los que contaba la sala. Pero viendo la interfaz de usuario de la aplicación de correo que usábamos, intuí que debía existir alguna biblioteca de funciones del estilo a conio.h. Así descubrí la existencia de ncurses, cuyos recursos aprendí a usar a base de consultas intensivas al manual de Unix con el comando man.

Con todos estos nuevos conocimientos adquiridos y mi experiencia hasta el momento programando con el lenguaje C++, tenía las herramientas necesarias para lograr con éxito mi objetivo.

El resultado final fue un chat funcional y vistoso, inspirado en el IRC, cuyo ejecutable coloqué en un directorio compartido dentro del servidor para que cualquiera pudiera ejecutarlo. Su funcionamiento estaba basado en la comunicación entre procesos dentro de la misma máquina (el servidor), pues los PCs de la sala eran simples terminales. Cuando el primer usuario ejecutaba la aplicación del chat, creaba un espacio de memoria compartida y una cola de mensajes. En la memoria compartida escribía una estructura con su nick y privilegio dentro del chat, el cual era de operador al ser el primero en entrar, tal y como sucede en el IRC. Desde ese momento cualquier otra ejecución del chat en terminales distintos comprobaba la existencia de los citados recursos IPC, añadía los datos del usuario a la memoria compartida y colocaba un mensaje en la cola de mensajes destinado a todos los usuarios, informando de su entrada en el chat. Para saber si había nuevos mensajes, la aplicación ejecutaba un bucle infinito en el que continuamente se consultaba la cola de mensajes.

La interfaz de usuario me quedó similar a la de IRC, haciendo uso de ventanas de texto, texto en negrita y demás elementos que permitían estructurar la pantalla en 3 zonas: la zona de conversación donde se mostraba todo lo que escribían los usuarios, la zona de escritura donde uno escribía lo que quería enviar al resto y la zona con la lista de usuarios conectados, ordenada primero por los operadores del canal y después por orden alfabético.

Ahora ya se podían ver los mensajes en tiempo real sin nada más que mirar a la pantalla, en todo momento se visualizaban los usuarios conectados y sus privilegios, e incluso se podía conversar en privado con cualquier usuario del chat.

Todo el proyecto así contado ‘a posteriori’ parece fácil y lógico, pero puedo asegurar que no lo es cuando no sabes apenas nada de Unix ni de programación concurrente y comienzas a entrar en detalles según avanzas. Por suerte no me rindo cuando me propongo algo.