Extracción e Inserción en textos y gráficos Devil Suvivor 2

Lugar donde se intentarán resolver problemas específicos
Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 28 Jun 2012, 22:01

Se j*d* la culebrilla 3, la 2.0 y todas las versiones, que paso de instalarlas.

Este fin de semana, entre cerveza y cerveza, creo que tendré hecho todo (paso del DS1, que hace mucho calor para meterse con 3 juegos a la vez). Me llego en el cálculo de punteros, cuando se vuelven borrachos y se balancean 6 pasos a la izquierda y 7 a la derecha, pero para mí es ((offset & 0x03FFFFFF) >> 1) + 1, y me ahorro tropecientas instrucciones.

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 30 Jun 2012, 12:04

La tool del empaquetador ya está terminada y sólo queda dejar un poco más decente el código fuente, que lo haré según tenga ganas, que estos días de calor me han dejado reventado y estoy hecho polvo. Si es que siempre me pasa lo mismo, me pongo malito los fines de semana, puñeteras leyes de Murphy. Ya no hay que crear la tabla de ficheros ni generar una tabla con los punteros para extraer/insertar las cosas, se hace todo de golpe.

El DS2 utiliza compresiones de la BIOS, como LZSS y RLE, y otras que no, como la mal llamaza LZ11. No sé si habrá alguna más, que no me apetece mirar la cabecera de todos los ficheros, pero parece que se pueden usar las tools habituales para tratar esos ficheros, lo que correrá a cargo de quienes quieran trabajar con el juego.

Sobre el DS1, lo más probable es que si lleva la misma estructura pero fallan las tools de Skye es porque el hash se calcule de forma diferente. Al menos ésa es la impresión que da. Si alguien lo puede comprobar, y no quiero mirar a Skye ni señalarla con el dedo, que es de mala educación, toda información será bien recibida para añadir a la tool.

Si alguien conoce algún otro juego en el que se use la misma estructura, con 3 ficheros de extensiones NDX/IDX/BIN, que lo diga para ver si también se puede añadir a la tool.

~~~ AÑADIDO ~~~
Me respondo a mí mismo.

Juegos que funcionan con la tool:
- Radiant Historia (USA y JAP)
- Devil Survivor 2 (USA y JAP)

Juegos que no funcionan con la tool:
- Devil Survivor (USA y JAP)
- Etrian Odyssey III (USA y JAP)

Skye
Mensajes: 95
Registrado: 03 Ago 2011, 20:09

Mensaje por Skye » 30 Jun 2012, 19:16

Ese iba a decir yo, el Etrian Odyssey III xD

Y lo frustrante del tema es que el hash se calcula exactamente igual. De hecho, algunos archivos los saca perfectamente, pero otros no.

Lo raro (o no) es que precisamente los archivos que no saca, o que saca mal, no parecen existir en el IDX. En el BIN están, pero al buscar el offset dividido por 4 en el IDX, no aparece. Igual es por eso, porque lo demás es exactamente igual.

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 30 Jun 2012, 19:52

Lo estuve mirando y sí, el hash se calcula igual. El "tema" está en el famoso bit0, mira por dónde, que hace algo cuando es 0. Incluso apuntan a zonas que están fuera del fichero. El offset que se saca del hash 11 debería estar en el hash 10. Los que tienen los 6 bytes a cero no me preocupan, que estoy seguro de que son hash sin usar. Curiosamente, la longitud parece estar bien pues suele dar valores idénticos a los de otros hash, así que serán de ficheros similares.

Código: Seleccionar todo

