Registrarse

[ASM] FR | Expandir la cantidad de MT/MO

hacanoca

Héroe de WaH
¡Hola a todos!
Antes de iniciar, quiero aclarar que este tutorial es en esencia una traducción del tutorial creado por ghoulslash en Pokecommunity. El link para el tutorial original se los presento a continuación:
https://www.pokecommunity.com/showthread.php?t=401063

Este método te permite tener hasta 128 MT/MO, las cuales deben estar en orden consecutivo en la lista de items. Sin embargo se permite tener una brecha entre estos items: Por decir algo tener las MT01 a MT58 seguidas y luego de otro montón de objetos, un segundo grupo con las MT59 a MO08.
Puedes ubicar a tu preferencia el ID de los items de las MT, sin embargo, se recomienda mantener las MT01-58 en su posición original (no hay problema con reemplazar las MO1-8 con MT51-58), y tener una brecha pequeña entre la MT58 y la MT59.

Herramientas necesarias
-Editor Hexadecimal (En mi caso HxD)
-Compilador de Assembly (Compilador de HackMew aquí)

Nota importante
El proceso es un poco largo y complejo, por lo que recomiendo hacer una copia de seguridad de la Rom.

Procedimiento

Paso 1: Expandir Objetos
Paso 1.1: Repuntear la tabla de información de Objetos
La tabla original está localizada en 3DB028. Tiene 375 objetos (contando el 0), cada entrada tiene una longitud de 44 bytes, lo que arroja una longitud total de 16500 bytes (Decimal). En esta página puedes encontrar información de la estructura de esta tabla.

Toma la cantidad total de objetos que requieras y multiplícala por 44, esa sería la cantidad de bytes necesarios para la nueva tabla. (Ejemplo:digamos te interesa expandir la cantidad de objetos a 415, entonces: 415*44=18260 bytes)

Busca por una localización que posea este espacio libre, en mi caso (que tengo rom expandida) la coloqué en 11AB9C4. En este espacio libre copia la información de la tabla original y llena el espacio restante con la información de los nuevos objetos (en mi caso todos los nuevos objetos:375-414 serán MT/MO), usa el editor de objetos que prefieras, en mi caso uso el GenIII Tools, pero debes ajustar la ini.

Una vez ya hayas armado la nueva tabla, debes buscar en la rom todas los punteros que conducian a la tabla original (28 B0 3D 08) y reemplazarlos por la posición de tu nueva tabla permutada (en mi caso C4 B9 1A 09).
Si no me equivoco son unas 15 direcciones las que hay que reemplazar.

Paso 1.2: Repuntear la tabla de imágenes/paletas de Objetos
La tabla original está localizada en 3D4294. La estructura de la tabla es la siguiente:
Cada entrada tiene 8 bytes así: [Puntero Imagen] [Puntero Paleta]
La longitud de la tabla sería: 375*8= 3000 bytes.

El proceso es el mismo que el del paso 1.1:

Toma la cantidad total de objetos que requieras y multiplícala por 8, esa sería la cantidad de bytes necesarios para la nueva tabla.
(Ejemplo: 415*8=3320 bytes)

Busca por una localización que posea este espacio libre, en mi caso (que tengo rom expandida) la coloqué en 11B0118. En este espacio libre copia la información de la tabla original y llena el espacio restante con los punteros imagen/paleta de los nuevos objetos. (Usa el editor de objetos que gustes)

Sólo hay puntero que conducía a esta tabla y está en 0x9899C, ve a esa dirección y cambia el puntero permutado de la tabla original (94 42 3D 08 por el de tu nueva tabla, en mi caso 18 01 1B 09).

Paso 1.3: Cambiar/Modificar los límites
En 0x9A8AE, reemplaza 81 42 01 D8 con 00 00 00 00

En 0x98998, reemplaza 77 01 con tu nuevo número de objetos en hexadecimal , forma "little endian": Para el ejemplo:
415 objetos: 415= 0x19F --> 9F 01

Paso 2: Nuevas MT
Acá es donde se empieza a complicar un poco, ya que es donde está el juego de la ubicación de las MT dentro de la lista ID de los objetos.
Tenemos 3 opciones a realizar:
La primera desarrollada por Taの境界, la cual mantiene la posición de las MT y MO originales del juego, lo cual deja la lista de las MO en medio de la lista de MT, la MO01 se mantendría tras la MT50 y la MT 51 estaría tras la MO08.
Esta opción puede generar problemas al momento de realizar la compatibilidad de las MT.

