Cirugía Retro

| tags: Atari ST

Intro

Replicando a la Wikipedia, “Cruise for a Corpse” es una aventura gráfica de Delphine Software desarrollado para Atari ST, Amiga y PC allá por 1991. Hasta donde se sabe, el juego estaba disponible en varios idiomas en las distintas plataformas: Inglés, Alemán, Francés (como “Croisière pour un Cadavre”) y Español.

A estas alturas, casi 30 años después me dió por buscar grupos de Telegram sobre Atari debido a varias cosillas sin relación con el juego:

  1. Me explotó el monitor (SC1224) :(
  2. Quería intentar preservar los discos que tengo y quería consultar opciones.

Total, que hablando de todo un poco, se dice, se comenta, que están preservadas todas las versiones para todas las plataformas en todos los idiomas… menos la versión española para Atari ST. Parece ser que la comunidad llevaba varios años detrás de ella. Ahí fué cuando se me encendió una bombillita. Ya que estaba preguntando por temas de preservación, me decidí a ponerle solución, por lo que me puse a indagar sobre el juego.

Y aquí es donde empieza mi aventura.

Antes de empezar a daros la chapa, quisiera agradecer desde aquí a Eugene ‘sev’ Sandulenko del equipo de desarrollo de ScummVM tanto por ayudarme a resolver algunas dudas sobre el funcionamiento del motor del juego como por aguantarme durante las pruebas realizadas en el desarrollo de las herramientas utilizadas durante este proceso para reempaquetar los ficheros y localizar algunos errores.

A Kari ‘Buddha^’ Salminen por el trabajo previo que realizó sobre el motor Cinématique, usado por otro juego de Delphine Software llamado Operation Stealth.

A Comunidad Atari por el apoyo que he recibido durante el proceso y por aguantar mis monólogos sobre este tema :)

Y lo más importante, a mi família por aguantar mis “friquerías” <3

Recon

Como soy un tío medio metódico (NOPE, muahaha!), la primera fase la dediqué al reconocimiento. Tanto de las versiones preservadas como desarrollos / investigaciones llevadas a cabo por otros en el pasado en relación al juego o al motor. Los objetivos que me marqué eran los siguientes:

  • Confirmar que la versión española para Atari ST no estaba preservada.
  • Averiguar si los ficheros de recursos del juego se podían extraer de manera relativamente simple.
  • Averiguar si alguien había intentado reversear / “meterle mano” al juego.
  • Recopilar toda la información posible acerca del motor utilizado en el juego.

Respecto al primer punto… efectivamente, parece que no está preservada la versión en español para Atari ST. En cuanto al resto de puntos, os lo cuento en detalle en las siguientes líneas, pero parece ser que entre 2008 y 2009 los motores utilizados por las aventuras gráficas de Delphine Software fueron víctimas de un proceso de ingeniería inversa y portados a ScummVM. Por suerte, bastantes características de dichos motores fueron detalladas por desarrolladores de ScummVM.

En las siguientes líneas paso a detallar cómo empecé a desengranar el juego.

Aglutinando versiones

El primer paso era conseguir las copias del juego que había disponibles. Me hice con las siguientes versiones:

Plataforma Idioma Crackeada
Amiga Español
Atari ST Alemán
Atari ST Francés No
PC VGA Español

El hecho de que esté crackeada influirá en el repacking del juego, como veremos más adelante. Los cracks que he visto sobre el juego tocan tanto el ejecutable CRUISE.PRG como los ficheros de recursos que se usa durante el proceso de protección. Así pues, a efectos de preservación, consideraba imprescindible obtener una copia del juego intacta.

El paso siguiente sería echar un vistazo a los ficheros del juego y empezar a “abrir” cosas, muahaha! :}

Análisis de ficheros y unpacking

Parece ser que el juego se distribuía en 5 floppies. El listado de ficheros es el siguiente:

Disco Fichero Descripción
A AUTO/CRUISE.PRG Ejecutable del juego, en el directorio AUTO para que arranque desde disco.
A D1 Volumen de recursos del primer disco.
A INSTALL.PRG Ejecutable para configurar el audio del juego.
A MIDI.OFF Fichero de configuración de sonido.
A READ.ME Fichero README con instrucciones de instalación.
A SYSTEM.FNT Fichero de la raster font del juego.
A VOL.1 Fichero identificador del primer volumen de recursos.
A VOL.CNF Volumen maestro de recursos. Tiene un índice general del contenido de todos los volúmenes.
B D2 Volumen de recursos del segundo disco.
B VOL.2 Identificador del segundo volumen de recursos.
C D3 Volumen de recursos del tercer disco.
C VOL.3 Identificador del tercer volumen de recursos.
D D4 Volumen de recursos del cuarto disco.
D VOL.4 Identificador del cuarto volumen de recursos.
E D5 Volumen de recursos del quinto disco.
E VOL.5 Identificador del quinto volumen de recursos.

Tal como se indica en el READ.ME, el juego podía instalarse en disco sin problemas, reduciendo un poco los tiempos de carga y evitando la molestia de tener que andar cambiando de disco cada dos por tres.

Viendo los ficheros, al final lo que se le ocurre a uno es tan “simple” como extraer los ficheros de recursos de una versión española, buscar los textos en español y meterlos de vuelta en los volúmenes de recursos de cualquier versión para Atari ST.

Volúmenes de recursos

Como hemos visto, se usan diferentes ficheros para almacenar los recursos del juego. En el caso de Cruise for a Corpse tenemos 5 ficheros de volumen, 5 ficheros identificando dichos volúmenes y un fichero volumen maestro en el que hay un índice donde aparecen todos los ficheros de recursos en los 5 volúmenes.

La estructura de los ficheros de volumen es la siguiente:

Estructura de fichero de volumen

En el caso del fichero D1, por ejemplo, la cabecera y la primera entrada serían tal que así:

Cabecera + primera entrada del fichero

Podemos ver que en el fichero D1 tiene un total de 0xA4 (164) entradas en el índice y que cada una de ellas se define en 0x1E (30) bytes. Esto es así para cada una de las entradas del índice. La estructura de cada entrada es la siguiente (contando como base address el principio de la entrada):

Formato de cada entrada

Por lo tanto, cada entrada quedaría así:

Formato entrada 2

En esta primera entrada como ejemplo podemos ver el nombre de fichero AUTO00.OVL, el offset (0x0000133C) el tamaño del fichero comprimido (0x00000994 - 2452 bytes) y el tamaño del fichero descomprimido (0x00001AC3 - 6851 bytes).

En cuanto al fichero VOL.CNF, tiene prácticamente la misma estructura que los ficheros de volumen de recursos, pero sólo contiene una entrada por cada fichero de volumen de datos (D1, D2, D3, D4, D5) y un índice general de ficheros sin tamaños ni offsets.

Al final esta es la parte fácil, ya que rebuscando un poco, uno encuentra que puede usarse el paquete de scummvm-tools para extraer todos los ficheros. Una vez descomprimido todo, vemos que los textos están en los ficheros con extensión .FR:

Muestra texto

Cabe decir que no son ficheros de texto al uso. Comprobando el código de ScummVM sobre este motor se puede ver como dichos ficheros se usan en conjunto con otros ficheros (OVL principalmente) sirven para “montar” el overlay de la escena. Esta capa, usando los ficheros FR y OVL correspondientes a cada escena, sirven para enlazar personajes/objetos/acciones/texto dentro de la escena, por lo que dentro de los ficheros .FR no sólo se encuentran las strings en español para el texto, también existen nombres de variables y objetos usados por el propio motor del juego.

Inicialmente lo que hice fue pensar en que tan solo encasquetando los ficheros .FR dentro del fichero de volumen y reconstruir el índice era suficiente, pero más adelante veremos que no.