hash=000  idx0=00000008  data=00 00 00 00 00 00  idx1=00000000  length=00000000 <--- bit0=0
hash=001  idx0=0000000E  data=11 60 00 D0 02 00  idx1=00003008  length=000000B4
hash=002  idx0=00000014  data=4D 60 00 A0 11 00  idx1=00003026  length=00000468
hash=003  idx0=0000001A  data=73 60 00 D0 02 00  idx1=00003039  length=000000B4
hash=004  idx0=00000020  data=F1 60 00 00 08 00  idx1=00003078  length=00000200
hash=005  idx0=00000026  data=2D 61 00 10 0C 00  idx1=00003096  length=00000304
hash=006  idx0=0000002C  data=53 61 00 D0 02 00  idx1=000030A9  length=000000B4
hash=007  idx0=00000032  data=E7 61 00 90 6D 00  idx1=000030F3  length=00001B64
hash=008  idx0=00000038  data=4F 62 00 D0 02 00  idx1=00003127  length=000000B4
hash=009  idx0=0000003E  data=CD 62 00 D0 02 00  idx1=00003166  length=000000B4
hash=00A  idx0=00000044  data=77 63 00 00 01 00  idx1=000031BB  length=00000040
hash=00B  idx0=0000004A  data=C9 63 00 D0 02 00  idx1=000031E4  length=000000B4
hash=00C  idx0=00000050  data=47 64 00 D0 02 00  idx1=00003223  length=000000B4
hash=00D  idx0=00000056  data=6D 64 00 00 08 00  idx1=00003236  length=00000200
hash=00E  idx0=0000005C  data=D5 64 00 D0 02 00  idx1=0000326A  length=000000B4
hash=00F  idx0=00000062  data=3D 65 00 D0 02 00  idx1=0000329E  length=000000B4
hash=010  idx0=00000068  data=7A 0B B4 8C 0C 00  idx1=005A05BD  length=00000323 <--- bit0=0
hash=011  idx0=0000006E  data=E7 65 00 D0 02 00  idx1=000032F3  length=000000B4
hash=012  idx0=00000074  data=65 66 00 50 0F 00  idx1=00003332  length=000003D4
...
Si tienes a mano el desensamblado de lo que hace después de calcular el hash, cuando coge los valores del IDX, ya sabes lo que tienes que hacer. También es coña que el único bit que no sabemos para qué sirve sea el que revienta todo.

Curiosamente, ni el RS ni el DS2 tienen algún bit0 a 0, por lo que nunca da esos problemas.

Skye
Mensajes: 95
Registrado: 03 Ago 2011, 20:09

Mensaje por Skye » 30 Jun 2012, 21:37

Pues a ver, desde que hace hash AND 0x7FF:

[spoil]

Código: Seleccionar todo

mov r2,#0x6
mul r2,r0,r2 ;r0 tiene el hash ANDeado
ldr r1,&#91;r7,#0x4&#93; ;r1 ahora tiene el offset del idx
add r0,r1,#0x8
add r7,r0,r2 ;r7 = offset de los 6 bytes
ldrb r0,&#91;r0,r2&#93;
ldrb r2,&#91;r7,#0x1&#93;
ldrb r3,&#91;r7,#0x2&#93;
strb r0,&#91;r6&#93;
ldrb r0,&#91;r7,#0x3&#93;
strb r2,&#91;r6,#0x1&#93;
ldrb r2,&#91;r7,#0x4&#93;
strb r3,&#91;r6,#0x2&#93;
strb r0,&#91;r6,#0x3&#93;
ldrb r3,&#91;r7,#0x5&#93;
ldr r0,&#91;r6&#93; ;los primeros 4 bytes
strb r2,&#91;r6,#0x4&#93;
mov r2,r0,lsl #0x1F
strb r3,&#91;r6,#0x5&#93;
movs r2,r2,lsr #0x1F
bne #0x210A1BC

si sale false&#58;

ldr r1,&#91;r6,#0x4&#93; ;el 5to byte
mov r2,r0,lsl #0x6
mov r2,r2,lsr #0x7
mov r1,r1,lsl #0x10
mov r3,r2,lsl #0x2
mov r2,r1,lsr #0xA
ldr r1,&#91;r13,#0x4&#93;
str r3,&#91;r1&#93;
add r1,r2,r0,lsr #0x1A
ldr r0,&#91;r13&#93;
str r1,&#91;r0&#93;
b #0x210A2E0

si sale true&#58;

mov r3,r0,lsl #0x6 ;r0 eran los 4 primeros bytes
ldrb r12,&#91;r1,r3,lsr #0x7&#93; ;primer byte del bloque de punteros
ldr r2,&#91;r6,#0x4&#93; ;el 5to byte
ldr r14,&#91;r13,#0x8&#93;
mov r2,r2,lsl #0x10
add r3,r1,r3 lsr #0x7
mov r2,r2,lsr #0xA
add r11,r2,r0,lsr #0x1A
mov r1,r14

luego&#58;

