La saga de Carnivores - Los archivos .car

The Carnivores saga - The .car files

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

Estos archivos se encuentran en el subdirectorio HUNTDAT tanto en Carnivores como en Carnivores 2 y Ice Age. Los archivos consisten en varios bloques, empezando por un bloque de cabecera que tiene 52 bytes de largo.
These files are located in the HUNTDAT subfolder both in Carnivores and in Carnivores 2 and Ice Age. The files consist of several blocks, starting with a header block which is 52 bytes long.

El formato completo de los bloques de triángulos y puntos aún necesita determinarse. 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 full format of the triangles and points blocks needs still to be determined. 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:

Bloque de cabecera/Header block:
(offset: 0000 0000 hex, 0 decimal)

byte name[24] (nombre/name)
byte extra[8] (usualmente "msc: #", donde "#" es un número/usually "msc: #", where "#" is a number)
long num_anims (número de animaciones/number of animations)
long num_sounds (número de sonidos/number of sounds)
long num_points (número de vértices/number of vertices)
long num_triang (número de triángulos/number of triangles)
long bytes_tex (longitud de la textura en bytes/texture length in bytes)

Bloque de triángulos/Triangles block:
(offset: 0000 0034 hex, 52 decimal)

num_triang bloques de 64 bytes cada uno, como sigue:/num_triang blocks of 64 bytes each, as follows:
long Tr1_Point1 (punto 1 triángulo #1/triangle #1 point 1)
long Tr1_Point2 (punto 2 triángulo #1/triangle #1 point 2)
long Tr1_Point3 (punto 3 triángulo #1/triangle #1 point 3)
long Tr1_CoordX1 (coordenada X punto 1 textura triángulo #1/triangle #1 texture point 1 X coordinate)
long Tr1_CoordX2 (coordenada X punto 2 textura triángulo #1/triangle #1 texture point 2 X coordinate)
long Tr1_CoordX3 (coordenada X punto 3 textura triángulo #1/triangle #1 texture point 3 X coordinate)
long Tr1_CoordY1 (coordenada Y punto 1 textura triángulo #1/triangle #1 texture point 1 Y coordinate)
long Tr1_CoordY2 (coordenada Y punto 2 textura triángulo #1/triangle #1 texture point 2 Y coordinate)
long Tr1_CoordY3 (coordenada Y punto 3 textura triángulo #1/triangle #1 texture point 3 Y coordinate)
long Tr1_U1 (desconocido/unknown)
long Tr1_U2 (desconocido/unknown)
long Tr1_Parent (índice al triángulo "padre", -1 si no tiene/index to the "parent" triangle, -1 if it hasn't)
long Tr1_U3 (desconocido/unknown)
long Tr1_U4 (desconocido/unknown)
long Tr1_U5 (desconocido/unknown)
long Tr1_U6 (desconocido/unknown)
... etc.

Bloque de puntos/Points block:
(offset: 0000 0034 +0040*num_triang hex, 52 +64*num_triang decimal)

num_points bloques de 16 bytes cada uno, como sigue:/num_points blocks of 16 bytes each, as follows:
single P1_CoordX (coordenada X punto #1/point #1 X coordinate)
single P1_CoordY (coordenada Y punto #1/point #1 Y coordinate)
single P1_CoordZ (coordenada Z punto #1/point #1 Z coordinate)
long P1_bone (hueso al que va unido el punto #1/bone to which point #1 is attached)
single P2_CoordX (coordenada X punto #2/point #2 X coordinate)
single P2_CoordY (coordenada Y punto #2/point #2 Y coordinate)
single P2_CoordZ (coordenada Z punto #2/point #2 Z coordinate)
long P2_bone (hueso al que va unido el punto #2/bone to which point #2 is attached)
... etc.

Bloque de textura/Texture block:
(offset: 0000 0034 +0040*num_triang +0010*num_points hex, 52 +64*num_triang +16*num_points decimal)

byte texture[bytes_tex] (codificación de estilo TGA a 16 bits, siempre 256 pixels de ancho/16-bit TGA-style encoding, always 256 pixels wide)

Bloque de animaciones/Animations block:
(offset: 0000 0034 +0040*num_triang +0010*num_points +bytes_tex hex, 52 +64*num_triang +16*num_points +bytes_tex decimal)

num_anims bloques de tamaño variable, como sigue:/num_anims blocks of variable size, as follows:
byte anim1_name[32] (nombre animación #1/animation #1 name)
long anim1_div (divisor animación #1/animation #1 divisor)
long anim1_num_frames (número de cuadros animación #1/animation #1 number of frames)
short anim1_Frame1_P1_CoordX (coordenada X punto #1 cuadro#1 animación #1/animation #1 frame #1 point #1 X coordinate)
short anim1_Frame1_P1_CoordY (coordenada Y punto #1 cuadro#1 animación #1/animation #1 frame #1 point #1 Y coordinate)
short anim1_Frame1_P1_CoordZ (coordenada Z punto #1 cuadro#1 animación #1/animation #1 frame #1 point #1 Z coordinate)
...
short anim1_Frame1_Pn_CoordX (coordenada X punto #n cuadro#1 animación #1/animation #1 frame #1 point #n X coordinate)
short anim1_Frame1_Pn_CoordY (coordenada Y punto #n cuadro#1 animación #1/animation #1 frame #1 point #n Y coordinate)
short anim1_Frame1_Pn_CoordZ (coordenada Z punto #n cuadro#1 animación #1/animation #1 frame #1 point #n Z coordinate)
short anim1_Frame2_P1_CoordX (coordenada X punto #1 cuadro#2 animación #1/animation #1 frame #2 point #1 X coordinate)
short anim1_Frame2_P1_CoordY (coordenada Y punto #1 cuadro#2 animación #1/animation #1 frame #2 point #1 Y coordinate)
short anim1_Frame2_P1_CoordZ (coordenada Z punto #1 cuadro#2 animación #1/animation #1 frame #2 point #1 Z coordinate)
...
short anim1_FrameN_Pn_CoordX (coordenada X punto #n cuadro#N animación #1/animation #1 frame #N point #n X coordinate)
short anim1_FrameN_Pn_CoordY (coordenada Y punto #n cuadro#N animación #1/animation #1 frame #N point #n Y coordinate)
short anim1_FrameN_Pn_CoordZ (coordenada Z punto #n cuadro#N animación #1/animation #1 frame #N point #n Z coordinate)
... etc.
Las coordenadas reales se obtienen dividiendo cada valor de 2 bytes entre el divisor.
The actual coordinates are obtained by dividing each 2-byte value by the divisor.

Bloque de sonidos/Sounds block:
(offset: 0000 0034 +0040*num_triang +0010*num_points +bytes_tex +0028*num_anims +0006*num_points*sum[animN_num_frames] hex, 52 +64*num_triang +16*num_points +bytes_tex +40*num_anims +6*num_points*sum[animN_num_frames] decimal)

num_sounds bloques de tamaño variable, como sigue:/num_sounds blocks of variable size, as follows:
byte sound1_name[32] (nombre sonido #1/sound #1 name)
long sound1_length (longitud sonido #1/sound #1 length)
byte sound1_data[sound1_length] (datos sonido #1/sound #1 data)
byte sound2_name[32] (nombre sonido #2/sound #2 name)
long sound2_length (longitud sonido #2/sound #2 length)
byte sound2_data[sound2_length] (datos sonido #2/sound #2 data)
... etc.

seguidos de una tabla de referencia cruzada:/followed by a cross-reference table:

long xref_table[64] (referencia cruzada para animaciones y sonidos/cross-reference for animations and sounds)
Sólo los primeros num_anims valores de la tabla se toman en cuenta, los demás se ignoran. El número indica qué sonido está asociado con una animación dada. Un valor de -1 significa que no hay un sonido. (Esto implica que sólo puede haber un máximo de 64 animaciones)
Only the first num_anims table values are taken into account, the rest are ignored. The number indicates which sound is associated with a given animation. A value of -1 means there is no sound. (This implies there can only be a maximum of 64 animations)