Код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void error(const char *message)
{
fprintf(stderr, "%s\n", message);
exit(-1);
}
int r_int(FILE *f)
{
int i;
fread(&i, sizeof(i), 1, f);
return i;
}
float r_float(FILE *f)
{
float fl;
fread(&fl, sizeof(fl), 1, f);
return fl;
}
short r_word(FILE *f)
{
short s;
fread(&s, sizeof(s), 1, f);
return s;
}
char r_byte(FILE *f)
{
char b;
fread(&b, sizeof(b), 1, f);
return b;
}
int r_chunk(FILE *f, int id)
{
if(r_int(f) == id)
return r_int(f); // size
else
{
fprintf(stderr, "%d ", id);
error("can't open chunk");
return 0;
}
}
int dictlen;
char *dictionary;
char *dictword(int n)
{
char *ptr;
if(n >= dictlen) error("word index out of range");
ptr = dictionary;
while(n--)
ptr = strchr(ptr, '\0')+1;
return ptr;
}
int main(int argc, char *argv[])
{
int magic, datapos, datasize, dictsize;
FILE *f;
int temp, start;
int entsize, entcount;
int counter;
int classcrc;
f = fopen("level.bin", "rb");
if(!f) error("can't open file!");
magic = r_int(f);
if(magic != 0x6C76656C) error("this is not level.bin file!");
r_byte(f); // skip flags
// remember data pos because we need load dictionary before parsing
datasize = r_chunk(f, 1);
datapos = ftell(f);
fseek(f, datasize, SEEK_CUR);
// load dictionary
dictsize = r_chunk(f, 2);
dictlen = r_int(f);
dictionary = malloc(dictsize-4);
fread(dictionary, dictsize-4, 1, f);
// parse data
fseek(f, datapos, SEEK_SET);
r_chunk(f, 0xD44B11A9); // unknown section containing all others
temp = r_chunk(f, 0xE48E50F6); // "startup" section
fseek(f, temp, SEEK_CUR); // skip it
temp = r_chunk(f, 0x922908F0); // unknown section
fseek(f, temp, SEEK_CUR); // also skip
entsize = r_chunk(f, 0x50EC64E5); // "entities" section
start = ftell(f);
entcount = r_int(f);
counter = 0;
while(ftell(f) < start+entsize)
{
temp = r_chunk(f, 0);
classcrc = r_int(f);
if(classcrc == 0x2301C4EF) // STATICPROP
{
printf("entity_%d = begin\n", counter++);
r_int(f); // skip static data key
printf("\tatt_bone_id : stringz = \"%s\"\n", dictword(r_int(f)));
printf("\tid : u16 = %hu\n", r_word(f));
printf("\tparent_id : u16 = %hu\n", r_word(f));
printf("\tatt_offset : 'pose, matrix_43T' = [\n");
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t]\n");
printf("\tatt_root : bool = %s\n", r_byte(f) ? "True" : "False");
printf("\tname : stringz = \"%s\"\n", dictword(r_int(f)));
r_int(f); // unknown 1
r_word(f); // unknown 2
printf("\txform : 'pose, matrix_43T' = [\n");
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t\t%f, %f, %f,\n", r_float(f), r_float(f), r_float(f));
printf("\t]\n");
printf("\tvisual : stringz = \"%s\"\n", dictword(r_int(f)));
printf("end;\n\n");
fseek(f, temp-127, SEEK_CUR); // skip rest of section
}
else
fseek(f, temp-4, SEEK_CUR); // not STATICPROP, skip
}
free(dictionary);
fclose(f);
return 0;
}