Bot de Guitar Hero III para PS2

GH III logo

Guitar Hero es una saga de juegos musicales en los que cada canción se toca siempre de la misma manera (en cada nivel de dificultad). Las notas a pulsar y el tiempo entre ellas es por tanto siempre el mismo. Esto hace que crear un bot que juegue por nosotros al Guitar Hero (y consiga auténticas proezas) sea bastante sencillo. En este documento explicamos cómo lo hicimos nosotros.

Lo primero fue abrir la guitarra para ver con qué íbamos a tener que tratar. Para nuestra (grata) sorpresa, la circuitería interna es bastante sencilla, al menos las partes que nosotros debíamos "tocar". Armados con un polímetro, averiguamos qué pin(es) del chip se activaban al pulsar cada botón (de los que queríamos que controlase el bot, a saber, los de notas y la púa).

MástilChip

Para simular que se ha presionado un botón determinado, no hay más que mandar tensión al pin correspondiente. Lo más sencillo hubiera sido deshacerse de la carcasa de la guitarra, desconectar todo el cableado innecesario y centrarse en el bot, pero sólo teníamos una guitarra y el presupuesto era limitado.
Además, queríamos seguir viciados al juego. Solución:
Mediante un interruptor, se selecciona si la guitarra entra en modo bot (los botones son presionados de manera "artificial") o modo "clásico", en el que sigue respondiendo de manera normal. Complicaba un poco la circuitería, pero valía la pena.

La parte de hardware es muy sencilla. Se trata simplemente de accionar electrónicamente los botones de la guitarra. De esta tarea se encargan optoacopladores, elegidos porque son bastante rápidos, pequeños, consumen muy poco y su coste es reducido.

Optoacoplador

El funcionamiento de los optoacopladores es simple. Se componen de dos subcomponentes en un mismo encapsulado: un LED y un fototransistor. El LED se encarga de controlar al fototransistor, regulando la intensidad que circula por él. Además, hay un aislamiento completo entre ambos componentes: sólo tienen interacción óptica, lo que los hace adecuados para nuestro proyecto ya que no corremos el peligro de dañar el puerto paralelo.
Para identificar en qué lado está cada componente suele hacerse un bisel en el encapsulado, o un punto en la parte superior, que indica cuáles son los 2 terminales del LED.
Para mas información, Wikipedia tiene la solución, o puedes preguntarle a Tito Google que lo sabe casi todo.

Estos optoacopladores serán manejados desde el puerto paralelo de un PC.

Puerto

En nuestro montaje utilizamos los pines 2-7 para controlar los optoacopladores (los pines 2-6 controlarán los botones del mástil y el 7 se encargará de la púa). Los pines 18-25 están todos conectados a masa. Para obtener la masa del circuito de LEDs de los optoacopladores puede optarse por puentear todos estos pines y sacar un cable o conectarlo a uno de estos pines directamente.

Puesto que queríamos que la guitarra ignorara la entrada por PC si estaba en modo normal e ignorara los botones si estaba en modo de control por PC, no era tan sencillo como conectar en paralelo los optoacopladores con los botones. Después de explorar el circuito de la guitarra nos dimos cuenta de que todos los botones seguían el mismo esquema: estaban conectados entre masa y el chip del circuito. Decidimos por tanto que el conmutador de modos debía servir para decidir quién controla la masa: los botones de la guitarra o los optoacopladores.

El circuito de cada uno de los pulsadores es éste:

Circuito de los pulsadores

Con las ideas del esquema bien claras, ya sabíamos todos los componentes que íbamos a necesitar para la parte de hardware, así que tocaba ir de compras:

Componentes

Ahora comenzamos el montaje del hardware. A continuación se exponen todos los puntos del circuito que son de vital importancia para el proyecto.

Las zonas 1 y 2 en la imagen inferior indican los pines donde están soldados los pulsadores que manejan la púa, mientras que las zonas 3 y 4 indican dónde se conectan los botones del mástil en el circuito. Obsérvese que, para el botón simbolizado con 1, el pin de masa es el que está más arriba, mientras que para el botón 2 es el que está más abajo. Aunque no pueda visualizarse que el 2 está conectado a masa en el circuito mirando esa imagen, lo está mediante un puente situado en el otro lado de la placa, que aparece dibujado en amarillo. En cuanto a los botones del mástil, todos están conectados al pin superior de la zona marcada como 3 (color negro), que va a masa, mientras que los otros 2 pines de esa zona y todos los de la zona 4 son los que van al chip.

Circuito