La segunda opción se debe aplicar cuando quieres que las MT se encuentren todas de forma consecutiva y las MO comiencen cuando estas finalicen. Además esta opción permite tener una brecha entre los ID de las MT (lo que se habló al principio).

La tercera opción se debe aplicar cuando ubicas tus MT/MO de tal forma que queden todas en orden consecutivo, MT y luego MO, pero sin ningún tipo de brecha. Esto por lo general implica mover la MT01 de su posición original ya que los objetos de "Tubo MT y Saco Bayas" son muy difíciles de modificar.

Independientemente de la opción a utilizar, hay algunos cambios que son comunes para todas.

Para hacer que los números de las MT tengan 3 dígitos, inserta 03 en 0x131DB6

Para hacer que los números de las MO tengan 2 dígitos, inserta 02 at 0x131D7C

Para ajustar el orden de las MT/MO, juega con el valor en 0x9A600. Viene por defecto en 0xA9 (que sería la posición original de la MT50 /2). Poner el valor del Id de tu primera MT /2 causaría que las MO aparezcan luego de las MT en la mochila.

Debes expandir la tabla de los movimientos MT, para lo cual debes repuntear la tabla:
La tabla original se encuentra en 45A80C. Tiene un total de 58 entradas (Una por movimiento MT/MO) y cada entrada tiene una longitud de 2 bytes.
Por lo tanto, la longitud total de la tabla es de 116 bytes (decimal, 74 en Hex). En mi caso, creé 40 objetos nuevos porque quiero 40 MT nuevas (Lo sé, lo sé, no estoy aprovechando que puedo tener hasta 120, pero bueno, será el ejemplo) Así que mi nueva tabla de movimientos MT/MO tendrá una longitud de: 98*2= 196 bytes (C4 en Hex).
Mismo procedimiento: Busco una zona con este espacio libre en la rom, y allí copio la info de la tabla anterior (en caso de querer conservar las mismas MT) y el espacio restante lo relleno con la info de las nuevas MT.
Lo que se debe poner en cada una de las entradas de esta tabla, es el número ID del movimiento que contiene cada una de las MT, por ejemplo:
La MT36 contiene Bomba Lodo, que tiene asignado el ID de mvto 188 (decimal) o BC (Hex), así que en la entrada número 36 de esta tabla se debe colocar BC 00, que sería el ID del movimiento en formato "little endian". MO08 contiene buceo, entonces le corresponde la ID 123 (Hex) así que se debe colocar 23 01 en su entrada para esta tabla.
Los ID de los movimientos los puedes ver en un editor de movimientos pkmn como el de GenIII Tools o bien en esta página.
Tras armar la nueva tabla de MT debes reemplazar los punteros que conducían a la tabla a la antigua por la dirección permutada de la nueva tabla. (Que si no me equivoco son sólo 2: 125A8C, 125AAC)
En mi caso, creé la nueva tabla en 11B0E7C, así que busco los offsets 0C A8 45 08 y los reemplazo por 7C 0E 1B 09.

Se dejará el código de Taの境界, que fue desarrollado para este escenario.
Para arreglar los números de las MT:
1.Seguir las instrucciones mencionadas debajo de la rutina
2. Inserta esta rutina en un espacio libre que esté alineado (el puntero debe terminar en 0,4,8 ó C)
3. Inserta 01 48 00 47 00 00 (XX+1) XX XX YY en 0x131D5A, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no)
Ejemplo: Si insertaste la rutina en 0x902364, el puntero permutado sería 65 23 90 08.

.text
.align 2
.thumb
.thumb_func
.global tm_name

main:
mov r0, #0xXX @(MT51 Objeto ID - 1) / 2 (ej. Para 375 -> 0xXX = 0xBB)
lsl r0, r0, #0x1
cmp r6, r0
bhi new_tm @si el Objeto ID de la MT51 es par, cambiar a bge

mov r0, #0xA9 @Objeto ID de la MT50 / 2
lsl r0, r0, #0x1
cmp r6, r0
bls old_tm

