La saga de Carnivores - Los archivos .rsc

The Carnivores saga - The .rsc files

Estructura de los archivos .rsc:
Structure of the .rsc files:

Estos archivos se encuentran en el subdirectorio HUNTDAT\AREAS tanto en Carnivores como en Carnivores 2 y Ice Age y complementan a los archivos .map, y el formato usado en el primero es sólo ligeramente distinto al que se usa en los otros dos. Los archivos consisten en varios bloques, empezando por un bloque de cabecera que tiene 32 bytes de largo para Carn1 y 80 bytes de largo tanto para Carn2 como CarnIce. Otras diferencias entre Carn1 y Carn2/IA son que Carn1 sólo almacena un único mapa de bits del cielo, mientras Carn2/IA usan 3, sendos para el alba, día y noche; y que los archivos .rsc de Carn2/IA tienen un bloque de datos de agua añadido al final.
These files are located in the HUNTDAT\AREAS subfolder both in Carnivores and in Carnivores 2 and Ice Age and they complement the .map files, and the format used in the former is only slightl different from the one used in the other two. The files consist of several blocks, starting with a header block which is 32 bytes long for Carn1 and 80 bytes long both for Carn2 and CarnIce. Other differences between Carn1 and Carn2/IA are that Carn1 only stores a single sky bitmap, while Carn2/IA use 3 ones, one each for dawn, day and night time; and that Carn2/IA .rsc files have a block of water data added at the end.

El formato exacto del bloque de objetos aún necesita determinarse. Mientras que las texturas resultan muy fáciles (tantos mapas de bits uno tras otro, de 128x128 pixels a 16 bits, como indique el valor en la cabecera), los objetos en 3-D son más complicados. Primero hay datos de los puntos y triángulos que conforman el objeto (varían en número dependiendo de éste), y después viene un mapa de bits de 16 bits que siempre tiene 256 pixels de ancho pero puede variar en alto también dependiendo del objeto, para tantos objetos como indique la cabecera. Después de eso, el resto del archivo consiste nuevamente de bloques que son muy sencillos: el cielo, que es un mapa de bits de 256x256 pixels a 16 bits (3 consecutivos en Carn2/IA), luego el mapa de bits de niebla, en 128x128 pixels y escala de grises de 8 bits, luego el número de diferentes nieblas para el mapa y los correspondientes datos para cada uno de ellos (el color de la niebla, su altura, densidad, distancia mínima y si es o no venenosa), luego el número de sonidos aleatorios en el mapa seguido por la longitud y el segmento de datos para cada uno, luego similarmente el número de sonidos ambientales y la longitud y datos para cada uno, y finalmente una tabla indicando cuáles sonidos aleatorios son utilizados y cómo. Aún necesito determinar el formato exacto de los bloques de objetos para poder 'llenar el vacío' y extraer el resto de la información de lo archivos .rsc después de las texturas (lo cual es la razón por la que hasta ahora sólo he sacado un visualizador de texturas, aún no paso de ahí). Gracias a Austin Wolfclaw, quien mencionó cómo extraer sonidos de los archivos .car, y a algo más de análisis, he determinado que los sonidos están almacenados en formato PCM mono de 16 bits, a 22050 Hz, y podrían fácilmente ser reproducidos o exportados a formato .WAV.
The exact format of the objects block needs still to be determined. While textures are pretty much straightforward (as many 128x128 pixels, 16-bit bitmaps one after the other, as many of them as the header value indicates), 3-D objects are more complicated. First there's data of the points and triangles which conform the object (they vary in number depending on it), and then comes a 16-bit bitmap which is always 256 pixels wide but may vary in height as well depending on the object, for as many objects as the header indicates. After that, the rest of the file consists again of blocks which are pretty straightforward: the sky, which is a 256x256 pixels, 16-bit bitmap (3 consecutive ones in Carn2/IA), then the fog bitmap, in 128x128 pixels and 8-bit grayscale, then the number of different fogs for the map and the corresponding data for each one of them (the fog color, its height, density, minimum distance and wether it's poisonous or not), then the number of random sounds on the map followed for the length and data chunk for each one, then similarly the number of ambient sounds and the length and data for each one, and finally a table indicating which randdom sounds are utilized and how. I still need to determine the exact format of the object blocks so I can 'fill the gap' and extract the rest of the info from the .rsc files past the textures (which is the reason currently I've only released a textures viewer, I can't get past that yet). Thanks to Austin Wolfclaw, who mentioned how to extract sounds from the .car files, and to some further checking, I've determined that the sounds are stored in 16-bit mono PCM format, at 22050 Hz, and could be easily played back or exported to .WAV format.
Tipos de datos empleados:/Data types used:

Para Carnivores:
For Carnivores:

Bloque de cabecera/Header block:

long num_textures (número de texturas/number of textures)
long num_objects (número de objetos/number of objects)
long atm_light_R (iluminación atmosférica, componente rojo/atmospheric lighting, red component)
long atm_light_G (iluminación atmosférica, componente verde/atmospheric lighting, green component)
long atm_light_B (iluminación atmosférica, componente azul/atmospheric lighting, blue component)
long unknown_R (desconocido/unknown)
long unknown_G (desconocido/unknown)
long unknown_B (desconocido/unknown)

Bloque de texturas/Textures block:

word texture1[128,128] (mapa de bits de textura #1/texture #1 bitmap)
word texture2[128,128] (mapa de bits de textura #2/texture #2 bitmap)
... etc.

Bloque de objetos/Objects block:
Tantos segmentos de objetos individuales como indica la cabecera, cada uno dividido en sub-bloques como sigue:
As many individual object chunks as indicated in the header, each one divided in sub-blocks as follows:

Sub-bloque de cabecera/Header sub-block:
long Ob1 (desconocido/unknown)
long Ob2 (desconocido/unknown)
long Ob3 (desconocido/unknown)
long Ob4 (desconocido/unknown)
long Ob5 (desconocido/unknown)
long Ob6 (desconocido/unknown)
long Ob7 (desconocido/unknown)
long Ob8 (desconocido/unknown)
long Ob9 (desconocido/unknown)
long Ob10 (desconocido/unknown)
long Ob11 (desconocido/unknown)
long Ob12 (desconocido/unknown)
long Ob13 (desconocido/unknown)
long Ob14 (desconocido/unknown)
long Ob15 (desconocido/unknown)
long Ob16 (desconocido/unknown)
long num_points (número de puntos/number of points)
long num_triang (número de triángulos/number of triangles)
long num_bones (número de huesos/number of bones)
long long_tex (longitud del bloque de textura/length of texture block)
Sub-bloque de triángulos/Triangles sub-block:
num_triang bloques de 64 bytes cada uno, como sigue:/num_triang blocks of 64 bytes each, as follows:
long Tn_Point1 (punto 1 triángulo #n/triangle #n point 1)
long Tn_Point2 (punto 2 triángulo #n/triangle #n point 2)
long Tn_Point3 (punto 3 triángulo #n/triangle #n point 3)
long Tn_CoordX1 (coordenada X punto 1 textura triángulo #n/triangle #n texture point 1 X coordinate)
long Tn_CoordX2 (coordenada X punto 2 textura triángulo #n/triangle #n texture point 2 X coordinate)
long Tn_CoordX3 (coordenada X punto 3 textura triángulo #n/triangle #n texture point 3 X coordinate)
long Tn_CoordY1 (coordenada Y punto 1 textura triángulo #n/triangle #n texture point 1 Y coordinate)
long Tn_CoordY2 (coordenada Y punto 2 textura triángulo #n/triangle #n texture point 2 Y coordinate)
long Tn_CoordY3 (coordenada Y punto 3 textura triángulo #n/triangle #n texture point 3 Y coordinate)
long Tn_U1 (desconocido/unknown)
long Tn_U2 (desconocido/unknown)
long Tn_Parent (índice al triángulo "padre", -1 si no tiene/index to the "parent" triangle, -1 if it hasn't)
long Tn_U3 (desconocido/unknown)
long Tn_U4 (desconocido/unknown)
long Tn_U5 (desconocido/unknown)
long Tn_U6 (desconocido/unknown)
... etc.
Sub-bloque de puntos/Points sub-block:
num_points bloques de 16 bytes c.u., como sigue:/num_points blocks of 16 bytes each, as follows:
single Pn_CoordX (coordenada X punto #n/point #n X coordinate)
single Pn_CoordY (coordenada Y punto #n/point #n Y coordinate)
single Pn_CoordZ (coordenada Z punto #n/point #n Z coordinate)
long Pn_bone (hueso al que va unido el punto #n/bone to which point #n is attached)
... etc.
Sub-bloque de huesos/Bones sub-block:
num_comp bloques de 48 bytes c.u., como sigue:/num_comp blocks of 48 bytes each, as follows:
byte bone1_name[32] (nombre hueso #1/bone #1 name)
single bone1_X (coordenada X del hueso #1/bone #1 X coordinate)
single bone1_Y (coordenada Y del hueso #1/bone #1 Y coordinate)
single bone1_Z (coordenada Z del hueso #1/bone #1 Z coordinate)
short bone1_parent (índice al hueso "padre", -1 si no tiene/index to the "parent" bone, -1 if it hasn't)
short bone1_unknown (desconocido, usualmente 0/unknown, usually 0)
byte bone2_name[32] (nombre hueso #2/bone #2 name)
single bone2_X (coordenada X del hueso #2/bone #2 X coordinate)
single bone2_Y (coordenada Y del hueso #2/bone #2 Y coordinate)
single bone2_Z (coordenada Z del hueso #2/bone #2 Z coordinate)
short bone2_parent (índice al hueso "padre", -1 si no tiene/index to the "parent" bone, -1 if it hasn't)
short bone2_unknown (desconocido, usualmente 0/unknown, usually 0)
... etc.
Sub-bloque de textura/Texture sub-block:
byte texture[long_tex] (datos de textura, codificados a 16 bits estilo TGA, siempre 256 pixels de ancho/texture data, 16-bit TGA-style encoding, always 256 pixels wide)
repetidos para tantos objetos como se indica.
repeated for as many objects as indicated.

Bloque de cielo/Sky block:

word sky_bmp[256,256] (mapa de bits del cielo/sky bitmap)
byte clouds_bmp[128,128] (mapa de sombras de nubes, escala de grises de 8 bits/clouds shadowmap, 8-bit greyscale)

Bloque de niebla/Fog block:

long num_fogs (número de nieblas/number of fogs)
byte fog1_RGBA[4] (color niebla #1/fog #1 color)
single fog1_alt (altitud niebla #1/fog #1 altitude)
long fog1_poison (0 = inofensiva/harmless, 1 = venenosa/poisonous)
single fog1_dist (distancia mínima niebla #1/fog #1 minimum distance)
single fog1_dens (densidad niebla #1/fog #1 density)
byte fog2_RGBA[4] (color niebla #2/fog #2 color)
single fog2_alt (altitud niebla #2/fog #2 altitude)
long fog2_poison (0 = inofensiva/harmless, 1 = venenosa/poisonous)
single fog2_dist (distancia mínima niebla #2/fog #2 minimum distance)
single fog2_dens (densidad niebla #2/fog #2 density)
... etc.

Bloque de sonidos/Sounds block:

long num_random_sounds (número de sonidos aleatorios/number of random sounds)
long length_random1 (longitud sonido aleatorio #1/random sound #1 length)
byte random1_data[length_random1] (datos sonido aleatorio #1/random sound #1 data)
long length_random2 (longitud sonido aleatorio #2/random sound #2 length)
byte random2_data[length_random2] (datos sonido aleatorio #2/random sound #2 data)
... etc.

long num_ambient_sounds (número de sonidos ambientales/number of ambient sounds)
long length_ambient1 (longitud sonido ambiental #1/ambient sound #1 length)
byte ambient1 data[length_ambient1] (datos sonido ambiental #1/ambient sound #1 data)
long length_ambient2 (longitud sonido ambiental #2/ambient sound #2 length)
byte ambient2_data[length_ambient2] (datos sonido ambiental #2/ambient sound #2 data)
... etc.

long u_random1_index (índice del sonido aleatorio usado #1/index of used random sound #1)
long u_random1_unknown1 (desconocido/unknown)
long u_random1_unknown2 (desconocido/unknown)
long u_random1_unknown3 (desconocido/unknown)
...
long u_random16_index (índice del sonido aleatorio usado #16/index of used random sound #16)
long u_random16_unknown1 (desconocido/unknown)
long u_random16_unknown2 (desconocido/unknown)
long u_random16_unknown3 (desconocido/unknown)
long num_u_random_sounds (número de sonidos usados en la tabla/number of used sounds in the table)
long u_random_sounds_unknown (desconocido/unknown)
Para Carnivores 2 y Ice Age:
For Carnivores 2 and Ice Age:

Bloque de cabecera/Header block:

long num_textures (número de texturas/number of textures)
long num_objects (número de objetos/number of objects)
long dawn_atm_light_R (iluminación atmosférica alba, componente rojo/dawn atmospheric lighting, red component)
long dawn_atm_light_G (iluminación atmosférica alba, componente verde/dawn atmospheric lighting, green component)
long dawn_atm_light_B (iluminación atmosférica alba, componente azul/dawn atmospheric lighting, blue component)
long day_atm_light_R (iluminación atmosférica día, componente rojo/day atmospheric lighting, red component)
long day_atm_light_G (iluminación atmosférica día, componente verde/day atmospheric lighting, green component)
long day_atm_light_B (iluminación atmosférica día, componente azul/day atmospheric lighting, blue component)
long night_atm_light_R (iluminación atmosférica noche, componente rojo/night atmospheric lighting, red component)
long night_atm_light_G (iluminación atmosférica noche, componente verde/night atmospheric lighting, green component)
long night_atm_light_B (iluminación atmosférica noche, componente azul/night atmospheric lighting, blue component)
long unknown_dawn_R (desconocido/unknown)
long unknown_dawn_G (desconocido/unknown)
long unknown_dawn_B (desconocido/unknown)
long unknown_day_R (desconocido/unknown)
long unknown_day_G (desconocido/unknown)
long unknown_day_B (desconocido/unknown)
long unknown_night_R (desconocido/unknown)
long unknown_night_G (desconocido/unknown)
long unknown_night_B (desconocido/unknown)

Bloque de texturas/Textures block:

word texture1[128,128] (mapa de bits de textura #1/texture #1 bitmap)
word texture2[128,128] (mapa de bits de textura #2/texture #2 bitmap)
... etc.

Bloque de objetos/Objects block:
Tantos segmentos de objetos individuales como indica la cabecera, cada uno dividido en sub-bloques como sigue:
As many individual object chunks as indicated in the header, each one divided in sub-blocks as follows:

Sub-bloque de cabecera/Header sub-block:
long Ob1 (desconocido/unknown)
long Ob2 (desconocido/unknown)
long Ob3 (desconocido/unknown)
long Ob4 (desconocido/unknown)
long Ob5 (desconocido/unknown)
long Ob6 (desconocido/unknown)
long Ob7 (desconocido/unknown)
long Ob8 (desconocido/unknown)
long Ob9 (desconocido/unknown)
long Ob10 (desconocido/unknown)
long Ob11 (desconocido/unknown)
long Ob12 (desconocido/unknown)
long Ob13 (desconocido/unknown)
long Ob14 (desconocido/unknown)
long Ob15 (desconocido/unknown)
long Ob16 (desconocido/unknown)
long num_points (número de puntos/number of points)
long num_triang (número de triángulos/number of triangles)
long num_bones (número de huesos/number of bones)
long long_tex (longitud del bloque de textura/length of texture block)
Sub-bloque de triángulos/Triangles sub-block:
num_triang bloques de 64 bytes cada uno, como sigue:/num_triang blocks of 64 bytes each, as follows:
long Tn_Point1 (punto 1 triángulo #n/triangle #n point 1)
long Tn_Point2 (punto 2 triángulo #n/triangle #n point 2)
long Tn_Point3 (punto 3 triángulo #n/triangle #n point 3)
long Tn_CoordX1 (coordenada X punto 1 textura triángulo #n/triangle #n texture point 1 X coordinate)
long Tn_CoordX2 (coordenada X punto 2 textura triángulo #n/triangle #n texture point 2 X coordinate)
long Tn_CoordX3 (coordenada X punto 3 textura triángulo #n/triangle #n texture point 3 X coordinate)
long Tn_CoordY1 (coordenada Y punto 1 textura triángulo #n/triangle #n texture point 1 Y coordinate)
long Tn_CoordY2 (coordenada Y punto 2 textura triángulo #n/triangle #n texture point 2 Y coordinate)
long Tn_CoordY3 (coordenada Y punto 3 textura triángulo #n/triangle #n texture point 3 Y coordinate)
long Tn_U1 (desconocido/unknown)
long Tn_U2 (desconocido/unknown)
long Tn_Parent (índice al triángulo "padre", -1 si no tiene/index to the "parent" triangle, -1 if it hasn't)
long Tn_U3 (desconocido/unknown)
long Tn_U4 (desconocido/unknown)
long Tn_U5 (desconocido/unknown)
long Tn_U6 (desconocido/unknown)
... etc.
Sub-bloque de puntos/Points sub-block:
num_points bloques de 16 bytes c.u., como sigue:/num_points blocks of 16 bytes each, as follows:
single Pn_CoordX (coordenada X punto #n/point #n X coordinate)
single Pn_CoordY (coordenada Y punto #n/point #n Y coordinate)
single Pn_CoordZ (coordenada Z punto #n/point #n Z coordinate)
long Pn_bone (hueso al que va unido el punto #n/bone to which point #n is attached)
... etc.
Sub-bloque de huesos/Bones sub-block:
num_comp bloques de 48 bytes c.u., como sigue:/num_comp blocks of 48 bytes each, as follows:
byte bone1_name[32] (nombre hueso #1/bone #1 name)
single bone1_X (coordenada X del hueso #1/bone #1 X coordinate)
single bone1_Y (coordenada Y del hueso #1/bone #1 Y coordinate)
single bone1_Z (coordenada Z del hueso #1/bone #1 Z coordinate)
short bone1_parent (índice al hueso "padre", -1 si no tiene/index to the "parent" bone, -1 if it hasn't)
short bone1_unknown (desconocido, usualmente 0/unknown, usually 0)
byte bone2_name[32] (nombre hueso #2/bone #2 name)
single bone2_X (coordenada X del hueso #2/bone #2 X coordinate)
single bone2_Y (coordenada Y del hueso #2/bone #2 Y coordinate)
single bone2_Z (coordenada Z del hueso #2/bone #2 Z coordinate)
short bone2_parent (índice al hueso "padre", -1 si no tiene/index to the "parent" bone, -1 if it hasn't)
short bone2_unknown (desconocido, usualmente 0/unknown, usually 0)
... etc.
Sub-bloque de textura/Texture sub-block:
byte texture[long_tex] (datos de textura, codificados a 16 bits estilo TGA, siempre 256 pixels de ancho/texture data, 16-bit TGA-style encoding, always 256 pixels wide)
Sub-bloque de sprite/Sprite sub-block:
word sprite_bmp[128,128] (mapa de bits de sprite, codificado a 16 bits estilo TGA, siempre 128x128 pixels/sprite bitmap, 16-bit TGA-style encoding, always 128x128 pixels)
repetidos para tantos objetos como se indica.
repeated for as many objects as indicated.

Bloque de cielo/Sky block:

word dawn_sky_bmp[256,256] (mapa de bits del cielo al alba/dawn sky bitmap)
word day_sky_bmp[256,256] (mapa de bits del cielo de día/day sky bitmap)
word night_sky_bmp[256,256] (mapa de bits del cielo de noche/night sky bitmap)
byte clouds_bmp[128,128] (mapa de sombras de nubes, escala de grises de 8 bits/clouds shadowmap, 8-bit greyscale)

Bloque de niebla/Fog block:

long num_fogs (número de nieblas/number of fogs)
byte fog1_RGBA[4] (color niebla #1/fog #1 color)
single fog1_alt (altitud niebla #1/fog #1 altitude)
long fog1_poison (0 = inofensiva/harmless, 1 = venenosa/poisonous)
single fog1_dist (distancia mínima niebla #1/fog #1 minimum distance)
single fog1_dens (densidad niebla #1/fog #1 density)
byte fog2_RGBA[4] (color niebla #2/fog #2 color)
single fog2_alt (altitud niebla #2/fog #2 altitude)
long fog2_poison (0 = inofensiva/harmless, 1 = venenosa/poisonous)
single fog2_dist (distancia mínima niebla #2/fog #2 minimum distance)
single fog2_dens (densidad niebla #2/fog #2 density)
... etc.

Bloque de sonidos/Sounds block:

long num_random_sounds (número de sonidos aleatorios/number of random sounds)
long length_random1 (longitud sonido aleatorio #1/random sound #1 length)
byte random1_data[length_random1] (datos sonido aleatorio #1/random sound #1 data)
long length_random2 (longitud sonido aleatorio #2/random sound #2 length)
byte random2_data[length_random2] (datos sonido aleatorio #2/random sound #2 data)
... etc.

long num_ambient_sounds (número de sonidos ambientales/number of ambient sounds)
long length_ambient1 (longitud sonido ambiental #1/ambient sound #1 length)
byte ambient1 data[length_ambient1] (datos sonido ambiental #1/ambient sound #1 data)
long length_ambient2 (longitud sonido ambiental #2/ambient sound #2 length)
byte ambient2_data[length_ambient2] (datos sonido ambiental #2/ambient sound #2 data)
... etc.

long u_random1_index (índice del sonido aleatorio usado #1/index of used random sound #1)
long u_random1_unknown1 (desconocido/unknown)
long u_random1_unknown2 (desconocido/unknown)
long u_random1_unknown3 (desconocido/unknown)
...
long u_random16_index (índice del sonido aleatorio usado #16/index of used random sound #16)
long u_random16_unknown1 (desconocido/unknown)
long u_random16_unknown2 (desconocido/unknown)
long u_random16_unknown3 (desconocido/unknown)
long num_u_random_sounds (número de sonidos usados en la tabla/number of used sounds in the table)
long u_random_sounds_unknown (desconocido/unknown)

Bloque de agua/Water block:

long num_water (número de cuerpos de agua/number of bodies of water)
long water1_texture (textura de la superficie agua #1/water #1 surface texture)
long water1_lvl (nivel agua #1/water #1 level)
single water1_opac (opacidad agua #1/water #1 opacity)
long water1_unknown
long water2_texture (textura de la superficie agua #2/water #2 surface texture)
long water2_lvl (nivel agua #2/water #2 level)
single water2_opac (opacidad agua #2/water #2 opacity)
long water2_unknown
... etc.