La primera tarea es desconectar las masas de los botones para poder usar el conmutador. Para ello, desconectamos el cable de masa del mástil y desoldamos completamente los botones de la púa. Doblamos hacia afuera los pines de estos botones que van a masa y los conectamos entre sí con un cable por la parte superior del circuito. Dicho cable va conectado al ánodo de un diodo. El cátodo va conectado al cable de masa del mástil que acabamos de desoldar. En ese extremo, soldamos además otro cable que conectaremos posteriormente al conmutador, dándoles la masa a los botones cuando se seleccione. Posteriormente se expondrá la función que desempeñan los diodos.

Debido a que hemos quitado uno de los dos pines de cada uno de los botones de la púa, éstos quedaron un poco mal asegurados, así que decidimos aplicar un poco de pegamento termofusible en los alrededores de los mismos para darle más consistencia al montaje.

Una vez aisladas las masas, procedimos a soldar los cables que irían al circuito de optoacopladores. Soldamos 5 cables para los botones en los pines de las zonas 3 y 4 (simbolizados con puntos del color de cada uno de los botones) y un cable extra para el control de la púa (punto blanco en la zona 1). Sólo soldamos en uno de ellos ya que para el juego sólo es necesario el uso de una dirección de punteo. Para finalizar, obtuvimos la masa del circuito del pin que dejamos libre al quitarle la masa al mástil (punto negro en la zona 3).

Cables soldados a la placa

En este punto no es necesario tocar la placa de la guitarra para nada más. Sólo resta elaborar el circuito que dará soporte a los optoacopladores.

Este circuito fue construido en una placa de baquelita, que aseguramos a la guitarra con una estructura hecha básicamente con cable monofilar pelado, reforzado con algo de estaño y aprovechando los tornillos que venían en la propia guitarra. Este circuito contiene 6 montajes como el siguiente:

Circuito de un optoacoplador

El terminal con la etiqueta "Pin" del lado de los LEDs va conectado directamente al puerto DB-9 utilizado para conectar la guitarra al PC. Utilizamos los pines 1-6 del puerto serie para conectar estos terminales, y conectamos todos los cátodos a la masa del puerto, aprovechando la carcasa metálica del conector. Entre cada ánodo y su pin correspondiente del puerto DB-9 conectamos una resistencia que servirá para regular la intensidad que suministra el puerto, protegiéndolo de una carga excesiva.

El lado de los fototransistores tiene 2 partes:
- Todos los pines marcados con "Masa" van conectados entre sí y al conmutador de masa.
- Los pines marcados con "Pulsador" van conectados a los cables verde, rojo, amarillo, azul, naranja y blanco que soldamos antes a la placa de la guitarra, teniendo cuidado con qué botón activa cada uno. Es una buena idea utilizar como guía los colores de los cables.

Éste es el resultado final de nuestra placa de optoacopladores:

Placa de optoacopladores terminada

Quedan un par de modificaciones en la guitarra. Una es la instalación de 5 diodos en los cables que unen la placa de la guitarra con la placa de los botones del mástil. Todos ellos se conectan de la misma forma, simplemente se intercalan en los cables de cada uno de los botones. El cátodo se conecta en dirección a la placa de los botones, y el ánodo en dirección a la placa de la guitarra. No es necesario añadir un diodo al cable de masa del mástil puesto que ya está protegido con el diodo añadido anteriormente.

La última tarea es conectar el conmutador. Se trata de un conmutador simple de 3 terminales (2 posiciones, 1 circuito). El contacto central es el que va a la masa de la placa de la guitarra. Uno de los pines laterales debe conectarse al cable que alimenta todos los emisores de los fototransistores (los que tenían la etiqueta "Masa"), mientras que el otro pin ha de conectarse al cable de masa de los botones de la guitarra.

¡Aquí finaliza el montaje! Bueno, queda atornillarlo todo...

Circuito terminadoCircuito terminado

Ahora procedemos a explicar el funcionamiento del hardware. Para ello, explicamos el funcionamiento de cada circuito de 2 formas: la primera es explicarlo como si ese circuito fuera el único que trabajara; la segunda es explicar la influencia del otro circuito en el que intentamos exponer. Se recomienda mirar el esquema del circuito modificado, mostrado más arriba, mientras se explica el funcionamiento del mismo.

Circuito de funcionamiento normal

En esta posición, la masa del circuito pasa directamente a los botones de la púa y al circuito del mástil, haciendo que la guitarra opere como si ni siquiera se hubiera abierto. Los diodos añadidos están polarizados directamente, así que el circuito trabaja como si no existieran.

Está también presente la influencia del circuito de los optoacopladores, puesto que físicamente está conectado. Pero el conmutador de modo ha dejado desconectado el terminal de masa de dicho circuito. Los emisores de los fototransistores no están conectados a ningún sitio. Como no hay circuito cerrado, es como si este circuito no existiera.