ldr r1, temp
ldr r0, return1
bx r0

new_tm:
ldr r1, text_no
mov r0, r5
bl refresh

ldr r4, ram
ldr r0, value
ldr r1, return3
bx r1

old_tm:
ldr r1, return2
bx r1

refresh:
ldr r2, routine
bx r2

.align 2
text_no: .word 0x08416226
routine: .word 0x08008DA5
temp: .word 0x08463178
return1: .word 0x08131D65
return2: .word 0x08131DA5
ram: .word 0x02021CD0
value: .word 0xFFFFFEBC
return3: .word 0x08131DB1

Para ajustar el índice de los movimientos MT:
1. Sigue las instrucciones de la rutina.
2. Cambia la dirección de "tm_table", 0x08YYYYYY, a la dirección de tu nueva tabla de movimientos MT. En mi caso: 0x091B0E7C.
3. Compilar e insertar la siguiente rutina en un puntero alineado (que termine en 0, 4, 8 ó C)
4. Inserta 00 49 08 47 (XX+1) XX XX YY en 0x125A78, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no).
.text
.align 2
.thumb
.thumb_func
.global TM_index

main:
mov r1, #0xXX @(Index de Objeto de la nueva primera MT-1) / 2 (ej. 0xBB para el objeto 375
lsl r1, r1, #0x1
cmp r0, r1
bhi newtm @si el Objeto ID de la MT51 es un número par, cambiar a bge

mov r1, #0x90 @(Locación de la MT01 - 1) / 2
lsl r1, r1, #0x1
add r1, r1, #0x1
sub r0, r0 ,r1
lsl r0, r0, #0x1
b exit

newtm:
add r1, r1, #0x1
sub r0, r0, r1
lsl r0, r0, #0x1
add r0, r0, #0x74 @116 / 2 -> 51st move ID

exit:
ldr r1, tm_table
add r0, r0, r1
ldrh r0, [r0]
bx lr

.align
tm_table: .word 0x08YYYYYY

La siguiente rutina obtiene el número del movimiento asignado a partir de un número de Objeto (ID de la MT)
Instrucciones
1.Seguir las indicaciones de la rutina (Más abajo encontrarás un ejemplo).
2. Inserta esta rutina en un espacio libre que esté alineado (el puntero debe terminar en 0,4,8 ó C)
3. En 0x131D5A escribe 01 48 00 47 00 00 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no)
Ejemplo: Si insertaste la rutina en 0x902364, el puntero permutado sería 65 23 90 08.

Este en particular fue la opción que yo (Hacanoca) seguí, así que procederé a explicar con mi caso, donde inserté 40 MT adicionales para un total de 98 MT/MO. En este caso, se conservó la posición original de las primeras 58 MT/MO, y las MT59-MO08 se ubicaron luego del objeto "Saphire"-ID:374. Por lo que los ID de los objetos quedaron así.

Obj. ID TM No.
289 TM01
290 TM02
291 TM03
292 TM04
293 TM05
294 TM06
295 TM07
296 TM08
297 TM09
298 TM10
299 TM11
300 TM12
301 TM13
302 TM14
303 TM15
304 TM16
305 TM17
306 TM18
307 TM19
308 TM20
309 TM21
310 TM22
311 TM23
312 TM24
313 TM25
314 TM26
315 TM27
316 TM28
317 TM29
318 TM30
319 TM31
320 TM32
321 TM33
322 TM34
323 TM35
324 TM36
325 TM37
326 TM38
327 TM39
328 TM40
329 TM41
330 TM42
331 TM43
332 TM44
333 TM45
334 TM46
335 TM47
336 TM48
337 TM49
338 TM50
339 TM51
340 TM52
341 TM53
342 TM54
343 TM55
344 TM56
345 TM57
346 TM58
~ ~
375 TM59
376 TM60
377 TM61
378 TM62
379 TM63
380 TM64
381 TM65
382 TM66
383 TM67
384 TM68
385 TM69
386 TM70
387 TM71
388 TM72
389 TM73
390 TM74
391 TM75
392 TM76
393 TM77
394 TM78
395 TM79
396 TM80
397 TM81
398 TM82
399 TM83
400 TM84
401 TM85
402 TM86
403 TM87
404 TM88
405 TM89
406 TM90
407 MO01
408 MO02
409 MO03
410 MO04
411 MO05
412 MO06
413 MO07
414 MO08