cmp r12,#0x0
add r2,r3,#0x1 ;r3 = offset del bloque de punteros
ble #0x210A2D4

si sale false empieza el bucle hasta que encuentra el puntero
si sale true se lo salta y va directamente a&#58;

cmp r14,#0x0
moveq r0,#0x1
streq r0,&#91;r13,#0x8&#93;
ldr r0,&#91;r13,#0x8&#93;
add r13,r13,#0x14
ldmfd r13!,&#123;r4-r11,r15&#125;
[/spoil]

Parece ser que, por lo menos en el Radiant, en el primer branch siempre sale True (he puesto un break ahí, he jugado un rato, y no se ha cortado). Así que lo interesante es lo que hace cuando sale False, donde básicamente:
Si los primeros 4 bytes son AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
Y el quinto byte es 000000000000000000000000aaaaaaaa
Acaba con algo como 000000000000000000aaaaaaaaAAAAAA

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 30 Jun 2012, 22:16

Creo que ya sé por dónde van los tiros, pero tengo que pulirlo un poco más, y ahora ya no estoy por la labor de hacerlo, que estoy hecho una mierdecilla.

El problema es el cálculo del hash, que, además de tener que ponerlo en minúsculas, que eso ya estaba controlado, ahora no hay que poner el carácter '/' al principio. Sólo con eso parece que ya me da bien el número de ficheros de cada hash, y los datos "raros" que hay son basura residual, o sea, que el bit 0 se inicializa a 0 y se pone a 1 cuando hay algún fichero con ese hash, sin importar lo que haya en los 6bytes-1bit restante.

Si puedes comprobarlo con alguno de esos juegos, mira a ver antes de calcular el hash cómo está almacenada la ruta completa de un fichero, y a partir de dónde comienza a calcular el hash.

Los primeros ficheros deberían dar:

Código: Seleccionar todo

hash=45D  name=Data/2D/2D_keyboard_obj.bin
hash=6E1  name=Data/2D/2D_keyboard_obj_pal.bin
hash=7A6  name=Data/2D/2D_map_obj.bin
hash=69A  name=Data/2D/2D_map_obj_pal.bin
hash=5E1  name=Data/2D/2D_sea_obj.bin
hash=425  name=Data/2D/2D_sea_obj_pal.bin
...
(pongo el nombre real, pero el cálculo lo realiza con todo en minúsculas)
Parece que todo coincide, excepto para el primer fichero, que da un hash que apunta a 0x00000000. Parece ser que hay que tomar diferente número de bits para calcular el offset. Si tienes el proceso localizado en el RH habría que buscar lo mismo ahora, a ver en qué cambia, a no ser que ya esté en lo que has puesto, pero no estoy con fuerzas para verlo ahora.

~~~ AÑADIDO ~~~
Ni caso a lo que he puesto, que está claro que todo lo que me he tomado hoy tenía que hacer efecto. Consigo sacar muchos ficheros, pero algo no termina de ir bien. Lo único que he hecho es que grabe el fichero si el puñetero bit0 es 1, ignorando cuando es 0, pero así descarto el primer fichero. Ya lo miraré cuando esté mejor, con más calma.

~~~ MÁS AÑADIDO ~~~
No puede uno estar ya enfermo, joer. Bueno, parece que después de un vaso de leche se ven mejor las cosas (y que lo tenga que decir yo, cervecero de toda la vida, hay que joderse). Creo que el puñetero bit 0 sólo se activa cuando hay más de un fichero con el mismo hash, algo así como para decirle que hay ionformación extendida. Si sólo hay un fichero guarda el offset del BIN y la longitud en los 6 bytes de la tabla de hashes. Si es así, entonces ya está al 100% completado el análisis de los ficheros NDX/IDX para sacar toda la morralla del BIN.

Skye
Mensajes: 95
Registrado: 03 Ago 2011, 20:09

Mensaje por Skye » 01 Jul 2012, 13:56

Pues tienes razón, ya que

Código: Seleccionar todo

hash=010  idx0=00000068  data=7A 0B B4 8C 0C 00  idx1=005A05BD  length=00000323 <--- bit0=0 
el idx1 ese tiene toda la pinta de ser un offset dividido por 4 del IDX.

Anda, que el programador de Atlus al que se le haya ocurrido este sistema... xD

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 01 Jul 2012, 14:31