Resultado Final 1

Circuito de control por PC

Ahora es el circuito de los optoacopladores el que está conectado a masa y los botones los que no lo están. Este circuito no es más que un reemplazo electrónico de los botones del mástil y la púa: cuando el LED de un optoacoplador recibe tensión, hace que el fototransistor conduzca la corriente, actuando como un simple pulsador.

El problema que surge con este circuito al tener presente el de funcionamiento normal es la pulsación de los botones. Imagina por un momento que los diodos no se han montado. Si uno de los optoacopladores esta activado, la masa está conectada tanto a la pista correspondiente del chip de la placa como al cable del mástil. Esto quiere decir que, si pulsamos el mismo botón que el optoacoplador esta accionando, estaremos conectando a masa todo el mástil, e incluso los botones de la púa. Si pulsamos ahora cualquier otro botón o la púa, funcionaran de la misma forma que en el modo normal. Estaremos por tanto haciendo que el montaje trabaje de una forma no deseada, ya que queremos que ignore completamente el accionamiento externo en este modo.

Este comportamiento se arregla con los diodos que hemos instalado. Cuando un optoacoplador esta activado, la masa está conectada a la pista correspondiente a un botón. En este caso, aunque la masa también está conectada a los cables del mástil, estos diodos estarán polarizados inversamente, por lo que estarán cortados, haciendo que parezca que hemos desconectado físicamente los elementos del otro circuito.

Resultado Final 2

Con esto finaliza la parte de hardware del proyecto. A continuación expondremos el proceso de desarrollo del software necesario para hacerlo funcionar.

Nótese que hardware y software fueron desarrollados en paralelo. Por ese motivo, en los vídeos que aparecen a continuación se puede observar una guitarra no acabada. La explicación en este documento se ha dividido en hardware/software para facilitar su comprensión.

Antes de nada hicimos algunas pruebas encendiendo LEDs con el puerto paralelo (utilizando el lenguage de programación C), realizando una (muy simple) aplicación que enviara un bit a un pin determinado si se pulsaba cierta tecla (para tratar la pulsación de teclas del teclado se usó SDL). Así nos aseguramos de que la tensión salía de éste como cabía esperar. Las función usada es:

typedef void _stdcall (*oupfuncPtr)(short portaddr, short datum);

Se encuentra en "inpout32.dll". Su primer parámetro es la direccion en hexadecimal para escritura en el puerto paralelo, normalmente 0x378 (depende de la configuración de la BIOS). El segundo parámetro indica el dato a transmitir por el puerto paralelo (los pines del paralelo pasan a 0 ó 1 según la representación en binario de este "datum").

Lo siguiente fue comprobar que el hardware funcionaba como esperábamos. En lugar de hacer pruebas con LEDs, conectamos por primera vez la guitarra al PC, y pudimos hacer un test en el que, utilizando el teclado del ordenador, manejábamos el menú del juego.

Todo estaba saliendo a pedir de boca. Ya podíamos volver a cerrar la guitarra, como si nada le hubiera pasado (eso sí, con un interruptor y una conexión de puerto serie de más) y hacer la siguiente prueba, jugar una canción desde el teclado del PC.

Pero necesitábamos que el PC tocase por sí sólo.
Para que pudiese tocar una canción determinada en un nivel de dificultad dado, obviamente debía tener acceso a información sobre cómo debía ésta tocarse (qué notas hay que pulsar y cuándo). Surgieron 3 ideas acerca de cómo obtener esta información:

1) Una webcam apunta al televisor en el que se está jugando, "viendo" qué teclas hay que pulsar. Un método que teóricamente serviría para todas las canciones una vez implementado correctamente, pero que parecía bastante laborioso, difícil de llevar a cabo. Y teniendo en cuenta la velocidad a la que bajan las notas por la pantalla en las canciones más difíciles, la proximidad de las notas, la calidad de imagen y los frames per second que proporciona una webcam... quizás hasta imposible. Opción descartada.

2) Crear un programa que registrase a un archivo las pulsaciones de teclas en el teclado, y así, a la vez que jugábamos a una canción desde el PC (como en el último vídeo), se iban generando unos .txt que el PC podía usar luego para tocar la canción de forma independiente. Esta opción teóricamente funcionaba bien, pero era demasiado tedioso grabar las canciones. Descartada tras algunos intentos.

3) Sacar la información directamente del juego. El juego debe saber cómo son las canciones, ¿no? Opción correcta.