Luego (para este ejemplo):
1. 0xXX (Primera MO) se convertiría en 0xCB -> 0xCB * 2 + 1 = 407
La línea "add r0, #0x1" se debe conservar si este número es impar, de lo
contrario se debe remover dicha línea.
2. 0xYY (Primera MT luego de la brecha) se convertiría 0xBB -> 0xBB * 2 + 1 = 375
La línea "add r0, #0x1" se debe conservar si este número es impar, de lo
contrario se debe remover dicha línea.
3. 0xZZ (número de objetos entre TMs) sería 375 - 347 = 28 = 0x1C
En este cálculo difiero con el tutorial original, allí la resta sería 375-346= 29=0x1D, pero a mí me funcionó fue con 0x1C
4. 0xWW (Número de objetos entre la nueva MO01 y la antigua MO01) sería 407 - 339 = 68 = 0x44

.text
.align 2
.thumb
.thumb_func
.global TM_names

main:
mov r0, #0xXX @Objeto ID de la primera MO / 2 (ej. 407 = 0xcb * 2 + 1)
lsl r0, r0, #0x1
add r0, #0x1 @Si el Objeto ID de la MO01 es impar. Otherwise, remove this line
cmp r6, r0
bge HMItem @item ID >= first HM item ID

TMItem:
ldr r1, =(0x08416226)
mov r0, r5
bl refresh
ldr r4, .RAM
ldr r0, =(0xfffffee0)
add r1, r6, r0 @TM num

mov r0, #0xYY @(Objeto ID de la primera MT luego de la brecha)/ 2
lsl r0, r0, #0x1
add r0, #0x1 @Mantener esta línea si el Objeto ID es impar
cmp r6, r0
blt orderTM
sub r1, #0xZZ @Número de Objetos en la Brecha

orderTM:
mov r0, r4
ldr r2, =(0x08131db4 +1)
bx r2


HMItem:
ldr r1, =(0x08463178)
mov r0, r5
bl refresh
ldr r1, =(0x08416226)
mov r0, r5
bl refresh
ldr r4, .RAM
ldr r0, =(0xfffffeae)
add r1, r6, r0
sub r1, #0xWW @Diferencia de Objetos ID entre la NUEVA MO01 y la VIEJA MO01
ldr r0, =(0x08131d78 +1)
bx r0

refresh:
ldr r2, =(0x08008DA4 +1)
bx r2


.align 2
.RAM: .word 0x02021CD0

La siguiente rutina carga los ID de los movimientos de las TM:
Instrucciones:
1. Reemplaza 0xXX y 0xYY con los valores apropiados (comentarios en la rutina)
2. Reemplaza "0x08XXXXXX", con la dirección de tu nueva tabla de movimientos MT. En mi caso: 0x091B0E7C.
3. Compilar e insertar la siguiente rutina en un puntero alineado (que termine en 0, 4, 8 ó C)
4. En 0x125A78 escribe 00 49 08 47 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no).
.text
.align 2
.thumb
.thumb_func
.global TM_moves

main:
push {r2}
mov r2, #0xXX @(Objeto ID de la primera MT- 1) / 2. Si mantienes la misma posición, debería ser 0x90
lsl r2, r2, #0x1
add r2, #0x1 @Remover esta linea si el número de objeto es par

mov r1, #0xXX @(Objeto ID de la primera MT tras la brecha)/ 2 (ej. 375 -> 0xBB)
lsl r1, r1, #0x1
add r1, #0x1 @Remover esta línea si el Objeto ID de la primera MT tras la brecha es par
cmp r0, r1
blt getmove

jump:
add r2, #0xYY @número de objetos en la brecha (ej. Si MT58 es 346 y MT59 is 375, 0xYY = 0x1C)

getmove:
sub r0, r0, r2 @TM number
pop {r2}
lsl r0, r0, #0x1
ldr r1, .table
add r0, r0, r1
ldrh r0, [r0]
bx lr

.align 2
.table: .word 0x08XXXXXX

Esta primera rutina obtiene el movimiento ID de la tabla de movimientos MT:

Instrucciones:
1. Cambiar 0xXX por el Objeto ID de la primera MT / 2
2. Cambiar 0x08XXXXXX a la dirección de la nueva tabla de movimientos MT. En mi caso: 0x091B0E7C.
3. Compilar e insertar la siguiente rutina en un puntero alineado (que termine en 0, 4, 8 ó C)
4. En 0x125A78 escribir 00 49 08 47 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no). (ej. Si la inserté en 0x904378, --> 79 43 90 08)

.text
.align 2
.thumb
.thumb_func
.global TM_moves

main:
mov r1, #0xXX @Objeto ID de la primera MT/ 2, ej. 375 = 0xBB
lsl r1, r1, #0x1
add r1, r1, #0x1 @Remover esta línea si el Objeto ID de la priemra MT es par
sub r0, r0, r1 @TM #
lsl r0, r0, #0x1
ldr r1, .table
add r0, r0, r1
ldrh r0, [r0]
bx lr

.align 2
.table: .word 0x08XXXXXX

La segunda rutina ajusta el número de MT en la mochila.

Instrucciones:
1. Ajusta 0xXX, 0xYY, 0xZZ basado en los apropiados Objetos ID (seguir indicaciones de la rutina)
2. Compilar e insertar la siguiente rutina en un puntero alineado (que termine en 0, 4, 8 ó C)
3. En 0x131D5A escribir 01 48 00 47 00 00 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no) (ej. Si se insertó en 0x906714 --> 15 67 90 08)

main:
mov r0, #0xXX @Objeto ID de la MO01 / 2 (ej. Si MO01 es 495, entonces 0xXX = 0xF7)
lsl r0, r0, #0x1
add r0, #0x1 @Remover esta línea si el Objeto ID de la primera MO es par
cmp r6, r0
bge HMItem

TMItem:
ldr r1, =(0x08416226)
mov r0, r5
bl refresh
ldr r4, .RAM
ldr r0, =(0xfffffee0)
add r1, r6, r0
sub r1, #0xYY @Número de objetos entre NUEVA MT01 y VIEJA MT01 (ej. 375 - 289 = 86 = 0x56)
mov r0, r4
ldr r2, =(0x08131db4 +1)
bx r2

HMItem:
ldr r1, =(0x08463178)
mov r0, r5
bl refresh
ldr r1, =(0x08416226)
mov r0, r5
bl refresh
ldr r4, .RAM
ldr r0, =(0xfffffeae)
add r1, r6, r0
sub r1, #0xZZ @Objeto ID de NUEVA MO01 - VIEJA MO01 (ej. 495 - 339 = 156 = 0x9C)
ldr r0, =(0x08131d78 +1)
bx r0

refresh:
ldr r2, =(0x08008DA4 +1)
bx r2


.align 2
.RAM: .word 0x02021CD0

Paso 3: Compatibilidad de las MT
Para mí este es sin duda la parte más engorrosa de todo el proceso.
Al tener una cantidad total de 128 MT/MO, la tabla de compatibilidad queda con una longitud de 16 bytes para cada pokémon, para cada entrada. Lo anterior hace que la anterior tabla de compatibilidad que trae por defecto el juego sea obsoleta.
Por lo tanto se debe crear una nueva tabla de compatibilidad de MT cuya longitud total será de 16 bytes por pokémon. Adicionalmente, se debe insertar una rutina que permita leer apropiadamente la información de la nueva tabla.
La rutina a implementar no chequea la especie Pokémon 0x0, ni los espacios para los PKMN ???? entre Celebi y Treecko.
Por lo tanto, la primera entrada de la tabla corresponde a la especie ID 0x1 (usualmente Bullbasaur), y la entrada 252 o 0xFC, estaría ocupada por Treecko. Si quieres utilizar el espacio de las especies "????" debes modificar apropiadamente la rutina y organizar tu tabla de compatibilidad acorde a lo que requieres.

Bien, ahora, ¿cómo realizar la tabla de compatibilidad?
Cada entrada de la tabla está compuesta de 4 segmentos, cada uno de 4 bytes (para un total de 16 bytes por entrada).
El primer segmento corresponde a las MT 1-32, el segundo a las MT 33-64, el tercero a las MT 65-96 y el cuarto a las MT 97-128
En primer lugar debes escribir cada segmento en formato binario indicando cuáles MT puede aprender el pokémon:
0: no puede aprender la MT.
1: Sí puede aprender la MT.
Por ejemplo,tu quieres que el pokemon aprenda las siguientes MT 3, 7, 20, 54, 87, y 102:



Entonces el número binario de cada segmento quedaría así
1-32: 00000000000010000000000001000100
33-64: 00000000001000000000000000000000
65-96: 00000000010000000000000000000000
97-128: 00000000000000000000000000100000

Una vez tengas los 4 segmentos en números binarios debes convertirlos al sistema hexadecimal, para eso, puedes usar diversas herramientas como la calculadora de windows en "versión programador", o existen diversas páginas que te ayudan con esta parte. En mi caso yo utilicé esta.

El tutorial original de Pokecommunity tiene un programa en phyton que ayuda con esta parte de la creación de la tabla, aunque yo no sé bien como utilizarlo y no lo hice o_O

Para el caso del ejemplo cada segmento en sistema hexadecimal quedaría de esta forma:
1-32: [00 08 00 44]
33-64: [00 20 00 00]
65-96: [00 40 00 00]
97-128: [00 00 00 20]
Para ingresarlos a la tabla de compatibilidad debes permutarlos y combinarlos, por lo tanto, los 16 bytes de la entrada de ejemplo quedaría así:
44 00 08 00 00 00 20 00 00 00 40 00 20 00 00 00

Esto, para cada uno de los pokémon...
(Ya ven por qué digo que es el paso más engorroso :( )

Por cierto, ¿qué hacer si no creaste 128 MT/MO, sino que agregaste menos?
Ese fue el caso que hice, la rutina está planeada para las 128 MT/MO, por lo que debes crear los segmentos de la misma forma, en mi caso que llegué hasta las 98 MT/MO, debo llenar estos segmentos colocando 0 en todas las MT 99-128; como si fueran MT que ningún pkmn puede aprender.

Ahora bien, tras un arduo trabajo y haber creado la tabla de compatibilidad, nos queda faltando insertar la rutina para que la rom lea bien los datos de dicha tabla.

Instrucciones:
1. Reemplazar "0x08XXXXXX" con la dirección de la nueva tabla de compatibilidad. (Ej, en mi caso la inserté en 11B0F70, así que reemplazo ese valor por 0x091B0F70)
2a. Reemplazar 0xXX con el valor de número de MT antes de la brecha en los objetos + el número de objetos en la brecha de objetos. Para nuestro ejemplo, tenemos la MT58 con el Objeto ID 346 y 375 para la MT59, entonces 0xXX = 58 + 28 = 0x56)
2b. Reemplazar 0xYY con el número de objetos en la brecha de Objetos. Para el ejemplo, 0xYY sería 28 = 0x1C
3. Compilar e insertar la siguiente rutina en un puntero alineado (que termine en 0, 4, 8 ó C)
4. En 0x43C40 escribir 00 48 00 47 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no) (ej. Si se insertó en 0x11B0F40 --> 41 0F 1B 09)

.text
.align 2
.thumb
.thumb_func
.global tm_compatability

get_compat_start:
mov r3, r1 @r3 = species ID
sub r3, #0x1 @start table at 0 (aka ignore stupid 0th species)

check_glitch_mons:
cmp r3, #0xFC @first glitch pokemon species ID
blt get_table_entry
sub r3, #0x19 @25 glitch pokes (eg. Treecko becomes entry 0xFC in compatability table)

get_table_entry:
lsl r3, r3, #0x4 @16 * (species ID -1)
ldr r1, .table
add r3, r1, r3 @table start + 16*species = start of selected species compatability
mov r2, #0x1

@if used third option where all TMs are in consecutive order with no gap
@remove check_gap and newtm

check_gap:
cmp r4, #0xXX
blt check @if r4 < 0xXX, TM is in consecutive order

newtm:
sub r4, #0xYY @num items in TM gap

check:
cmp r4, #0x1f @ 31 -> 0-31
bls first_32
cmp r4, #0x3f @ 63 -> 32-63
bls first_64
cmp r4, #0x5f @ 95 -> 63-95
bls first_96

last_word: @ 96-128
sub r4, #0x60
lsl r2, r4
add r3, #0xC @last word in table address
b get_compat_word