Sólo queda que me confirmes que si pones algo a mano en el sexto byte se tiene en cuenta para hacer los cálculos, que imagino que sí para que la longitud del fichero pueda meterse en 22 bits en vez de en 14, que son muy pocos, aunque creo que he visto en algún caso que sí tenía algo ese byte.

He sacado todo de los 8 juegos, contando USA y JAPAN, y lo he vuelto a meter, quedando todo idéntico. Ahora tengo que meter algunos controles más, controlando que los tamaños de los ficheros y sus offsets puedan meterse en sus bits correspondientes, sin pasarse. Las pruebas modificando ficheros os las dejo a vosotros.

¿Cuándo vais a tenerme los 4 juego traducidos, hoygan?

Drek9
Mensajes: 10
Registrado: 04 Sep 2012, 16:14

Mensaje por Drek9 » 14 Sep 2012, 13:28

Le estoy echando un ojo al devil survivor 2, la verdad es que me interesa traducirlo ya que después de jugarlo me ha gustado mucho.

Pero no sé comoo extraer el texto de los overlay una vez descomprimidos ni tampoco de los ficheros en data/tbl/ para poder editarlos de forma más cómoda y luego insertarlos.

¿Me podéis echar una mano con eso?

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 14 Sep 2012, 14:27

Pues ya te digo que es tarea enorme.

Los ficheros los sacas de los tres "Target" que hay en el juego con la utilidad que está posteada por ahí:
- para desempaquetar: packer Target

Ahora viene lo divertido. Los ficheros ".cmp" están comprimidos. Así, a simple vista, hay dos compresiones, aunque no descarto que haya más. Si el primer byte del fichero es 0x10 es una LZSS, y si es un 0x11 es la que llaman LZ11. También necesitas las utilidades que están posteadas por el foro:
- para LZSS: LZSS -d fichero
-para LZ11: LZX -d fichero
En caso de que haya otras compresiones, el primer byte sería 0x30 (RLE) ó 0x24/0x28 (Huffman). No creo que el juego use otras aparte de ésas.

Además de muchos textos, las fuentes están comprimidas.

Los textos son harina de otro costal. Por lo que he visto, todo está codificado en Shift-JIS. En los ficheros ".bin", como el BIBLE.BIN, parece tener al principio los punteros a los textos, seguidos de los textos en SJIS. El AUCTION.BIN no tengo ni idea de cómo guarda los punteros. En la carpeta "Event\", después de descomprimir todo, deben estar los textos del juego, pero tampoco sé exactamente cómo van, aunque sólo he mirado por encima, y puede que sea más simple porque antes de los textos parece habe numeritos característicos. Si tengo tiempo y me apetece, luego paso el HUSMEATOR para ver si son los offsets. Y no he mirado más, que cuando la cuenta de ficheros excede el número de dedos de mis manos me lío mucho y me quedo todo el día hecho polvo.

Si hay textos en los overlays o en el ARM9, y si están comprimidos, deberás usar el BLZ, aunque eso requiere de explicaciones posteriores para poder volverlo a comprimir.

Los gráficos, a excepción de las fuentes, parecen ser los normales de la consola, así que no creo que den mucho problema.

Y bueno, con eso ya te haces una idea de cómo está el tema. Es bastante trabajo para una persona, incluso para muchas, que de entrada "sólo" hay 24509 ficheros extraídos del Target.

Drek9
Mensajes: 10
Registrado: 04 Sep 2012, 16:14

Mensaje por Drek9 » 14 Sep 2012, 17:22

En el arm9 no estoy seguro pero en los overlay si hay texto tras descomprimirlos con BLZ puedes verlo en shis jis.

Es cierto, el bible tiene pinta de sencillo pero habría que revisar bien los cmp de event, ya que es la historia y en esos no sé como podría extraerlo bien.

Sí hay muchos ficheros, pero lo importante es modificar la fuente y al menos traducir los textos de la carpeta event, es lo que quiero hacer en principio. También los de data/tbl y los de AUCTION si se consigue saber como están almacenados. Pero creo que lo principal es al menos la historia, luego ya es ir "mejorando" el proyecto jeje.

Gracias por todo CUE, a ver si esto sale adelante y me pongo a traducir.

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 14 Sep 2012, 19:22