En las siguientes líneas, me centraré en explicar la fase del reempaquetado de los volúmenes de recursos, así como el resto de cosillas que toqué para hacer que el invento funcione. Puesto que ya había conseguido descomprimir todos los recursos, tan sólo me quedaba la segunda parte y no tenía muy claro que esto fuera a salir adelante.

Reempaquetado

Bien, lo primero que tenemos que hacer para volver a dejarlo todo como estaba, limpio como una patena y sin rastro de marraneo es averiguar el algoritmo de compresión que utilizó la gente de Delphine. Después de comentar el tema con sev, me dijo que el algoritmo no tenía mucho misterio, que se trataba de una modificación del archiconocido LZ77. Al final, después de darle muchas vueltas, parece ser que el algoritmo utilizado era el que usaban muchos crunchers de la época (compresores): ByteKiller.

Después de todo el trabajo de investigación, me piqué una serie de herramientas que me permitían automatizar el proceso de paquetización. Estas herramientas se encargan de lo siguiente:

  1. Desempaquetar los volúmenes de recursos del directorio indicado al directorio destino.

  2. Mover los ficheros con los textos en español al directorio destino.

  3. Indexar qué ficheros corresponden a cada volumen.

  4. Comprimir todos los ficheros.

  5. Reconstruir el índice correspondiente al volumen con los siguientes datos:

    • Nuevos offsets.
    • Nuevo tamaño comprimido.
    • Nuevo tamaño descomprimido.
  6. Reconstruir el volumen de datos con los nuevos ficheros.

El fichero VOL.CNF no es necesario recrearlo debido a que no contiene información individual sobre los ficheros, por lo que no es necesario reflejar ninguno de los cambios realizados.

Una vez terminado el proceso, tan solo queda montar las imágenes de floppy nuevas. Para ello lo que hago es crear una imagen vacía desde Hatari replicando los discos originales.

Una vez tengo las imágenes vacías, las edito con las herramientas de HxC y añado los ficheros:

HxC Tools

Acto seguido guardo la imagen en formato .ST y abro en el emulador:

Juego en español

Bien, esta la imagen de arriba tiene trampa. Sí, os he engañado, esto no se acaba aquí. La captura anterior inicialmente se veía de la siguiente manera:

Español inicial

Fijaos que falta la ú. Después de investigar sobre el mapa de carácteres utilizado por Atari, probar a meter toda la tabla ASCII extendida en el texto y realizar mil y una pruebas sin resultado positivo, la respuesta estaba, de nuevo, en el código de ScummVM.

Parece ser que en los recursos del juego no se define un mapa de carácteres concreto. Debido a las características del motor, el mapa de carácteres que se usará, independientemente de si existe el caracter en SYSTEM.FNT, es el definido en el ejecutable del juego, en este caso el fichero CRUISE.PRG.

Dicho esto, puesto que tiene hardcodeada la tabla de carácteres correspondiente al idioma de la versión del juego, si queremos ver los textos en español en todo su esplendor no sólo hay que reconstruir los volúmenes de recursos. Tampoco es suficiente con copiar el fichero de la fuente bitmap de otra versión en español (SYSTEM.FNT). También hay que parchear el ejecutable del juego. Así que nada, manos a la obra!

Para que reconozca los nuevos carácteres, simpemente hay que parchear unos bytes en la parte donde está definida la tabla de carácteres. Aquí los cambios, donde CRUISESP.PRG es la versión parcheada y CRUISEO.PRG la original:

$ radiff2 CRUISESP.PRG CRUISEO.PRG
0x0001ae3e 00720080 => ffffffff 0x0001ae3e
0x0001ae7c 007f0079007b008100820083 => ffffffffffffffffffffffff 0x0001ae7c
0x0001ae8c 007d => ffff 0x0001ae8c
0x0001ae96 007e => ffff 0x0001ae96
0x0001af14 00790078 => ffffffff 0x0001af14
0x0001af20 007b007a => ffffffff 0x0001af20

A continuación podéis todos los carácteres soportados en la versión francesa:

Francesa

Y aquí podéis ver la tabla de carácteres del ejecutable parcheado, con sus ñÑ y sus cosicas:

Española

Todo esto nos vale para la versión original sin cortar, pero… ¿qué ocurre si tenemos una versión crackeada? Bien, pues podemos parchear de la misma manera. El único problema que tendremos es a la hora de descomprimir y volver a comprimir el ejecutable del juego. Para ello hará falta identificar el packer/cruncher utilizado:

Packed

El ejecutable descomprimido tenía casi 4 veces el tamaño del ejecutable original (gracias a Tito Teclado por iluminarme el camino con las herramientas que me mandó). Esto es debido a la música, las fuentes para los scrollers, etc… todo lo que lleva una cracktro, vamos. En este caso tuve problemas a la hora de volver a montar el ejecutable, ya que si bien es cierto que arrancaba la cracktro sin problemas, a la hora de lanzar el juego se quedaba colgado. Seguramente había algún offset hardcodeado para saltar después de la cracktro que me cargué en el reempacado, así que no perdí mucho tiempo y me centré en la versión original sin crackear.

TODO:

Temas pendientes:

  • Intentar documentar el formato de los ficheros de texto y la relación con overlays (ficheros .FR y .OVL).
  • Generar y publicar una versión con los textos revisados y actualizados, acordes al 2020. Joaquín Ferrero (explorer) está en ello.
  • Generar y publicar una versión crackeada con su cracktro, musiquita y dibujutos. Para no andar con la ruedecita de protección todo el rato.

Cierre y despedida

Lo explicado aquí es una versión bastante resumida de todas las pruebas que hice durante todo el proceso, me he limitado a ir bastante al grano para no aburrir (aunque creo que ni así lo he conseguido). De todas formas, si alguien quiere saber más, que pregunte :}

Para terminar, decir que independientemente de que haya existido o no la versión española del juego, he echado un ratito divertido, que es de lo que se trataba. Me quedo con lo siguiente:

  • En la época no era extraño ver que los juegos utilizaban técnicas usadas en el mundillo demoscene. Como ejemplo pongo la compresión de los ficheros. ¿Qué fue antes, el huevo o la gallina?

  • Los sets de las escenas y los textos parece que no han cambiado nada entre diferentes plataformas / idiomas. Los textos de PC VGA y Amiga en español funcionan sin problemas en Atari ST.

  • He aprendido sobre algoritmos de compresión que no conocía. Sobre (de)crunchers/(un)packers de los 90 para Amiga y Atari ST.

  • Cada vez que me da por mirar cosas antiguas un poco a fondo, más las admiro. En los créditos del juego, en lo referente al core del desarrollo del juego (grafistas, sonido, programadores) aparecen un total 8 personas diferentes. ¿Cuantas hacen falta hoy en día?

  • He escondido un easter egg en las versiones que reempaqueto para aquellos aventurados que quieran replicar todo este proceso. Es una tontería, pero he intentado emular aquello que hacían los grupos de crackers cuando destripaban algo :)

La intención inicial era contribuir de alguna manera a la comunidad. Encima que llego casi 30 años tarde con una montaña de preguntas, quería hacer algo para, de alguna manera, devolver a la comunidad retro en general todas las cosas que me he llevado de una época que no fui capaz de disfrutar por edad, pero que a medida que descubría cosas nuevas, más me interesaba.

Espero que esto sirva como mi pequeño (y primer) aporte.

En breve colgaré las 5 imágenes de disco con los textos en español, basadas en la copia original francesa. Estas 5 imágenes llevan los textos en español tal cual se lanzaron en la época. Está sin adulterar: el texto íntegro de la narrativa y sin crackear.

Adicionalmente, si veo que hay suficiente interés, limpiaré el código y colgaré también las herramientas que he hecho para automatizar todo esto.

A disfrutar!

PATCHED!

PS: Por favor, si has llegado hasta aquí y has visto algún error (crítico o no) en todo este galimatías de cosas que han salido de mi cabeza sin orden alguno, ponte en contacto conmigo para que pueda arrglarlo.