first_96:
sub r4, #0x40
lsl r2, r4
add r3, #0x8
b get_compat_word

first_64:
sub r4, #0x20
lsl r2, r4
add r3, #0x4
b get_compat_word

first_32:
lsl r2, r4

get_compat_word:
ldr r0, [r3]
and r0, r2

exit:
pop {r4-r5}
pop {r1}
bx r1

.align 2
.table: .word 0x08XXXXXX @tm compatability table

Paso 4: Remover la animación de las MT/MO
Esta rutina funciona bien excepto que cuando se remplazan antiguos movimientos mediante el aprendizaje de un movimiento de MT/MO, el juego se congela en la animación de la MT. Por lo tanto, se debe remover dicha animación.
Para removerla:

1. Insertar 00 00 en 0x11CE6E
2. Insertar 00 F0 0E FA en 0x11CA2C
3. Insertar 00 00 00 00 00 00 00 00 00 00 00 00 44 E0 en 0x11CD9E

Paso 5: Expandir el límite de objetos en la maleta
Necesitas tener aplicado el "JPANs save block hack" para lograr que la información de los objetos quede debidamente guardada en RAM libre.

Si sólo quieres expandir la cantidad de MT en la mochila, usa esta rutina:

Instrucciones:
1. Cambia la RAM libre a tu propia locación.
2. Compila e inserta en un puntero libre alineado.
3. En 0x99E6A, escribe 01 48 00 47 00 00 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no)

.text
.align 2
.thumb
.thumb_func
.global tm_slots_hack

