IMG архив
Материал из GTAModding.ru
Версия от 12:37, 17 января 2009; Dageron (обсуждение | вклад)
В IMG архивах GTA в основном хранятся игровые модели, текстуры, транспортные и пешеходные пути, анимации, а так же внешние скрипты. IMG архив имеет расширение .img. Эти архивы разделяются на версии и имеют схожий между собой формат (за исключением версии, используемой GTA IV).
Содержание |
Структура
Версия 1 - GTA III & VC
Архивы первой версии, используемые в GTA III и Vice City, разделены на два файла: директория содержимого архива (.dir) и сам архив, содержащий файлы (.img).
Директория содержит список файлов, их имена, смещение и размер. Значения смещения и размера файлов должны быть умножены на 2048. Файлы расположены в блоках по 2 КБ. Это означает, что даже если файл имеет размер менее 2-х КБ (например, 218 байт), то в архиве он будет занимать 2 КБ. Файлы (обычно) не имеют сортировку, не сжаты и располагаются "друг за другом" (никакой древовидной иерархии).
Чтобы найти общее количество элементов (файлов) в .img архиве, необходимо разделить размер .dir файла на 32.
Файл директории не имеет заголовка, просто массив элементов по 32 байта на каждый:
Элемент (повторяется n-раз, где n - общее количество элементов): 4 байта - DWORD - смещение файла (в блоках) в .img архиве, относительно его начала 4 байта - DWORD - размер файла (в блоках) в .img архиве 24 байта - CHAR[24] - имя файла
Сам .img архив не имеет заголовка, просто файлы, как говорилось ранее, расположенные в блоках по 2 КБ.
Версия 2 - GTA SA
Архивы второй версии, используемые в GTA San Andreas, содержат .dir и .img файлы в одном .img файле. Директория имеет такой же формат, как и в формате 1-ой версии, но располагается в начале .img файла. Файлы так же размещены в блоках по 2 КБ. Смещения файлов задаются от начала самого архива, а не от конца списка файлов.
Заголовок: 4 байта - CHAR[4] - сигнатура архива, всегда имеет значение "VER2" 4 байта - DWORD - общее количество элементов (файлов) Элемент: (повторяется n-раз, где n - общее количество элементов): 4 байта - DWORD - смещение файла (в блоках) в архиве 4 байта - DWORD - размер файла (в блоках) 24 байта - CHAR[24] - имя файла
Недостаток этого формата - это его расширяемость. Если вы добавите слишком много файлов, директория начнёт записываться поверх первых файлов в архиве, поэтому вам нужно будет записывать первые файлы в конец архива.
Пример программы на Delphi по работе с форматом
procedure TForm1.Button1Click(Sender: TObject); //Процедура открытия архива var Size, Offset, FileNum, A : Integer; Name : PChar; FileName : String; ListItem : TListItem; begin if OpenDialog1.Execute then begin CFileName.Text := OpenDialog1.FileName; Size := 0; Offset := 0; Name := PChar(AllocMem(24)); CFileList.Clear; FileName := OpenDialog1.FileName; Stream := TFileStream.Create(FileName, fmOpenRead); // Открываем архив для чтения Stream.Seek(4, 0); // Пропускаем первые 4 байта, так как они всегда равны "VER2" Stream.Read(FileNum, 4); // Считываем количество файлов for A := 0 to FileNum - 1 do // Цикл считывания всех файлов begin Stream.Read(Offset, 4); // Считываем смещение файла Stream.Read(Size, 4); // Считываем размер файла Stream.Read(Name^, 24); // Считываем имя файла ListItem := CFileList.Items.Add; // ListItem.Caption := Name; // Добавляем файл со всеми ListItem.SubItems.Add(IntToStr(Size * 2048)); // параметрами в список файлов ListItem.SubItems.Add(IntToStr(Offset * 2048)); // end; end; end;
procedure TForm1.Button2Click(Sender: TObject); //Процедура извлечения файлов var Size, Offset : Integer; DestFile : TFileStream; // Сюда будем загружать файл для сохранения begin if CFileList.SelCount > 0 then // Если что-либо выделено в списке файлов begin SaveDialog1.FileName := CFileList.Selected.Caption; if SaveDialog1.Execute then begin DestFile := TFileStream.Create(SaveDialog1.FileName, fmCreate); // Создаём файл DestFile.Seek(0, 0); // Смещаемся в начало файла. Size := StrToInt(CFileList.Selected.SubItems.Strings[0]);// Узнаём размер выделенного файла Offset := StrToInt(CFileList.Selected.SubItems.Strings[1]);// Узнаём смещение выделенного файла Stream.Seek(Offset, 0); // Смещаемся к смещению (то есть, к началу) файла в архиве DestFile.CopyFrom(Stream, Size); // Копируем количество байт, равным размеру файла в архиве DestFile.Free; // Закрываем файл end; end; end;
Версия 3 - GTA IV
Данная версия архива имеет более сложную структуру. Эта статья не завершена