La solución fue instalar la versión del juego para PC, en la que (afortunadamente) todas las canciones parecen jugarse exactamente igual que en la versión de PlayStation 2. Una vez instalado el juego, descubrimos que la ansiada información se encontraba en: "...Guitar Hero III\DATA\SONGS" en forma de archivos .pak.xen

Songs

Encontramos ciertos programas que nos podían ayudar en el foro scorehero, y es que mucha gente ha hecho ya programas que tratan estos archivos de canción con diferentes propósitos. Si nos servían, ¿para qué reinventar la rueda?

Aplicamos algunos de estos programas a los .pak.xen (que incluyen mucho más de lo que nos hacía falta para saber tocar la canción), de forma que al final del proceso tenemos unos .txt que tienen esta pinta:

Txt

¡Eso ya era otra cosa! Timestamp indica el milisegundo en el que empieza la nota, duration el tiempo durante el cual hay que dejarla pulsada y note de qué nota(s) se trata, evidentemente.

A continuación se describe el proceso de paso de los .pak.xen a los .txt:

1) Usamos en primer lugar UnPAK.exe (GHIII PAK file extractor v1.0 by Invo). Además de pasarle el archivo de canción necesario (por ejemplo: "thrufireandflames_song.pak.xen") necesita el archivo "...Guitar Hero III\DATA\PAK\dbg.pak.xen".
La ejecución de este programa produce una serie de archivos, de los cuales el único que nos interesa es el de extensión ".mid.qb".

2) Aplicamos UnPAKMidQB.exe (GHIII MID.QB file extractor v1.0 by Invo) al fichero .mid.qb obtenido en el apartado anterior, obteniendo múltiples archivos. De éstos nos interesan los acabados en "_song_Easy", "_song_Medium", "_song_Hard" y "_song_Expert". Ya tenemos un archivo para cada nivel de dificultad de la canción.

3) Falta darle a éstos un formato tratable/legible. Usando una utilidad llamada DumpChart.exe (GHIII chart extractor v1.0 by Invo) conseguimos finalmente la información que de verdad nos interesa.

Para más información acerca de estos programas visita este enlace. Allí encontrarás todos los detalles de estas 3 magníficas aplicaciones, y tanto el ejecutable como el código fuente están disponibles (junto con los archivos del proyecto).

Perl

Para automatizar esta tarea programamos un pequeño script en Perl (lo mejor para tratamiento de texto) que, a partir de una canción de la carpeta "Guitar Hero III\DATA\SONGS\" crea directamente los ".txt" correspondientes.
El código fuente de esta aplicación puede descargarse aquí.

En resumen: tenemos el hardware listo, un programa que activa los pines del puerto paralelo al pulsar una tecla determinada y un .txt con la información necesaria para tocar la canción.
Lo que falta es que el PC sea capaz de "ir leyendo la información de este .txt e ir automáticamente activando los pines necesarios".

En primer lugar transformaremos estos .txt (llenos de información innecesaria) a una serie de archivos binarios (6, uno por cada tecla de nota y otro para la púa) que contengan lo estrictamente necesario para tocar.

Luego tocaba desarrollar una aplicación que convirtiese los .txt que ya habíamos obtenido a los .gh que el player sabría reproducir. El código fuente de esta aplicación puede descargarse aquí.

Cada uno de estos archivos (formato .gh) no es más que un conjunto (par) de números (de tipo long, pues int era demasiado pequeño) que indica cuándo (en milisegundos) se debe pulsar (activar) y cuándo soltar el botón (pin) correspondiente. Pulsar, soltar. De ahí que sea un número par de longs.

Finalmente, otro programa escrito en C (por su velocidad) se encarga de leer estos archivos .gh a memoria. Espera hasta que se le indica que la canción ha empezado, y se dedica a (mediante un bucle que va calculando cuánto tiempo ha transcurrido desde que la canción empezó) ir activando y desactivando los pines adecuados. El código fuente de esta aplicación puede descargarse aquí.

El problema de que haya que indicarle al PC manualmente (presionando Enter) que la canción ha empezado es importante, pues requiere que se presione esta tecla en el momento justo en que la primera nota de la canción (que ya está ejecutándose en la PS2, claro) debe ser pulsada. El momento justo con una precisión de un milisegundo, algo verdaderamente complicado. Sin embargo, el juego permite un margen de error (que varía según la canción y el nivel de dificultad), lo que hace que el problema no sea "tan grave".

Y aquí dejamos un vídeo del bot en acción, tocando Through The Fire And Flames en Hard.

Y así se hace.

Si tenéis alguna duda (algunas fases del desarrollo no habrán quedado demasiado claras) mi e-mail de contacto es IamBMF@gmail.com.