Introducción:Vista la falta de turoriales en castellano para el uso de wiird y usbgecko, voy a escribir un tutorial lo más simple y detallado posible sobre el uso básico de wiird para la creación de trucos / RAM Hacks.
Hay una serie de conceptos básicos que no me voy a parar a explicar porque entiendo que la mayoría ya los conocemos, no obstante si alguien tiene alguna duda no tiene más que preguntar.
Voy a usar principalmente el juego que se usa en la mayoría de tutoriales de Wiird, el Super Mario Galaxy por 3 motivos: lo tiene casi todo el mundo, es sencillo encontrar los valores que busquemos en el juego y cuenta con muchos de los casos con los que nos podemos encontrar a la hora de crear trucos.
Material necesario (es bastante obvio, pero por si acaso):-Wii con posibilidad de cargar hombrew y la última versión de
Gecko Os.
-Super Mario Galaxy (si quieres comprobar los pasos del tutorial, para usarlo en otros juegos evidentemente sólo necesitas el juego correspondiente).
-USBGecko
-Un PC con Windows, con los
drivers de USBGEcko instalados y con la última versión de
Wiird.
Conceptos y abreviaturas para este tutorial:Base adress (a partir de ahora lo llamaremos ba): o dirección base, como prefiráis. Por defecto siempre es 80000000. está es la dirección a la que hay que sumar el offset que ponemos en los códigos, se puede cambiar, pero hay que recordar volver a poner la dirección por defecto al final de código.
Pointer offset (a partir de ahora po): Un puntero, los que sepáis algo de programación ya sabéis lo que es y para los que no en resumen la función de un puntero es guardar una dirección de memoria (la ba también es un puntero). Por defecto también está a 80000000, su uso es similar al de la ba, en el propio código queda indicado si debe empezar en la ba o en el po. Al igual que con la ba conviene resetearlo al final del código.
Yo prefiero usar el po cuando es posible, pero es a gusto de cada uno, en algunas situaciones convendrá usar uno u otro o habrá que usar ambos, en cualquier caso es bueno saber que contamos con las 2 opciones.
Códigos necesarios para este tutorial:00XXXXXX 000000YY (escribe el valor de 8bits YY en ba+XXXXXX)
10XXXXXX 000000YY (escribe el valor de 8bits YY en po+XXXXXX)
02XXXXXX 0000YYYY (escribe el valor de 16bits YYYY en ba+XXXXXX)
12XXXXXX 0000YYYY (escribe el valor de 16bits YYYY en po+XXXXXX)
04XXXXXX YYYYYYYY (escribe el valor de 32bits YYYYYYYY en ba+XXXXXX)
14XXXXXX YYYYYYYY (escribe el valor de 32bits YYYYYYYY en po+XXXXXX)
40000000 XXXXXXXX (le da a la ba el valor del contenido de la dirección de memoria XXXXXXXX)
42000000 XXXXXXXX (le da a la ba el valor XXXXXXXX)
48000000 XXXXXXXX (le da al po el valor del contenido de la dirección de memoria XXXXXXXX)
4A000000 XXXXXXXX (le da al po el valor XXXXXXXX)
E0000000 80008000 (Full Terminator, hace varias cosas, pero para lo que atañe a este tutorial, sirve para resetear el po y la ba, es buena idea terminar así los códigos en los que cambies el po o la ba)
Para más información (en inglés) sobre códigos
http://wiird.l0nk.org/codetypes.html o podéis preguntar aquí
Empezamos (por fin):Tendréis que perdonar que no ponga vídeos del juego ya que la no tengo una capturadora a mano y poner simples capturas de pantalla me parece absurdo.
Bien pues cargamos Super Mario Galaxy con Gecko Os y abrimos Wiird. A mi me gusta tener la consola de wiird abierta al lado por lo que le doy a "Show WiiRd", pero es opcional.
Cogiéndole el tacto:Vamos a buscar un primer truco fácil, por ejemplo los trocitos de estrella, así que cargamos una partida y vemos los trocitos que tenemos, en mi caso 3727.
Lo primero que tenemos que hacer es decidir el tamaño de dato que vamos a buscar, en este caso buscare valores de 16bits ya que 3727 no cabe en 8bits (sí,soy amigo del capitán obvio, ¿que pasa?)
Así que marcamos Specific Value (porque sabemos el valor que queremos buscar) y 16bits, ponemos el valor a buscar en el recuadro y pulsamos "Convert Dec to Hex" (en mi caso queda 0E8F) y le damos a Start. A mi me gusta entrar en el menú HOME antes de hacer una búsqueda, pero también es opcional.
Empezará a dumpear la memoria y cuando acabe tendremos algo así:
Como vemos han aparecido 30 dirección con ese valor, a ti te pueden quedar más o menos ( Aviso: lo normal, casi siempre que se hace una primera búsqueda es que aparezcan muchas más), pero son demasiadas como para comprobarlas una por una, así que vamos a cambiar el valor y hacer una segunda búsqueda. Así que vuelvo al juego, lanzo una cuantos trozos de estrella y me quedo con 3722 (0E8A), cambiamos el valor en el recuadro correspondiente de Wiird y le damos a Search.
En este caso hemos tenido mucha suerte y a la segunda nos ha quedado un solo valor:
Si en lugar de uno nos hubieran quedado muchos valores, habría que seguir repitiendo el procedimiento hasta que quedaran entre 1 y 4 valores (o más si quieres, pero cuantos más queden, más tendrás que comprobar).
Bien, vamos a comprobar que el el valor es correcto, hacemos click derecho sobre la dirección que nos ha quedado y elegimos "-> Poke" y veremos que los recuadros de abajo se rellenan con la direccion y con el valor de "Old Value", pues vamos a poner el valor que queramos, por ejemplo 270F (9999) y pulsamos Poke:
Y veremos como efectivamente el numero de estrellas empieza a subir hasta esa cifra.
Si tuvieramos varias direcciones que comprobar, repitimos este mismo proceso hasta encontrar la dirección que funciona.
Ahora vamos a convertir eso en un código GCT:
02F63D1E 0000270F
Explicación:
02: Valor de 16bits usando ba para la dirección.
F63D1E: Dirección a usar menos ba.
270F: Valor a escribir en la dirección.
Lo podemos comprobar en la pestaña GCT codes:
Le damos a "Add New Code", le cambiamos el nombre al que queramos pinchando 2 veces sobre "New code 1", ponemos el código en el recuadro de la derecha y le damos a "Add Code", pinchamos en el cuadrado de la izquierda del código que ha aparecido (ver imagen) y aparecerá un asterisco, por ultimo pinchamos "Apply codes" y comprobamos que funcione. Efectivamente, por muchos trocitos que lancemos siempre volvemos a tener 9999.
Fácil ¿verdad?, vamos a hacer unos apuntes:
-Si con este proceso no nos hubiera dado ningún resultado, podemos repetirlo cambiando el Memory Range a 90.
-¿Que pasa si la dirección en lugar de ser la que hemos encontrado es por ejemplo 81F63D1E o 90F63D1E? Con un código como el anterior solo podemos llegar a la dirección 80FFFFFF. La solución es cambiar la ba o cambiar el po y usar un codigo del tipo 12. En código, imaginando que la direccion fuera 81F63D1E:
42000000 81000000
02F63D1E 0000270F
E0000000 80008000
ó
4A000000 81000000
12F63D1E 0000270F
E0000000 80008000
Ambos son perfectamente válidos, yo prefiero usar el segundo, pero cada cual que elija su estilo
.
Avanzando:Hasta aquí todo muy fácil, pero vamos a buscar un truco más útil, vamos a hacer que Mario no pierda vida, así que vamos a entrar en una pantalla, por ejemplo a la primera misión de la galaxia ovoestrella, le damos a Restart en wird, damos a yes y a yes, dejamos 8bits(que ya está seleccionado por defecto) y vamos a realizar el mismo proceso que realizamos antes, empezando con el 3 y perdiendo o ganado trozos de vida, haciendo búsquedas (No voy a explicar el proceso de nuevo).
Cando hayáis encontrado la dirección correcta (en este caso 810B5CF7) creamos el código, por ejemplo:
4A000000 81000000
100B5CF7 00000003
E0000000 80008000
y comprobando que funciona diréis, ¡cojonudo ya no pierde vida!, vamos a otra pantalla... y entramos, por ejemplo en la segunda misión de la misma galaxia. Con nuestro código activado vamos a dejar que nos ataque un enemigo... ¿eh, que ha pasado, ha bajado la vida, por qué? Pues muy sencillo, porque el valor que indica la vida de Mario ya no está en la misma dirección de memoria, ha cambiado de posición, ¿y cómo sabe entonces el juego donde tiene que mirar la vida de Mario? Pues para eso el juego crea unos punteros que le indican donde tiene que mirar.
El puntero no tiene porque apuntar directamente a la dirección que nos interesa si no que suele apuntar a donde comienza un bloque con varios datos.
¿Que hacemos ahora? Pues ahora entra en juego la pestaña Pointer Search.
Primero vamos a buscar por el método habitual la dirección en la que se encuentra ahora la vida. En este caso en 810B62AB.
Una vez encontrada hacemos click derecho sobre ella y marcamos "-> Pointer1".
Ahora sí, pasamos a la pestaña "Pointer search" y veremos que el valor ha quedado escrito en "Address 1", bien pues ahora vamos a pulsar el botón Dump de arriba y esperamos a que termine. Ahora necesitamos otro dump y otra dirección para compararlos, así que vámonos a otra pantalla, por ejemplo vamos a volver a la primera misión.
Comprobamos que la dirección que encontramos antes (810B5CF7) sigue funcionando (si no fuera así tendríamos que buscarla de nuevo), así que la escribimos en "Address 2" y le damos al botón Dump de debajo (de nuevo esperamos a que acabe). Por último pulsamos "Search".
Aquí nos pueden salir desde uno a vete-tú-a-saber-cuántos resultados. (si no nos sale ninguno estamos jo***os
). En este caso nos salen muchísimos, eso sí a la derecha nos salen los mejores resultados (que son los que apuntan directamente o a una dirección no muy lejana), hay que tener en cuenta que es posible que varios de ellos sean válidos, así que vamos a empezar a comprobar esos "Best results" uno por uno.
Así que me voy a ir a una tercera pantalla, por ejemplo la tercera misión de la misma galaxia. Vamos a comprobar el primer valor que nos daba como resultado [806B7B14]. Para ello nos vamos al "Memory Viewer" y en el recuadro que hay entre "Auto Update" y "Display Type" introducimos la dirección y pulsamos Enter. Esto nos lleva a esa dirección y nos muestra su contenido, en este caso 810B87A4, vamos ahora a introducir esa dirección, en el recuadro y vemos que el valor de esa dirección es (en mi caso) 80, como sabemos debería ser 03, ésta no es, así que repetimos el proceso con el siguiente puntero que nos dio el pointer search.
Para los puntero que tengan un +loquesea, por ejemplo [806B7B40]+383, primero vamos a 806B7B40, luego al valor que contenga le sumamos lo que corresponda (en este caso 810B62B8 + 383 = 810B663B) y por último vamos a esa dirección (810B663B).
Ahora sí, esto es un 3, vamos bien, pero vamos a asegurarnos, marcamos la casilla de Auto-Update y nos dejamos atacar para que baje la vida. Efectivamente vemos que el valor ha bajado a 2.
Así que parece que ya lo tenemos, desactivamos el Auto Update para que nos deje cambiar de pestaña y vamos a hacer el código:
48000000 806B7B40
10000383 00000003
E0000000 80008000
Explicación (aunque a estas alturas ya no debería
):
48000000 806B7B40: le decimos que le dé a po el valor contenido en 806B7B40
10000383 00000003: escribimos el valor de 8bits 03 en la dirección po+383
E0000000 80008000: este está ya explicado
Lo activamos y para comprobar que funciona bien nos vamos a cualquier otra pantalla y comprobamos que no nos baja la vida. ¡Buen trabajo!
Otras búsquedas:Bueno, hasta ahora hemos buscado valores concretos, pero ¿y si no sabes cual es el valor concreto de lo que buscamos?, por ejemplo en barras de vida y cosas similares en la que no hay un número que buscar. Pues vamos a buscar este ejemplo con el mario-abeja.
Vamos a la primera misión de la galaxia Reino de Abejas y nos hacemos con el mario-abeja. Uy, pero que abeja más debilucha, se cansa en seguida de volar, eso hay que solucionarlo... vamos a hacer que no le baje la barra de resistencia de vuelo.
Pero, ¿cuanto vale la barra de resistencia llena? no tenemos ni idea, tampoco sabemos si es un valor de 8bits, 16 o 32.
Vamos a empezar, vamos a "Code Search" y vamos a marcar "Unknown value" y en tamaño de dato vamos a empezar con 8bits, si no nos funcionase haríamos otra búsqueda con 16 y si tampoco con 32 (puedes hacerlo al revés si lo prefieres).
Vamos al lío, con mario en reposo, le damos a start y esperamos a que acabe, evidentemente no nos va a mostrar ningún resultado ya que como no sabemos que buscamos es un dump de todo el rango de memoria en el que estamos buscando. Cuando termine, vamos al juego y hacemos que vuele un poco, entramos en el menu HOME, para que no se recupere y vamos al wiird, en "Compare Types" marcamos "Less than" (ya que hemos bajado el nivel de la barra) y le damos a search. Nos devolverá un montón de direcciones (en mi caso me devuelve 316147 direcciones), así que tenemos que repetir el proceso hasta que encontremos la dirección adecuada. Cuando tengamos la barra más llena que la última vez que buscamos, marcaremos "Greater than" y cuando este más vacía "Less than".
También podemos combinar búsquedas de valores desconocidos, con búsqueda de valores conocidos, por ejemplo en está búsqueda, cuando tenemos la barra completamente vacía podemos cambiar a "specific value" y el "compare type" a Equal y buscar 0, esto nos ayudará a acelerar un poco la búsqueda.
En este caso encuentro la dirección 810B57FF, asi que en "Memory Viewer" me voy a esa direccion y activo el Auto Update, para comprobar que valor tiene cuando la barra está llena y veo que es B4 (180), así que ya tenemos lo necesario para preparar el código:
4A000000 81000000
100B57FF 000000B4
E0000000 80008000
Esta vez no lo voy a explicar, que a estas alturas seguro que ya lo entendéis
Y listo ¡Ya tenemos una abejita que vuela hasta el infinito y más allá!
Con este código os pasaría lo mismo que con el de la vida, cuando cambiéis de pantalla no funcionará, así que habría que buscar punteros, pero esta vez os lo dejo a vosotros
Y así llegamos al final de este tutorial, cualquier duda o corrección es siempre bienvenida.Este tuto no habría sido posible sin los foros de wiird y la gente que en ellos escribe, que son auténticos fenómenos
.
Próximamente, Tutorial nivel medio: Uso de condicionales, switchs on/off y registros-gecko. Casos prácticos: Uso de combinaciones de botones para activar/desactivar trucos.Un saludo.