EXTRACTOR | .RU – версия 2.2 |
||
Что у нас есть? Это тоже интересно |
Статьи и описания форматов игровых файлов Brave Dwarves 2Эта статья относится к играм: Автор материала: Varg Описание формата DAT из игры Brave Dwarves 2 (студия GameOverGame) и пример использования библиотеки Zlib для извлечения ресурсов. Файлы формата DAT имеют следующее строение: Заголовок. 0x00000000 строка длинной 28 байт содержащая "GaveOverGames' Resource File" 0x00000022 DWORD число указывает на первый запакованный файл 0x00000026 DWORD количество файлов в архиве На "С++" это выглядит следующим образом: struct Header { char Id[0x1d]; //Начальная строка как индефикатор DWORD start; //Начальная позиция DWORD num; //Число файлов }; Пример чтения заголовка: FILE *mfile; Header header; //Заголовок DAT файла .... BOOL ArcOpen(char *arc_name) { if(mfile!=0) fclose(mfile); mfile=fopen(arc_name,"rb"); if(mfile==0) { sprintf(str_error,"Error! Can`t open arc file!"); return FALSE; }; //****************************** // Читаем заголовок //****************************** fread(header.Id,0x1c,1,mfile); if(strcmp(header.Id,"GaveOverGames' Resource File")!=0) { sprintf(str_error,"Error! It`s not BD2 dat file!"); return FALSE; }; fseek(mfile,0x22,0); fread(&header.start,4,1,mfile); fread(&header.num,4,1,mfile); return TRUE; }; Запакованные файлы. offset+0 DWORD указатель на начало строки содержащей имя запакованного файла. offset+8 DWORD указатель на позицию следующего запакованного файла. offset+12 DWORD реальный размер запакованных данных. offset+16 DWORD размер запакованных данных. offset+22 строка содержащая имя запакованного файла. Далее после строки имени идут сами запакованные данные. struct Arc_File { DWORD start_pos; //Указатель на имя файла DWORD size; //Размер запакованных данных DWORD r_size; //Реальный размер данных DWORD data_pos; //Указатель на данные DWORD next; //Указатель на следующий файл char name[256]; //Имя запакованного файла }; Пример чтения информации из заголовков запакованных файлов: FILE *mfile; Header header; //Заголовок Arc_File *afile; //Заголовки запакованных файлов ... BOOL ArcScan() { afile=new Arc_File[header.num]; //Выделяем память под заголовки if(!afile) { printf(str_error,"Error! Can`t Alloc Memory!"); return FALSE; }; long off=0; fseek(mfile,header.start,0); //Устанавливаем указатель на начало (заголовок) запакованного файла. for(int i=0;i<header.num;i++) { fread(&afile[i].start_pos,4,1,mfile); //Читаем указатель на имя запакованного файла. fseek(mfile,off+8,0); //Устанавливаем позицию ф-ла в off+8 fread(&afile[i].next,4,1,mfile); //Читаем смещение по которому расположен следующий запакованный файл. fseek(mfile,off+12,0); //Устанавливаем позицию ф-ла в off+12 fread(&afile[i].r_size,4,1,mfile); //Читаем реальный размер упакованных данных. fseek(mfile,off+16,0); //Устанавливаем позицию ф-ла в off+16 fread(&afile[i].size,4,1,mfile); //Читаем размер упакованных данных. fseek(mfile,afile[i].start_pos,0); //Устанавливаем указатель на начало строки содержащей имя запакованного файла. fread(afile[i].name,afile[i].next-afile[i].start_pos-afile[i].size-1,1,mfile); //Читаем имя файла (обратить внимание на расчет длинны строки) afile[i].data_pos=off=ftell(mfile); //Читаем позицию файла которая численно равна позиции с которой начинаются данные запакованные zlib. fseek(mfile,afile[i].next,0); //Устанавливаем позицию на следующий запакованный файл. }; return TRUE; }; Собственно распаковка всех файлов: ... #include "direct.h" #include "zlib.h" ... #pragma comment (lib, "zlib.lib") //Подключаем zlib.dll ... FILE *mfile; Header header; Arc_File *afile; ... void ExtractAll() { FILE *o; //Указатель на файл вывода данных Bytef *cdata; //Упакованные данные Bytef *data; //Распакованные данные uLongf sz=0; //Реальный размер //********************************** //Главный цикл извлечения данных //********************************** for(int i=0;i<header.num;i++) { o=CreateFileName(i); //Создаем файл для вывода данных if(o!=0) { fseek(mfile,afile[i].data_pos,0); //Начало запакованных данных cdata=new Bytef[afile[i].size+1]; //Выделяем память под запакованные данные if(cdata) { data=new Bytef[afile[i].r_size]; //Выделяем память под незапакованные данные if(data) { sz=afile[i].r_size; //Реальный размер fread(cdata,afile[i].size+1,1,mfile); //Читаем запакованные данные из файла DAT //Распаковываем данные из cdata в data с размером r_size используя //функцию из библиотеки ZLib //где &sz реальный размер распакованного файла //afile[i].size+1 размер запакованных данных //если функция uncompress возвращает 0 (Z_OK) значит все рулеzzz //если же нет, то номера ошибок можно найти в zlib.h if(uncompress(data,&sz,cdata,afile[i].size+1)==0) { //Записываем данные data в файл// fwrite(data,afile[i].r_size,1,o); }; delete data; //new data }; delete cdata; //new cdata } fclose(o); //fopen } else { printf("Error"); } }; }; //************** CreateFileName()*****************// //************************************ // Функция создающая файл для вывода // распакованных данных //************************************ FILE * CreateFileName(int n) { FILE *out; char str[256]; char sstr[256]; BYTE ch=0; int len=0; strcpy(sstr,afile[n].name); len=strlen(sstr); for(int a=0;a<len;a++) { ch=sstr[a]; if(ch==0x5c) { str[a]=0; mkdir(str); }; str[a]=ch; }; out=fopen(afile[n].name,"wb"); return out; }; Вот и все что нужно знать, чтобы распаковать файлы с такой структурой. Причем навык пользования ZLib можно использовать и при написании программ к другим форматам использующим ZLib для компрессии. |
© | 2000—2010 «EXTRACTOR.ru» — игровые ресурсы: распаковка музыки и графики, конверторы форматов и многое другое… |