Hace mucho que no ponga nada, pero creo que esta información es interesante para todos aquellos que quieran modificar los textos de los scripts en SCI (motor de Sierra Online). Estoy haciendo un software que intentará hacerlo automáticamente, pero tardaré.
ESPECIFICACIONES:
----------------------
Cuando se lee un número de bytes, siempre se leen al revés; es decir si ves "82 00" en el editor hexadecimal, esto se lee como "00 82". Esto es por el sistema endian de los PCs.
0x45, 0x0A... = Representación en hexadecimal de un byte.
ushort = son 2 bytes sin signo (siempre es un número positivo).
byte[] = array de bytes.
offset = posición dentro de un archivo.
0x00 = null (no tiene representación en carácter ASCII).
SCRIPT FORMATO:
----------------------
TIPO NOMBRE DESCRIPCIÓN
-----------------------------------------------------------------------------------
ushort CABECERA Indica que es un archivo script (siempre 0x0082)
byte[] BLOQUE Un tipo de bloque (hay 10 tipos de bloques, ver
BLOQUE FORMATO)
ushort FIN Todos los scripts terminan con 0x0000.BLOQUE FORMATO:
-------------------------
Se leen los bloques hasta que se encuentre FIN (0x0000).
TIPO NOMBRE DESCRIPCIÓN
-----------------------------------------------------------------------------------
ushort TIPO Tipo de bloque
ushort TAMAÑO Tamaño del bloque en bytes incluyendo
los 4 bytes del inicio (2 bytes de TIPO y
2 bytes de TAMAÑO).
byte[] DATOS El bloque en sí.Cada BLOQUE es diferente, los nueve tipos son:
0x0001 = objeto
0x0002 = código
0x0003 = lista de sinónimos de palabras
0x0004 = especificaciones para palabras
0x0005 = cadenas de texto
0x0006 = clases
0x0007 = exportaciones
0x0008 = tabla de recolocación
0x0009 = texto de precarga
0x000a = variables locales
Los BLOQUES que interesan para traducir textos son el 5, el 2 y, a veces, el 9.
BLOQUE 5:
----------------------
Simplemente son cadenas seguidas una detrás de otra que terminan con el carácter null (Ejemplo: SkaZz mola0x00mucho mucho0x00mogollon0x00). Si se modifica el tamaño del bloque, hay que cambiar también TAMAÑO en el bloque.
BLOQUE 2:
----------------------
Es código y algo complicado. SCI usa opcodes en este caso. ¿Qué son opcodes? Bueno, son bytes que representan una función. Por ejemplo, uno que nos interesa es el opcde 0x72 (lofsa) que carga textos de nuestro BLOQUE de "cadenas de texto". Bueno, este BLOQUE no tiene que aumentar ni disminuir, tan sólo modificar los punteros a nuestros textos. Al lado del opcode 0x72, hay un ushort que determina un offset pero este es relativo. Esto me dio muchos quebraderos de cabeza, pero al fin entendí su (francamente estúpida) forma. El offset real es el offset indicado más la posición siguiente a este offset leído. Toma ya. Me explico con un ejemplo:
script.997 de SQ3
El BLOQUE "código" en la posición del archivo 0x07 tiene los bytes "72 34 04". Cogemos el primer byte que es un opcode, el "72" que es lofsa, y luego los dos siguientes bytes "04 34" que sería la posición al primer offset de nuestro texto: " 0x01 " (un 0x01 entre dos espacios, porque en sus fuentes representa un carácter). Sin embargo, cuando vamos a esa posición, resulta que ese texto está en "04 3E". De acuerdo, pues ahora miramos la posición siguiente a "04 34" que es la 0x0A. ¿Qué pasa si sumamos 04 34 + 0A, pues que es igual a 04 3E. ¡¡¡Aleluya!!!
Miremos el siguiente opcode "72" que está en la posición 0x0B y que es "72" y offset "04 34". ¡¡¡Es igual que el anterior!!! Pues usamos la misma fórmula:
1. Cogemos el offset (04 34)
2. La posición siguiente a este offset (0x0E)
3. Sumamos ambos: 0434+0E = 04 42
4. Buscamos esa posición en el archivo y voilá ("About game`^a :Help`#1 :VaporCalc`^c ")
5. Nos tocamos por la alegría (opcional)
COSAS A TENER EN CUENTA:
-------------------------------------
- Puede haber varios bloques de código (aunque no es muy habitual).
- No hay que olvidar modificar el TAMAÑO del BLOQUE 5.
- Hacer una pasada al BLOQUE 2 para modifcar los offsets.
De momento tengo hecho un programilla que carga el script, divide los bloques y permite modificar los textos... pero aún queda hacer una pasada al código porque habrá que reescribirlo byte a byte.
Un saludo, espero que esto os ayude.