main:
ldr r0, ram
str r0, [r1, #0x18]
mov r0, #0x80
strb r0, [r1, #0x1c]
ldr r0, return
bx r0

.align
ram:.word 0x0203cXXX
return:.word 0x08099e74+1

Si quieres expandir todos los tipos de objetos en la mochila, usa esta rutina:

Instrucciones:
1. Cambia la RAM libre a tu propia locación.
2. Define la cantidad máxima de objetos que quieres en cada clase de objeto (esta cantidad la puedes escribir en decimal o si la pones en Hex recuerda anteponerle el "0x")
3. Compila e inserta en un puntero libre alineado.
4. En 99E50 inserta 00 48 00 47 (XX+1) XX XX YY, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no)

.text
.align 2
.thumb
.thumb_func
.global pocket_size_limiters

.equ freeRAM, 0x0203cXXX
.equ NumMainPocketItems, XX
.equ NumKeyItems, XX
.equ NumPokeballs, XX
.equ NumTMs, XXX
.equ NumBerries, XX

MainPocket:
ldr r0, .MainPocketRAM @start of expanded item data
str r0, [r1] @store new RAM pocket data address into DMA memory
mov r0, #0x4B @75 main pocket items
strb r0, [r1, #0x4]

KeyItems:
ldr r0, =(freeRAM + (4*NumMainPocketItems))
str r0, [r1, #0x8]
mov r0, #NumKeyItems
strb r0, [r1, #0xC]

PokeballsPocket:
ldr r0, =(freeRAM + (4*NumMainPocketItems) + (4*NumKeyItems))
str r0, [r1, #0x10]
mov r0, #NumPokeballs
strb r0, [r1, #0x14] @store limiter

TMsPocket:
ldr r0, =(freeRAM + (4*NumMainPocketItems) + (4*NumKeyItems) + (4*NumPokeballs))
str r0, [r1, #0x18]
mov r0, #NumTMs
strb r0, [r1, #0x1C] @store 128 into TM pocket limiter

BerriesPocket:
ldr r0, =(freeRAM + (4*NumMainPocketItems) + (4*NumKeyItems) + (4*NumPokeballs) + (4*NumTMs))
str r0, [r1, #0x20]
add r1, #0x24
mov r0, #NumBerries
strb r0, [r1]
bx lr


.align 2
.MainPocketRAM: .word freeRAM

Notas adicionales
1. Si tú añades nuevos movimientos MO y el nombre de su movimiento asociado tiene 13 caracteres de longitud, el nombre se mostrará junta al nombre de la siguiente MO. He aquí una solución a ese problema:

Instrucciones:
1. Compila e inserta la siguiente rutina en un espacio libre.
2. Inserta 00 48 00 47 (XX+1) XX XX YY en 0x8DAC, donde (XX+1) XX XX YY es el puntero permutado del sitio donde insertaste esta rutina +1 (YY es porque puede ser 08 o 09 según la insertes en una zona de rom expandida o no)
.text
.align 2
.thumb
.thumb_func
.global NameLimit

Main:
push {r3}
mov r3, #0x0

Loop:
ldrb r0, [r2]
cmp r0, #0xFF
beq Exit
cmp r3, #0xF
beq Exit
add r3, #0x1
add r2, #0x1
b Loop

Exit:
mov r0, r2
bl SubRout
pop {r3}
pop {r1}
bx r1


SubRout:
push {lr}
mov r3, r0
b InnerLoop

OuterLoop:
strb r2, [r3]
add r3, #0x1
add r1, #0x1

InnerLoop:
ldrb r2, [r1]
mov r0, r2
cmp r0, #0xFF
bne OuterLoop

ExitLoop:
mov r0, #0xFF
strb r0, [r3]
mov r0, r3
pop {r1}
bx r1



.align 2

2. Si estás añadiendo nuevos movimientos MO, este tema te puede interesar para crear los efectos de campo.

3. El autor del tutorial original solicita que si se tiene alguna duda del procedimiento o se encuentra algún bug, por favor se le reporte en su tema.
Igualmente, me interesa que me reporten si detectan fallos, ya que es una expansión que utilizaré en mi hack.

4. Por si les interesa, también existe este tema para la expansión de los objetos en la mochila (paso 5), asumo que también será compatible, pero no lo he intentado.

Les dejo una imagen que ilustra algunas de las nuevas MT que ingresé en la rom:


Por último quiero dar los créditos a:
- ghoulslash: Por la creación del tutorial original.
- Taの境界 y Jambo51: por la investigación y trabajo realizado en este tema.

No siendo más...
Espero que se entienda bien. :)
 

~Criisss

Usuario mítico
Respuesta: ASM-Expandir la cantidad de MT/MO-FR

Excelente tutorial. Lo había visto en pokeco hace poco y me pareció super interesante, aunque mi limitación con el inglés no ayuda. Las ediciones largas en hex no son para todos, pero con el resultado final realmente vale la pena intentarlo. Gracias por traerlo en español!
 

Gold

Porrero a tiempo parcial
Miembro insignia
Respuesta: ASM-Expandir la cantidad de MT/MO-FR

El tutorial ya lo habia leido antes e incluso aplicado a mi hack, pero reverti los cambios cuando vi lo jodidamente tedioso que era volver hacer la compatibilidad para todos los 386 Pokemon. Para alguien con paciencia infinita le va a venir de perlas.
 

Eddie

U Got Woomy
Respuesta: ASM-Expandir la cantidad de MT/MO-FR

Un bien tutorial sin lugar a dudas. justamente me había planteado eso y vi el tutorial en PokeCo hace poco (nivel de ingles jodidamente malo). Por lo mismo agradezco que te hayas tomado la molestia de traducir (en cierto punto) uno de los tutoriales mas difíciles del RH (eso creo).

GoodBye
 

hacanoca

Héroe de WaH
Respuesta: ASM-Expandir la cantidad de MT/MO-FR

Qué tal un qué tal un parche?
No sé, no lo veo tan claro.
Porque la tabla de compatibilidad varía mucho según el hack de cada quien.
Un parche implicaría que el hack que lo va a aplicar deba mantener una cantidad establecida de MT/MO, con un orden y ataques ya definidos, además también implica que el hack deba mantener el mismo orden de Pokédex con el cual se hizo el parche.
Este tutorial en general es útil para hacks que añaden ataques nuevos de otras generaciones y nuevos Pokémon, por lo tanto, limitarlos a los ataques y Pokemon con los que se haga el parche....creo que no es útil.
 

GaboExtreme

El Ayudante Infinito
Respuesta: ASM-Expandir la cantidad de MT/MO-FR

ooooooh esta muy interesante.

de verdad que es un buen aporte, pero se podría hacer en otras plataformas como ruby.
 

Nachoius

Caminante del cielo
Respuesta: FR | ASM | Expandir la cantidad de MT/MO

Genial bro gran aporte es algo que men queda pendiente en mi hack expandir ataques y las mt expandidas tb sería un lujo
 
Arriba