Голосование

Как вы относитесь к играм в жанре "симулятор колонии"?












Оформление



Пользователей
  • Всего: 29197
  • Последний: WebMotive
Сейчас на форуме
Пользователи: 1
Гостей: 634
Всего: 635

0 Пользователей и 1 Гость просматривают эту тему.

Тема: [Other].SCO File Parser  (Прочитано 4669 раз)

  • Сообщений: 2766
  • За создание крупных модов и других особо сложных проектов За регистрацию на форуме не позже декабря 2016 года и не менее 2500 постов Выдается модераторам, достигнувшим значимых успехов на своем посту
    • Просмотр профиля
0
« : 26 Марта, 2013, 12:34 »
Автор: cmpxchg8b
Оригинал: http://mbmodwiki.ollclan.eu/SceneObj

Это сам парсер, он написан на стандартном C (но я не знаю зачем он вообще нужен):
#include <stdio.h>
#include <stdlib.h>
 
#define SCO_MAGIC -717
#define GROUND_PAINT_MAGIC -11873882
#define GROUND_PAINT_ELEVATION_MAGIC -7793
#define GROUND_PAINT_COLOR_MAGIC -12565
 
typedef struct vector
{
float x;
float y;
float z;
} vector_t;
 
typedef struct matrix
{
vector_t v0;
vector_t v1;
vector_t v2;
vector_t o;
} matrix_t;
 
typedef struct ground_paint_layer
{
char *ground_spec_id;
int ground_spec_no;
float *cells;
} ground_paint_layer_t;
 
typedef struct ground_paint
{
int size_x;
int size_y;
int num_layers;
ground_paint_layer_t *layers;
} ground_paint_t;
 
typedef struct ai_mesh_vertex
{
vector_t position;
} ai_mesh_vertex_t;
 
typedef struct ai_mesh_edge
{
int start_vertex;
int end_vertex;
} ai_mesh_edge_t;
 
typedef struct ai_mesh_face
{
int num_vertices;
int vertices[4];
int edges[4];
int unknown;
} ai_mesh_face_t;
 
typedef struct ai_mesh
{
int num_vertices;
int num_edges;
int num_faces;
ai_mesh_vertex_t *vertices;
ai_mesh_edge_t *edges;
ai_mesh_face_t *faces;
} ai_mesh_t;
 
typedef struct mission_object
{
char *id;
int meta_type; // 0 = scene prop, 1 = entry point, 2 = scene item, 4 = flora, 5 = passage
int sub_kind_no;
int variation_id;
int variation_id_2;
matrix_t position;
vector_t scale;
} mission_object_t;
 
typedef struct sco_file
{
int version;
int num_mission_objects;
mission_object_t *mission_objects;
ai_mesh_t *ai_mesh;
ground_paint_t *ground_paint;
} sco_file_t;
 
void read(FILE *file, size_t size, void *dest)
{
if (dest)
fread(dest, size, 1, file);
}
 
void read_int(FILE *file, int *dest)
{
read(file, 4, dest);
}
 
void read_char(FILE *file, char *dest)
{
read(file, 1, dest);
}
 
void read_float(FILE *file, float *dest)
{
read(file, 4, dest);
}
 
void read_string(FILE *file, char **dest)
{
int length;
 
read_int(file, &length);
*dest = malloc(length + 1);
read(file, length, *dest);
(*dest)[length] = '\0';
}
 
void read_vector(FILE *file, vector_t *dest)
{
read_float(file, &dest->x);
read_float(file, &dest->y);
read_float(file, &dest->z);
}
 
void read_matrix(FILE *file, matrix_t *dest)
{
read_vector(file, &dest->v0);
read_vector(file, &dest->v1);
read_vector(file, &dest->v2);
read_vector(file, &dest->o);
}
 
