Contenido
Introducción
Los archivos BCSV de SMG son la base de datos que tiene el juego para guardar información de distinto tipo: posición/configuración de los modelos/planetas en las galaxias, nombres de las zonas en una galaxia, caracteristicas de la colisión de un modelo KCL, etc. Las letras de la extensión BCSV significan, según otros, Binary Comma Separated Values. Los archivos BCSV son como los archivos CSV, son tablas para almacenar datos.

Tabla planetmapdatatable.bcsv
(ObjectData) en Blender 2.79.7 (Blenxy)
Funcionamiento
Como se mencionó arriba, los archivos BCSV son simplemente tablas para almacenar datos. Lo diferente de estas tablas es que la información está codificada y no puede verse directamente a través de un editor de texto, de allí el Binary en su nombre.
A diferencia de los CSV este tipo de tablas tienen las siguientes restricciones/características:
-
Los tipos de datos a escribir estan restringidos a 7 tipos. Son los 7 tipos que se han podido ver en tablas BCSV originales del juego. Los nombres acuñados por la comunidad para referirse a estos tipos son los siguientes:
LONG
: Generalmente se interpreta como un entero de 32 bits.STRING
: Generalmente se interpreta como una cadena de caracteres (se asume que está codificada en CP932) cuya codificación cabe en un espacio de 32 bytes (tiene que terminar en el caracter nulo).FLOAT
: Generalmente se interpreta como un número de punto flotante de 32 bits.LONG_2
: Generalmente se interpreta como un entero de 32 bits.SHORT
: Generalmente se interpreta como un entero de 16 bits.CHAR
: Generalmente se interpreta como un entero de 8 bits.STRING_OFFSET
: Generalmente se interpreta como un entero de 32 bits que se usa para especificar la posición de una cadena de caracteres (se asume que está codificada en CP932) de tamaño variable (tiene que terminar en el caracter nulo) en la "piscina de cadenas de caracteres" de la estructura BCSV.
- Todas las celdas de una columna están forzadas a ser de un tipo de dato en específico.
- Los tipos de datos
FLOAT
tienen que estar posicionados en una dirección multiplo de 4 bytes con respecto al inicio del archivo. Al juego no le gusta que no estén alineados. - Las tablas pueden contener 0 filas.
Definiciones
-
Tipo de dato: El tipo de los elementos a guardar en cada columna de la tabla.
LONG
: Entero de 32 bits. El tipo se especifica con el valor0x00
.STRING
: Cadena de caracteres de 32 bytes codificada en CP932. Usar el terminador nulo. El tipo se especifica con el valor0x01
.FLOAT
: Número de punto flotante de 32 bits. El tipo se especifica con el valor0x02
.LONG_2
: Entero de 32 bits. El tipo se especifica con el valor0x03
.SHORT
: Entero de 16 bits. El tipo se especifica con el valor0x04
.CHAR
: Entero de 8 bits. El tipo se especifica con el valor0x05
.STRING_OFFSET
: Entero de 32 bits que especifica la posición de una cadena de caracteres en la "piscina de cadenas de caracteres", codificada en CP932 de tamaño variable. Usar el terminador nulo. El tipo se especifica con el valor0x06
.
-
Piscina de cadenas de caracteres: Lista en la que se encuentran todas las cadenas de caracteres de tipo
STRING_OFFSET
referenciadas en las celdas de la tabla BCSV.Piscina de caracteres de
ObjectData/Butler/butler/butler.banmt
vista en ImHex. -
Información de cada columna: Una estructura de 5 datos que especifica para una sola columna, en orden, las siguientes características.
- El hash del nombre que identifica a la columna (truncado a 32 bits -- rutina de calculo).
- Una mascara de bits (32 bits) que se usa para extraer los bits deseados en los bytes de una celda de la columna. Parece que sólo se usa en los tipo entero.
- Un número (16 bits) que especifica la posición/offset del primer dato de la columna en la piscina de datos.
- Un número (8 bits) que especifica el número de desplazamientos de bit derecho que se le tiene que hacer al valor extraído con la máscara de bits para obtener lo que realmente estaba guardado. Parece que sólo se usa en los tipo entero.
- El tipo de dato (8 bits) que se almacena en las celdas de la columna.
Información de la primera columna de la tabla
groupinfo
deObjectData/PlanetDisk.arc
. -
Piscina de datos: Lista en la que se encuentran los valores de cada celda de la tabla BCSV. Los valores de las celdas en una fila pueden estar en el orden que se quiera. De forma original no están en el orden de aparición de las columnas, por alguna razón desconocida. La única restricción es que el tipo de dato
FLOAT
esté alineado, con respecto al inicio del archivo, a una dirección múltiplo 4 bytes. Esta lista contiene los datos de las filas una tras otra.Piscina de datos de la tabla
g0.bgrv
deObjectData/PlanetDisk.arc
.
Estructura
La estructura del archivo descrita aquí es la estructura que se ha conseguido en los archivos originales de SMG. Esta información no significa que la estructura tenga que ser exactamente como se describe en la página.
Encabezado
Nombre | Tamaño | Descripción |
---|---|---|
Número de filas | 4 bytes | Puede ser 0. |
Número de columnas | 4 bytes | No he encontrado un caso, pero asumo que el mínimo es 1. |
Posición de la piscina de datos | 4 bytes | Respecto al inicio del archivo, en bytes. |
Longitud en bytes de las filas | 4 bytes | La información de cada fila se encuentra en "una misma línea", este valor especifica el tamaño en bytes de esta línea. Se usa para encontrar los valores de cada celda de una columna y para calcular la posición de la piscina de cadenas de caracteres. |
Información de las columnas -- Se repite Número de columnas
veces
Nombre | Tamaño | Descripción |
---|---|---|
Hash del nombre de la columna | 4 bytes | Hash de la cadena de caracteres que identifica a la columna, truncado a 32 bits -- rutina de calculo. |
Máscara de bits | 4 bytes | Parece aplicar sólo a los tipos de dato entero: CHAR , SHORT , LONG y LONG_2 . Con este valor se extrae el valor que se guardó en el campo de bits. |
Posición del dato de la primera celda en la columna | 2 bytes | Posición respecto al inicio de la piscina de datos. Para conseguir el valor de la segunda celda (si existe) se le suma a la posición del dato el valor de Longitud en bytes de las filas . Con la nueva dirección, se repite lo mismo para conseguir el tercer, cuarto, ... valor en la tabla. |
Número de desplazamientos de bits derecho | 1 byte | Parece aplicar sólo a los tipos de dato entero: CHAR , SHORT , LONG y LONG_2 . Con este número se modifican los bits extraídos del campo de bits con la máscara de bits. |
Tipo de dato | 1 byte | Un número entre 0x00 y 0x06 especificando el tipo de dato a leer. |

