Rick Dangerous II+
Mensaje del excelentísimo señor Mauricio:
Entré en el proyecto para ayudar a darle el impulso que necesitaba, porque toda la parte gráfica estaba lista, pero se habían bloqueado con los parches.
Lo he dicho un millón de veces, nunca comencéis con cracks, es mejor siempre partir de los originales, porque así evitamos problemas debido a los bugs que hayan introducido los piratas. En juegos multicarga, raro es el que no se llevó algún bug gratis, porque recordemos que muchos de estos cracks fueron hechos por gente que su única preocupación era convertir aquello a bloques para poder venderlos en el mercadillo ese final de semana.
Hoy en día con emuladores, las protecciones nos las saltamos en segundos, y una vez hemos pasado la protección, podemos crear snapshots justo en el momento antes de comenzar a ejecutar el juego y así tener todo limpito.
Con esos snapshots es muy fácil dividir la memoria en partes, que si ésto es el código, que si ésto son los gráficos, mapas, … De hecho yo suelo hacer eso, dividir todo en partes y luego reconstruir ese snapshot a partir de un fichero en ensamblador que lo único que hace es juntar las partes y recrear ese snapshot. Así el ensamblador va a quejarse cuando te has pasado en el tamaño de los gráficos, evitando que pises trozos del código y aquello empiece a hacer cosas raras.
Y conforme voy entendiendo cosas, pues ese fichero en ensamblador va detallándose más y más, lo cual además de servirme como documentación, funciona como una forma de automatizar parches.
El RD2 por ser un juego multicarga, nos interesa ver si existe un motor ó estamos ante un cargador de snapshots como en el LN2 😛
Afortunadamente usando emuladores es muy fácil interceptar cuando se produce una carga y descubrir cuál es el código que hace la carga de niveles y qué se carga y dónde se carga. Ni que decir tiene que RD2 usa un motor, por lo que no precisamos hacer ninguna turcada.
El primer detalle interesante es que el Sr. Pridmore hace algunas operaciones sobre los niveles una vez han sido cargados. Digamos que es como una forma rudimentaria de cifrar los datos de los niveles para que la gente que usaba el discology no pudiese cambiarlos y dificultar la tarea de crear un editor de niveles ó cambiar los gráficos.
En nuestro caso, simplemente descifré los datos de los niveles, para ahorrarnos el tener que cifrarlos de nuevo a la hora de ponerlos en el disco de vuelta con los nuevos gráficos y demás modificaciones que hiciéramos.
Luego otro detalle importante, había que saber si el juego se podía acabar, que si hay algún bug de esos típicos, íbamos a perder un tiempo que no teníamos. Para ayudar en las pruebas, lo mejor es ser un maniaque y tirar de pokes; así que se sacaron todos los pokes, incluso uno de inmunidad que en ciertos lugares del nivel te bloqueará la partida.
Al final no se ha puesto ningún cargador porque descubrimos que el juego incluye trucos, para activarlos durante el juego, solo hay que pulsar las teclas C+E+S+3 simultáneamente para obtener vidas y munición infinita.
Por supuesto, para probar todo, había que desbloquear el último nivel. Y eso si que lo hemos dejado activo, ya que no tiene mucho sentido a día de hoy no permitir escoger cualquier nivel, especialmente en un juego tan difícil.
Como era un juego para CPC+, había que activar el Asic y poner la paleta. Para ello había que desactivar todo acceso al Gate Array para poner la paleta del juego original. Afortunadamente, el juego solo usa una paleta y solo se accede al Gate Array justo después de haber cargado el juego. Por lo que fue solo desactivar esa selección de paleta, de hecho al final la paleta del CPC+ la ponemos directamente al final del cargador del juego, justo antes de lanzarlo.
Se hizo la primera prueba con los gráficos del primer nivel ya modificados. Y comprobamos que se podía terminar el primer nivel. Todo funcionaba perfectamente. Y de hecho todo lo relativo a la inclusión de los gráficos nuevos se reducía a Ángel mandar los gráficos nuevos y por mi lado todo estaba automatizado para generar los snapshots con los gráficos actualizados.
Así que viendo que no íbamos a encontrarnos muchos problemas, me metí en la locura de intentar entender cómo funciona el juego y el motor clásico de los plataformas de Gremlin/Core que tantas veces hemos hablado en el programa.
Los primeros cambios fueron cosas más a nivel estético, por ejemplo, el juego solo tiene 15 colores diferentes. Ya que usa dos plumas en negro, una es la 0, pero la otra es la 12 ó algo así.
En nuestro caso, para hacer el juego más bonito el poder tener un color extra sin repetir ayudaba mucho. Ni que decir tiene que el juego usaba ese segundo negro cuando le venía en gana, para cosas como la fuente de letras ó por ejemplo, había momentos en que limpiaba la pantalla usando el segundo negro. Todo ese código que usaba el segundo negro hubo que cambiarlo para que usara el primero. Y Pridmore no era un turco que no sabía optimizar, por lo que tocó pensar en la forma de hacer esos cambios usando el mismo espacio ó menos.
Había veces que el código llamaba varias veces seguidas a una rutina que siempre hacía lo mismo, como si se le hubiese ido la mano en el copiar y pegar en el editor del PDS. Y fue de ahí de donde fuimos sacando espacio de donde no lo había.
Otro cambio estético es cuando te sale el mensaje del game over, que creíamos innecesario el que el mensaje saltase como durante el menú, así que se desactivo. Aunque descubrí un truco interesante para el menú, si no tenéis paciencia es solo darle a la tecla 0 y se salta todo ese efecto de salto.
Por supuesto, se cambiaron las teclas a una combinación más sana, es decir, qaop.
Ángel es de las pocas personas a las que le moló mi truco de poner el CRTC en NTSC, por lo que me pidió que lo añadiese. Así que si queréis jugar en NTSC, es solo mantener la tecla TAB después de darle al enter tras lanzar el juego con |CPM. Una vez veáis la pantalla de carga, ya podéis dejar el de pulsar la tecla.
Yo seguía estudiando el juego porque había dos cosas que queríamos mejorar, los dos principales defectos que el juego posee; y es que aunque el juego usa scroll hardware y es algo que debemos agradecer a Pridmore por siempre intentar mejorar su motor de CPC. Todos sabemos que el motor de CPC está basado en el de zx.
El primer defecto es relativo a las cámaras, culpa de esa herencia spectruniana el scroll vertical se produce en saltos bien grandes, ya que va de 64 en 64 pixeles. En c64 y 16 bits el scroll va al pixel y en cpc sin comerse mucho el coco, Pridmore podría haber conseguido que fuese de 8 en 8 pixeles. Y además ahora para el CPC+ podríamos añadir scroll vertical hardware al pixel sin muchos problemas.
Pero primero tenemos que explicar el porqué esos saltos en el scroll son un problema, y es que tenemos una serie de pantallas en que no se consigue ver la misma zona de pantalla que en las otras versiones, de hecho la parte que queda oculta es donde se generan los enemigos, por lo que éstos no dejan de aparecer hasta que conseguimos que la pantalla haga scroll, lo cual hace esas pantallas más difíciles en CPC.
La primera vez que podemos observar este problema es una vez hemos subido la primera escalera del primer nivel, ya que la pantalla debería haberse movido al menos 1 tile más hacía arriba y se debería poder ver los pies de un enemigo que aparece arriba del todo y que veremos más tarde en el juego. El problema es que al entrar en la siguiente habitación a la derecha, se mantiene esa vista de la pantalla y solo se ve la parte de abajo de la plataforma que está arriba de la pantalla, por lo que no se ve la parte de arriba que es donde los monstruos son generados y mientras no se vean los monstruos, el generador de enemigos continuará creándolos.
Uno se puede acostumbrar y en éste caso no es tan grave, pero en el cuarto nivel tenemos que dar un salto a ciegas para caer en una plataforma que está bajo de la pantalla y que no conseguimos ver, por lo que acertar es más cosa de suerte que otra cosa.
Ni que decir tiene que primero intente ver si podíamos ver esas partes no visibles, subiendo de forma artificial el scroll y si, podía hacer visible esas partes que no se veían. Pero arreglarlo no era tan fácil.
El código del scroll está creado para que siempre haga ese salto de 64 pixeles ó 4 tiles, y si lo hacía menor ó mayor, empezaban a ocurrir cosas extrañas. La segunda idea era intentar encontrar algún marcador para cuando apareciera una de esas pantallas problemáticas la cámara del juego se desplazara un tile hacía arriba; pero tampoco hubo suerte.
Y es que parece que la información de las cámaras está definida en el formato de los niveles. El motor clásico de plataformas de Gremlin/Core define tiles, metatiles y habitaciones. Luego con esas habitaciones tenemos otra estructura que es la que se define las secciones, que son pedazos independientes del nivel (recordad lo que hablamos en el postpodcast del Avenger sobre los mapas), en esas secciones se indica las habitaciones, como están conectadas unas con las otras, los enemigos asociados a esas habitaciones, los «tesoros», … y en teoría la información de la cámara.
Por desgracia ahora mismo carezco del tiempo para entender ese formato. Está pendiente porque con esa información podremos crear editores de mapas para todos los plataformas de Gremlin/Core por ejemplo el Jack The Nipper 2 ó el Mask 3 ó el Impossamole ó … pero ahora mismo es imposible sacar tiempo para eso.
El segundo gran problema son los enlentecimientos que se producen en el juego. Ésto también lo hemos comentado cuando hemos hablado del motor de sprites de los juegos de Gremlin/Core. Recordemos cómo funcionan, ellos no usan doble buffer, sino que tienen una región de memoria donde pintan los fondos ocupados por los sprites, luego pintan los sprites sobre esos fondos y por último los vuelcan a pantalla.
La peculiaridad de ese buffer oculto es que está dividido en tiras de un tamaño fijo, por decir, pueden ser 10 tiras. Entonces un sprite como Rick ocupa 3 tiras, un enemigo puede ocupar entre 2 y tres, los tesoros 2, … El juego va llenando ese buffer de forma dinámica.
La principal ventaja es que el tamaño es ínfimo comparado con un buffer oculto normal, el problema es que cuanto más sprites haya, más tardará el proceso de pintar fondo, pintar sprite usando máscaras y volcarlo a pantalla. Entonces normalmente funciona bien cuando solo está rick y un enemigo, pero en cuanto empezamos a tener más enemigos, los láseres, las plataformas móviles, los bonus, … la velocidad se empieza a resentir y mucho.
La idea original es que como estamos en los CPC+, podríamos hacer uso de los sprites hardware, para reducir la carga de CPU. Mi intención era comenzar por descargar a los sprites hardware todos esos sprites estáticos, como los bonus, ó todos aquellos que no cambian la animación como láseres y plataformas móviles. Y una vez tenemos eso, empezar a ver como pasar los bichos y el propio Rick a usar los sprites del CPC+, ya que recordemos lo pesado que es en consumo de memoria y cpu el pintar animaciones en los sprites hardware.
Con eso el juego pasaría a ir al frame y sería tan suave ó más que las versiones de 16 bits.
Pero de nuevo nos enfrentamos con un problema, el juego va insertando elementos en una estructura de tiras sprites y luego un montón de rutinas generales se encargan de gestionar ese motor de sprites. Entonces no existe un concepto de pinta un láser ó un bonus ó un Rick… sino que el código va procesando esas tiras.
Lo que significa que hay que desensamblar una buena parte del código del juego, y se ha hecho, pa colgao yo xDDDD pero ahora toca identificar y documentar todo eso, y con ese exceso de tiempo libre que tengo, eso va para largo, para 600 y largo….
Y el objetivo era sacar este proyecto del parón en el que estaba.
Al ver el trabajo y el tiempo que requería resolver estos dos problemas, mi motivación se fue a la fosa de las Marianas… y ahí se quedará hasta que dentro de unos años miremos de nuevo el código y podamos mejorar la jugabilidad.
Entonces para darle el impulso final que necesitaba este proyecto, por lo menos a nivel técnico, pensé que mi idea original de convertir el juego a una sola carga para máquinas con 128 KBs, no molaba. Y lo mismo hacer un cartucho donde lo único que íbamos a usar de los pluses era su paleta mejorada, ya que para mí un cartucho tiene que hacer uso de todas las características de los pluses que podemos.
Así que la cabeza se me fue para intentar crear una herramienta que nos permitiese crear lo que hubiese sido una versión comercial del juego en disco, usando el mismo formato y protecciones del original y que funcionase con 64 KBs. Como si en la época hubieses podido ir a la tienda y al pedir un RD2 para CPC+ te hubiesen entregado esta versión.
Al final, la parte con la que mejor me lo he pasado del proyecto es lo que nadie va a ver. Todo lo relativo a recrear ese disco original, parcheando los cargadores originales del juego para que se cargue nuestra versión parcheada, active el Asic, así como crear una herramienta que permite hacer masters de originales aplicando protecciones, … todo muy técnico y de lo más divertido.
Lo que si vais a ver es que hemos ganado una pantalla de carga alucinante 🙂
Y un poco eso… A parte de todo lo comentado, se corrigieron bastantes bugs en el juego.
Normalmente los juegos de 8 bits funcionan muchas veces de pura chorra y suelen estar plagados de bugs… ni que decir ir tiene que ésto es producto de las prisas por terminar los juegos, lo cual en el caso del cpc y juegos ingleses era todavía peor de lo normal, por ser nuestra máquina la tercera de 8 bits, por lo que difícilmente alguien probaba nuestras versiones. Lo cual es una pena porque por lo menos dar una pasada con trucos no debería haberles robado mucho tiempo y se podrían haber arreglado algunas cosas.
El otro problema es el desconocimiento, por falta de información de la máquina, lo cual podemos hasta perdonar. Pero también habia un desconocimiento cuando intentaban simplemente tratar al cpc como si fuese un spectrum, como esas conversiones de Cecco de finales de semana.
Aunque el error más llamativo que encontramos en el RD2 es que una vez abres el último nivel, algo que imagino que solo el Fran pudo ver en la época; pues eso una vez alcances el último nivel, si intentas jugar a los niveles 2, 3 ó 4, el juego se cuelga.
Cuando analice el error, todo parece indicar que fue otro fallo de copiar y pegar, el juego funciona de la siguiente forma, si le das a comenzar una partida, se inicializa el nivel (es decir, todos los bonus se activan, los enemigos se ponen en sus posiciones iniciales, los interruptores, …), a continuación si el nivel escogido no es el que está cargado en memoria, se carga y se comienza la partida.
¿Habéis visto dónde está el problema?
La inicialización del nivel es para el nivel que ya estaba en memoria, algo que no va a coincidir si nos toca cargar un nivel de disco. De hecho como los niveles tienen tamaños variables y las zonas a inicializar están en posiciones diferentes, esa inicializacion modificaba zonas de memoria que no debía tocar.
Ese error está produciéndose todo el tiempo, solo que no vemos ese cuelgue porque los niveles 2 a 4 tienen un tamaño similar, mientras que el 5 tiene un tamaño menor. Por eso solo se produce en ese instante, y que no ocurra con el nivel 1 ó que el juego no se cuelgue antes de llegar al nivel 5 es solo por suerte.
De hecho aunque se corrompen partes del mapa, como a continuación se carga el nivel de disco, todo vuelve a su estado original sin corrupciones.
En nuestro caso la solución fue bien sencilla, lo que hicimos fue intercambiar las dos rutinas, es decir, primero comprobamos si hay que cargar un nivel y después llamamos a la rutina de inicialización de ese nivel, no del nivel que estaba anteriormente en memoria.
Descarga: Rick Dangerous II+ por SyX y RedAngel