int main(int argc, char **argv)
{
if (argc < 2)
{
printf("Usage: %s filename\n", argv[0]);
return EXIT_FAILURE;
}
 
FILE *file = fopen(argv[1], "rb");
 
if (!file)
{
printf("ERROR: file %s not found\n", argv[1]);
return EXIT_FAILURE;
}
 
fseek(file, 0, SEEK_END);
 
long file_size = ftell(file);
 
fseek(file, 0, SEEK_SET);
 
printf("Reading %s\n", argv[1]);
 
sco_file_t sco_file;
int magic;
 
read_int(file, &magic);
 
if (magic == SCO_MAGIC)
{
read_int(file, &sco_file.version);
read_int(file, &sco_file.num_mission_objects);
}
else
{
sco_file.version = 0;
sco_file.num_mission_objects = magic;
}
 
printf("SCO file version: %d\n", sco_file.version);
printf("Mission object count: %d\n", sco_file.num_mission_objects);
 
sco_file.mission_objects = malloc(sco_file.num_mission_objects * sizeof(mission_object_t));
 
for (int i = 0; i < sco_file.num_mission_objects; ++i)
{
read_int(file, &sco_file.mission_objects[i].meta_type);
read_int(file, &sco_file.mission_objects[i].sub_kind_no);
fseek(file, 4, SEEK_CUR); // unused
read_matrix(file, &sco_file.mission_objects[i].position);
read_string(file, &sco_file.mission_objects[i].id);
read_int(file, &sco_file.mission_objects[i].variation_id);
 
if (sco_file.version >= 2)
read_int(file, &sco_file.mission_objects[i].variation_id_2);
else
sco_file.mission_objects[i].variation_id_2 = 0;
 
if (sco_file.version >= 3)
read_vector(file, &sco_file.mission_objects[i].scale);
else
{
sco_file.mission_objects[i].scale.x = 1.0f;
sco_file.mission_objects[i].scale.y = 1.0f;
sco_file.mission_objects[i].scale.z = 1.0f;
}
}
 
if (sco_file.version >= 4)
{
int ai_mesh_size;
 
read_int(file, &ai_mesh_size);
 
long start_pos = ftell(file);
 
sco_file.ai_mesh = malloc(sizeof(ai_mesh_t));
 
read_int(file, &sco_file.ai_mesh->num_vertices);
sco_file.ai_mesh->vertices = malloc(sco_file.ai_mesh->num_vertices * sizeof(ai_mesh_vertex_t));
 
printf("AI mesh vertex count: %d\n", sco_file.ai_mesh->num_vertices);
 
for (int i = 0; i < sco_file.ai_mesh->num_vertices; ++i)
{
read_vector(file, &sco_file.ai_mesh->vertices[i].position);
}
 
read_int(file, &sco_file.ai_mesh->num_edges);
sco_file.ai_mesh->edges = malloc(sco_file.ai_mesh->num_edges * sizeof(ai_mesh_edge_t));
 
printf("AI mesh edge count: %d\n", sco_file.ai_mesh->num_edges);
 
for (int i = 0; i < sco_file.ai_mesh->num_edges; ++i)
{
fseek(file, 4, SEEK_CUR); // unused
read_int(file, &sco_file.ai_mesh->edges[i].start_vertex);
read_int(file, &sco_file.ai_mesh->edges[i].end_vertex);
fseek(file, 8, SEEK_CUR); // unused
}
 
read_int(file, &sco_file.ai_mesh->num_faces);
sco_file.ai_mesh->faces = malloc(sco_file.ai_mesh->num_faces * sizeof(ai_mesh_face_t));
 
printf("AI mesh face count: %d\n", sco_file.ai_mesh->num_faces);
 
for (int i = 0; i < sco_file.ai_mesh->num_faces; ++i)
{
read_int(file, &sco_file.ai_mesh->faces[i].num_vertices);
 
for (int j = 0; j < sco_file.ai_mesh->faces[i].num_vertices; ++j)
{
read_int(file, &sco_file.ai_mesh->faces[i].vertices[j]);
}
 
for (int j = 0; j < sco_file.ai_mesh->faces[i].num_vertices; ++j)
{
read_int(file, &sco_file.ai_mesh->faces[i].edges[j]);
}
 
read_int(file, &sco_file.ai_mesh->faces[i].unknown);
 
if (sco_file.ai_mesh->faces[i].unknown > 0)
read_int(file, &sco_file.ai_mesh->faces[i].unknown);
else
sco_file.ai_mesh->faces[i].unknown = 0;
}
 
long end_pos = ftell(file);
 
if (end_pos - start_pos != ai_mesh_size)
{
printf("ERROR: failed to read AI mesh\n");
fclose(file);
return EXIT_FAILURE;
}
}
else
sco_file.ai_mesh = NULL;
 
if (ftell(file) != file_size)
{
read_int(file, &magic);
 
if (magic != GROUND_PAINT_MAGIC)
{
printf("ERROR: wrong ground paint magic\n");
fclose(file);
return EXIT_FAILURE;
}
 
int ground_paint_size;
 
read_int(file, &ground_paint_size);
 
long start_pos = ftell(file);
 
sco_file.ground_paint = malloc(sizeof(ground_paint_t));
 
read_int(file, &sco_file.ground_paint->num_layers);
sco_file.ground_paint->layers = malloc(sco_file.ground_paint->num_layers * sizeof(ground_paint_layer_t));
 
printf("Ground paint layer count: %d\n", sco_file.ground_paint->num_layers);
 
read_int(file, &sco_file.ground_paint->size_x);
read_int(file, &sco_file.ground_paint->size_y);
 
for (int i = 0; i < sco_file.ground_paint->num_layers; ++i)
{
read_int(file, &sco_file.ground_paint->layers[i].ground_spec_no);
read_string(file, &sco_file.ground_paint->layers[i].ground_spec_id);
 
int has_cells;
 
read_int(file, &has_cells);
 
if (has_cells)
{
sco_file.ground_paint->layers[i].cells = malloc(sco_file.ground_paint->size_x * sco_file.ground_paint->size_y * sizeof(float));
 
int empty = 1;
int count;
 
read_int(file, &count);
 
for (int y = 0; y < sco_file.ground_paint->size_y; ++y)
{
for (int x = 0; x < sco_file.ground_paint->size_x; ++x)
{
if (!count)
{
empty = !empty;
read_int(file, &count);
}
 
count--;
 
float value;
 
if (empty)
{
if (sco_file.ground_paint->layers[i].ground_spec_no == GROUND_PAINT_COLOR_MAGIC)
value = -1.0f;
else
value = 0.0f;
}
else
{
if (sco_file.ground_paint->layers[i].ground_spec_no < 0)
read_float(file, &value);
else
{
char cvalue;
 
read_char(file, &cvalue);
value = cvalue / 255.0f;
}
}
 
sco_file.ground_paint->layers[i].cells[x * sco_file.ground_paint->size_y + y] = value;
}
}
}
else
sco_file.ground_paint->layers[i].cells = NULL;
}
 
long end_pos = ftell(file);
 
if (end_pos - start_pos != ground_paint_size)
{
printf("ERROR: failed to read ground paint\n");
fclose(file);
return EXIT_FAILURE;
}
}
else
sco_file.ground_paint = NULL;
 
fclose(file);
return EXIT_SUCCESS;
}

1 + 2 + 3 + 4 + ... = ζ(-1) = -0.08(3)
1 - 1 + 1 - 1 + 1 - ... = 0.5
1 - 2 + 3 - 4 + 5 - ... = 0.25

На вопросы в ПС не отвечаю! Спрашивать в темах!

СиЧЪ Total War СиЧЪ Total War
Сайт "Всадники Кальрадии" не является СМИ. Администрация не несет ответственность за высказывания и публикацию каких-либо материалов, сделанные любыми пользователями форума, в том числе посредством личных и публичных сообщений. Материалы, размещенные на ресурсе третьими лицами, могут содержать информацию, не предназначенную для лиц, не достигнувших совершеннолетия. При обнаружении на ресурсе материалов, нарушающих законодательство Российской Федерации, необходимо обращаться к администрации.
Сайт работает на быстром VPS/VDS хостинге от FASTVPS


Powered by SMF 2.0 | SMF © Simple Machines LLC