Datos de la primera columna de la tabla groupinfo
de ObjectData/PlanetDisk.arc
.
En la imagen mostrada, se puede ver el uso de la posición del primer dato de la primera columna y la separación entre los datos de una misma columna. La tabla es un poco larga por lo que no se puede ver la piscina de cadenas de caracteres.
Piscina de datos
- Los datos se tienen que extraer usando la posición del dato de la primera celda en la columna. La longitud en bytes de las filas se usa para leer los datos de las celdas que vienen después en la misma columna.
- El tamaño de la piscina se calcula con
Número de filas * Longitud en bytes de las filas
. - Después de la piscina de datos viene la de cadenas de caracteres.
- Se desconoce la razón del ordenamiento no lineal de los valores de las celdas de las filas.
- Los tipos de dato
FLOAT
tienen que estar alineados en una dirección multiplo de 4 bytes con respecto al inicio del archivo. - El tipo de dato
STRING
no se ha encontrado en tablas originales pero el juego puede procesar este tipo de dato.
Piscina de cadenas de caracteres
- Las cadenas de caracteres generalmente estan codificadas en CP932.
- Todas terminan en el caracter nulo.
- Todas las cadenas que se encuentran aquí tienen su offset especificado en la piscina de datos. Este offset es con respecto al inicio de la piscina de caracteres.
- El tamaño de esta estructura no se puede determinar.
- Al final de la piscina usualmente se encuentra un "relleno" formado con caracteres
@
para hacer que el tamaño de archivo en bytes sea múltiplo de 32. Este relleno no parece ser necesario. - Pueden existir cadenas de caracteres "nulas", es decir, el offset especificado en la piscina de datos apunta a un caracter nulo directamente. Esto se interpreta como que no hay una cadena de caracteres asignada (como un campo vacio).
Ejemplo
Estructura coloreada de scenariodata.bcsv
de StageData/AstroGalaxy/AstroGalaxyScenario.arc
:

En la imagen de arriba se muestran los inicios de las informaciones de cada columna y la posición de todos los elementos de la primera columna.