Pues he mirado dos de los ficheros de "Event\" con el HUSMEATOR y son de los más simples. Espero que todos sean igual.

Primero los descomprimes con LZX: LZX -d Event\*.cmp (si queda alguno sin descomprimir miras a ver si usa otra compresión).

Los textos están en un bloque al final del fichero, por lo que meter textos de más es factible. El bloque de texto se encuentra en la posición indicada en 0x0000C0. Míralo bien porque no me apetecía comprobar muchos ficheros.

El bloque de textos tiene como estructura:

cabecera:
- 4 bytes con el tamaño del bloque
siempre será el tamaño total del fichero menos el valor de 0x0000C0

punteros:
- 4 bytes con su offset relativo, empezando a contar desde el inicio de los punteros
el número de punteros, o textos, que es lo mismo, es el resultado de dividir el primer valor entre 4

textos
- la parrafada en SJIS, con un código 0x00 como fin de texto

Al final parece que el fichero se alinea a 4 bytes, o sea, que se añaden ceros hasta que la longitud sea múltiplo de 4.

Con todo eso se puede una sencilla herramienta para extraer/insertar los textos, pero eso ya se lo dejo a otro.

Ya hablaremos de cómo vas a pagarme las cervezas.

Drek9
Mensajes: 10
Registrado: 04 Sep 2012, 16:14

Mensaje por Drek9 » 14 Sep 2012, 19:50

Por lo que veo si hay diferentes tipos de ficheros en EVENT.

Los que tú has descrito son los ficheros b_*.cmp que se ajustan a esos datos.
Pero hay otros diferentes, los d_*.cmp y los e_*.cmp aunque los e_*.cmp salvo el primero, el resto son sencillos. Tabla al inicio y texto después.

Pero los textos en shis jis siempre me han dado problemas. No sé como extraerlos, no es como cuando están es ascii que elaborar la herramienta para extraer es más sencillo o será que con shis jis no sé... ¿Cómo puedo hacerlo para extraer en ese formato de caracteres?

Avatar de Usuario
CUE
Administrador
Administrador
Mensajes: 5521
Registrado: 24 Ene 2011, 16:52

Mensaje por CUE » 14 Sep 2012, 20:31

Los e_* son sencillotes:

cabecera
- 4 bytes con el número de textos

punteros:
- 4 bytes por cada puntero, empezando a contar desde el inicio del fichero

textos:
- textos Shift-JIS terminados en 0x00

El primer e_* que mencionas es como los b_*.


Los d_* también son facilones:

- punteros a los textos en 0x000020 y 0x000028

textos:
- textos Shift-JIS terminados en 0x00, sin punteros aparentes


Lo de los SJIS también es una tontería. Lo hicieron así los japoneses porque les ocupa menos espacio que usando UTF8 y pueden aprovechar también el ASCII normal.

Primero abre http://msdn.microsoft.com/en-us/goglobal/cc305152 para hacerte una idea de cómo va la cosa.

- si es un código de 7 bits (0x00-0x7F) es tal cual, con la excepción de que los japoneses no usan la barra invertida y ponen el símbolo del yen en su lugar
- del 0xA1 al 0x0xDF van los katakana de medio ancho
- el resto, excepto esos pocos no usados que hay en la tabla, se componen de 2 bytes

Resumiendo: cualquier cosa occidental ocupa 1 byte y la oriental 2. Así es más sencillo de recordar.

En algún sitio del foro puse una tabla completa para poder ver los caracteres con WindHex. Yo suelo usar otra para transformar los códigos SJIS a UNICODE, que es más decente. Mañana miro a ver dónde está o la subo de nuevo.

Así que lo único que hay que hacer es leer un byte, comprobar si necesita un segundo byte, transformar a UTF8 o UNICODE para trabajar más fácilmente, y ya está todo.

Drek9
Mensajes: 10
Registrado: 04 Sep 2012, 16:14

Mensaje por Drek9 » 14 Sep 2012, 21:46

Perfecto, apuntado queda para hacer la herramienta.

Y ya sobre la tabla, en cuanto la subas le hecho un ojo para transformar los códigos al ir leyendo bytes.

Y luego hay que volver a transformarlo a shift jis, verdad? ya que el juego no lo acepta en ascii

Muchas gracias de verdad!

Responder