Outpost 2 Форматы файлов · bei.pm
Форматы файлов, описанные на этой странице, основаны на техническом анализе интеллектуальной собственности Dynamix, Inc. и Sierra Entertainment.
Интеллектуальная собственность сегодня является частью активов Activision Publishing, Inc. / Activision Blizzard, Inc. и в настоящее время находится в собственности Microsoft Corp..
Информация была собрана с помощью обратного проектирования и анализа данных с целью архивирования и обеспечения совместимости с историческими данными.
Не использовались никакие собственнические или конфиденциальные спецификации.
Игра в настоящее время доступна для покупки в виде загрузки на gog.com.
Следующая серия статей документирует мои выводы о форматах данных в реальном времени стратегии "Outpost 2: Divided Destiny", выпущенной в 1997 году компанией Sierra и разработанной Dynamix.
С 1 ноября 2015 года по 14 ноября 2015 года я в основном занимался анализом данных игры и тем, что с ними можно сделать.
Согласно информации, которую я смог собрать до сих пор, Dynamix - как многие коммерческие компании - не разрабатывала некоторые форматы данных специально для Outpost 2, а использовала их в других проектах, таких как серия Mechwarrior (с изменениями).
Кроме того, можно отметить, что инновационность форматов данных фактически ограничена и часто базируется на давно существующих концепциях из обычных форматов, таких как JFIF и RIFF.
Для интерпретации таблиц и форматов данных доступны дополнительные сведения по ссылке Что есть что?.
Указанные здесь данные в общем следует понимать как Little Endian.
В заключение можно сказать, что обратное проектирование было очень увлекательным, хотя и не завершенным.
Конечно, я также рекомендую поиграть в саму игру, так как она предлагает интересные игровые механики.
Введение
Форматы данных, используемые в Outpost 2, имеют структуру, напоминающую JFIF / PNG - каждый блок данных всегда имеет заголовок размером 8 байт. Поэтому я не буду документировать отдельные заголовки в соответствующих специфических местах, а буду фиксировать только отклонения.
Формат всегда следующий; фактические полезные данные встроены в него:
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | Содержит информацию о том, что ожидать в следующем блоке данных. Известные значения:
|
0x0004 | uint(24) | Длина блока | Содержит информацию о том, насколько велик (в байтах) следующий блок данных. При этом имеется в виду только полезные данные - 8 байт заголовка не включены. |
0x0007 | uint(8) | Флаги? | Неизвестно, для чего именно предназначен этот блок. В объемах это значение часто равно 0x80, в других файлах часто 0x00. Это указывает на то, что это может быть набор флагов. |
Томa
Объемы представляют собой контейнеры данных для игры, аналогичные архивным форматам, таким как Tarball. По крайней мере в Outpost 2 формат знает только файлы - папок нет. Вероятно, их можно смоделировать с помощью соответствующих имен файлов.
Объем состоит из заголовка объема и нескольких блоков объема, которые соответствуют конкретным файлам.
"Объемы" - это файлы с расширением 'vol'
в игровом каталоге.
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 4f | 4c | 20 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | O | L | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Заголовок объема
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 68 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | h | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Заголовок объема сам по себе не содержит никаких пользовательских данных.
Он служит лишь контейнером.
В качестве первой записи в заголовке объема должны находиться строки объема; за ними следуют данные о объеме.
Строки объема
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 73 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | s | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги | |
0x0008 | uint(32) | Длина полезной нагрузки | Указывает, сколько байтов из следующих данных действительно являются полезными данными. Остальные данные из списка строк тома, по-видимому, следует считать мусором. В файлах с более поздней датой эти 'остальные данные' равны 0x00, что может указывать на недостатки в инструментальной цепочке во время разработки игры, а именно, что разработчик занялся правильной инициализацией буферов только на очень позднем этапе, поскольку наличие или отсутствие инициализированных данных не влияет на игру. |
0x000c | uint(8)[] | Список имен файлов | Это нулевая-байтовая терминальная lista имен файлов, которая - по крайней мере в данном компоненте данных - ожидает только ASCII-символы. Нет необходимости более подробно анализировать этот блок данных при разборе данных, так как в информации о томах непосредственно ссылаются на смещения имен файлов. |
Объемные строки представляют собой список имен файлов, которые находятся в объеме.
Информация о объеме
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 76 | 6f | 6c | 69 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | v | o | l | i | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Информация о томах содержит более подробные данные о файлах. Это своего рода запись в каталоге FAT (FAT = таблица размещения файлов).
Количество файлов вычисляется как размер блока, делённый на длину записей каталога - 14 байт.
Каждая отдельная запись каталога имеет следующую структуру:
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Смещение имени файла | Указывает, на каком смещении (!) в списке имен файлов (строки тома) находится имя файла. Это относится к началу блока данных. |
0x0004 | uint(32) | Смещение файла | Указывает, на каком смещении внутри всего тома файла находится файл. |
0x0008 | uint(32) | Размер файла | Указывает, насколько велика файл в байтах. |
0x000c | uint(16) | Флаги? | По всей видимости, предоставляется дополнительная информация о кодировке файла.
|
Объёмный блок
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 56 | 42 | 4c | 48 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | V | B | L | H | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Объемный блок представляет собой контейнер, который содержит файлы. Он включает в себя только еще раз - из-за формата блока - избыточный размер файла, и затем сразу же следуют полезные данные.
Плитки
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 42 | 4d | 50 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | B | M | P | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Тайлы представляют собой специфический для Outpost-2
формат графики в битмапе. Они охватывают 13 тайлсетов,
называемых "колодцами" (well0000.bmp
до well0012.bmp
),
которые находятся внутри объема maps.vol.
При этом тайлсеты / колодцы содержат следующее:
Имя файла | Содержимое |
---|---|
well0000.bmp | Графика размером 32x32 пикселя, синего цвета - идеально подходит для тестирования, работает ли ваш загрузчик изображений |
well0001.bmp | Содержит светлые камни, горные хребты на светлом камне и бесчисленные варианты кратеров удара на светлом камне |
well0002.bmp | Содержит элементы 'Doodads' светлого камня - то есть элементы, которые могут быть размещены для разбавления (или специально в качестве структуры, например, стен) на светлом камне, включая растительность |
well0003.bmp | Содержит коркообразную структуру на светлом камне |
well0004.bmp | Содержит темные камни, горные хребты на темном камне и бесчисленные варианты кратеров удара на темном камне |
well0005.bmp | Содержит элементы 'Doodads' темного камня - то есть элементы, которые могут быть размещены для разбавления (или специально в качестве структуры, например, стен) на темном камне |
well0006.bmp | Содержит коркообразную структуру на темном камне, а также переходы между светлым и темным камнем |
well0007.bmp | Содержит лаву, включая по 4-5 кадров анимации |
well0008.bmp | Содержит песок и бесчисленные варианты кратеров удара на песке |
well0009.bmp | Содержит элементы 'Doodads' песка - то есть элементы, которые могут быть размещены для разбавления (или специально в качестве структуры, например, стен) на песке |
well0010.bmp | Содержит по 48 переходов от песка к светлому и темному камню |
well0011.bmp | Содержит полярные шапки карты, с темным камнем в качестве фона |
well0012.bmp | Содержит полярные шапки карты, со светлым камнем в качестве фона |
Рекомендуется для точного выполнения не рендерить тайлы заранее для кэширования, так как данные для цикла день/ночь еще должны быть обработаны - и возникло бы слишком много данных.
Тайлы представляют собой графики с глубиной цвета 8 бит на пиксель с индексированной палитрой размером 32x32 пикселя, которые расположены друг под другом. Однако в таком созданном тайлсете может быть значительно больше
Главный контейнер состоит из 2 секций: head
и data
.
Заголовок плитки
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги | |
0x0008 | uint(32) | Версия / Флаги? | Это может быть указанием версии формата файла; во всех имеющихся у меня файлах здесь стояло значение |
0x000c | uint(32) | Ширина (Горизонтальное разрешение) | Указывает, насколько широка файл изображения (в пикселях). Для всех скважин Outpost 2 здесь следует ожидать значение |
0x0010 | uint(32) | Высота (Вертикальное разрешение) | Указывает, насколько высок файл изображения (в пикселях). Для всех колодцев Outpost 2 здесь ожидается значение |
0x0014 | uint(32) | Глубина цвета? | Значение этого параметра неизвестно. Поскольку он во всех проверенных файлах имеет значение |
0x0018 | uint(32) | Глубина цвета 2? | Значение этого значения неизвестно. Возможно, это 'целевое' цветовое глубина. |
После этих данных будет представлена палитра в стандартизированном формате RIFF. Точное описание можно найти - так как палитры встречаются и в других местах - по адресу Палитры.
Данные плитки
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
В конце концов, следуют чистые пиксельные данные, начиная с верхнего левого угла и движущиеся по строкам к нижнему правому углу.
Значение данных для графиков, которые обычно представлены в формате 8bpp-битмап, соответствует индексу цвета в цветовой палитре.
Игровой движок, вероятно, рисует тайлы по запросу.
Это, среди прочего, связано с циклом дня и ночи, который имеет 32 градации отдельных тайлов. При этом, судя по всему, от значения яркости отнимается 'немного'. Точные значения пока не удалось определить, я работаю на основе расчётов
v *= (daylight / 48) + 0.25;
с данными HSV пикселей, где daylight — это значение от 0 до 31, а v — значение от 0 до 1. Кроме того, следует учитывать, что на карте по бокам есть граница из 16 тайлов (она служит для невидимого появления юнитов).
Кроме того, цикл дня и ночи, похоже, обновляет только одну колонку карты за игровой цикл.
Ускоренный цикл дня и ночи выглядит следующим образом:
ПРТ
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 43 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | C | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина паллеты | Указывает количество палет, найденных в этом файле, в отличие от обычного блочного формата - не длину блока в байтах. |
0x0007 | uint(8) | Флаги | Вероятно, как обычно, флаги. Однако мне не известны флаги; так как все известные мне значения соответствуют |
Что именно обозначает PRT
, мне неизвестно; возможно, это 'Palette and Resource Table' - поскольку этот файл, который можно найти как op2_art.prt в maps.vol, является именно таким, или это довольно хорошо описывает его функцию.
Этот файл содержит список палитр, таблицу всех используемых битмапов, все определения анимации и еще ряд неизвестных данных. Он слабо следует предыдущему формату контейнера, поскольку не все записи соответствуют этой схеме.
Секция CPAL
(вероятно, обозначающая контейнер палитр) охватывает лишь данные палитр, указывая, сколько из обычно имеющихся 1052 байтных 8-битных палитр присутствуют.
Указание на 1052 байта не является обязательным, так как формат палитр потенциально может предусматривать различные размеры палитр. Это относится только к набору данных, с которым поставляется Outpost 2.
После списков палитр сразу, без вводного заголовка, следует список битмапов; точно так же сразу следуют списки анимаций.
Оба из них начинаются с uint(32) (или снова uint24+uint8 флаги?), который содержит количество записей.
Палитры
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 50 | 50 | 41 | 4c | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | P | P | A | L | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина поддона | Указывает количество палет, которые можно найти в этом файле, в отличие от обычного блочного формата - не длину блока в байтах. |
0x0007 | uint(8) | Флаги | Вероятно, как обычно, флаги. Однако мне не известны флаги; поскольку все известные мне значения соответствуют |
Информация о паллетах очень проста для восприятия.
Она состоит из заголовка и сегмента данных.
Заголовок палет
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 68 | 65 | 61 | 64 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | h | e | a | d | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина поддона | Указывает количество палет, которые можно найти в этом файле, в отличие от обычного блочного формата - не длину блока в байтах. |
0x0007 | uint(8) | Флаги | Вероятно, как обычно, флаги. Однако мне не известны флаги; поскольку все известные мне значения соответствуют |
0x0008 | uint(32) | Версия формата паллет? | Вероятно, определяет, какой версии формата палет соответствует палитра. Все палитры Outpost2, похоже, имеют версию |
Данные по палетам
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | 64 | 61 | 74 | 61 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | d | a | t | a | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Магические байты | |
0x0004 | uint(24) | Длина блока | |
0x0007 | uint(8) | Флаги |
Раздел данных включает в себя отдельные записи палет. Количество записей палет определяется как длина блока / 4.
Каждая из записей имеет следующий простой формат;
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | 04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(8) | Красный компонент | Указывает на долю красного цвета |
0x0001 | uint(8) | Зелёный компонент | Указывает долю зеленого в цвете |
0x0002 | uint(8) | Синяя компонента | Указывает долю синего цвета в цвете |
0x0003 | uint(8) | Неизвестно - Флаги? | Неясно, что означает это значение, так как оно, похоже, в основном |
Что касается палитр, то следует отметить, что для палитр, используемых в анимациях, действуют следующие правила:
- Первый цвет ВСЕГДА прозрачный, независимо от указанного значения.
-
Записи палитры с 1 по 24 считаются цветами игрока в палитрах с 1 по 8.
Откуда берутся цвета, отличные от цвета игрока 1, мне неясно.
Я предполагаю, что остальные цвета закодированы.
Растровые изображения
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Выравненная ширина | Указывает ширину строк пиксельных данных в байтах - так как они выровнены по границам в 4 байта. Таким образом, быстро можно перейти к определенной строке изображения. Почему это значение хранится отдельно, хотя его можно было бы вычислить, неясно. |
0x0004 | uint(32) | Смещение | Указывает смещение первой строки в битовой карте |
0x0008 | uint(32) | Высота | Указывает высоту изображения в пикселях |
0x000c | uint(32) | Ширина | Указывает ширину изображения в пикселях |
0x0010 | uint(16) | Тип | Указывает тип изображения. Похоже, что это битовая маска:
|
0x0012 | uint(16) | Палитра | Определяет, какая палитра из файла PRT должна использоваться |
Эта структура данных файла PRT указывает, как устроены битмапы, используемые для спрайтов. Эти битмапы служат отдельным компонентом, из которого собираются несколько кадров анимации спрайта.
Конкретные данные изображения скрываются в
op2_art.BMP в игровом каталоге.
Почему этот файл битмапа имеет (в основном корректный) заголовок RIFF-битмапа, остается неясным. Возможно, Outpost 2 использует системные API для загрузки графики, временно заимствуя этот заголовок и перезаписывая соответствующие изменяющиеся поля.
Данные пикселей находятся в BMP-файле по позиции Offset + uint32-Offset, который можно найти в BMP-файле по адресу 0x000A (RIFF-данные смещения битмапа) и снова соответствуют построчной организации сверху слева направо вниз.
Монохромные графики 1bpp могут быть нарисованы так, что цвет 0 представляет полную прозрачность, а цвет 1 является полупрозрачным черным/серым, так как монохромные графики обычно используются для теней автомобилей и зданий в анимациях.
Таким образом, можно собрать множество графиков.
Анимации
Теперь мы переходим к королевскому классу дисциплин внутри форматов данных Outpost 2:
К анимациям.
Списки анимаций начинаются с глобального заголовка, который служит в основном для верификации данных. После этого следуют конкретные определения анимаций, которые делятся на 3 уровня:
-
Анимация
Анимация является верхней инстанцией; она представляет собой анимацию юнита, здания или 'частичной анимации' (удар кометы, погода, взрыв) в определенной начальной позиции. -
Кадр
Кадр — это одно изображение в рамках анимации. Анимация может содержать один или несколько кадров. -
Субкадр
Субкадр — это информация о том, что определенная битмап должна быть нарисована в определенном месте кадра по определенным критериям. Один кадр может содержать один или несколько субкадров.
После этого сразу следуют отдельные определения анимаций.
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Количество анимаций | Сколько анимационных наборов данных доступно |
0x0004 | uint(32) | Количество кадров | Сколько всего кадров должно быть |
0x0008 | uint(32) | Количество подсистем | Сколько субкадров всего должно быть |
0x000c | uint(32) | Количество дополнительных записей | Сколько "дополнительных записей" имеется. |
Анимация
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0010 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
0x0020 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(32) | Неизвестно 1 | Неизвестная информация |
0x0004 | uint(32) | Ограничивающий прямоугольник: Слева | Указывает левый край (в пикселях) ограничивающей рамки. |
0x0008 | uint(32) | Ограничивающий прямоугольник: Вверх | Указывает верхнее начало (в пикселях) ограничивающего прямоугольника. |
0x000c | uint(32) | Ограничивающий прямоугольник: Ширина | Указывает ширину (в пикселях) ограничивающей рамки. |
0x0010 | uint(32) | Ограничивающий прямоугольник: высота | Указывает высоту (в пикселях) объемлющего прямоугольника. |
0x0014 | uint(32) | Смещение: X | Указывает горизонтальный центр анимации |
0x0018 | uint(32) | Смещение: Y | Указывает вертикальный центр анимации |
0x001c | uint(32) | Неизвестно 2 | Неизвестная информация |
0x0020 | uint(32) | Количество кадров | Указывает, сколько кадров анимации содержится в этой анимации |
0x0024 | uint(32) | Количество окон | Указывает, сколько окон следует использовать при рисовании |
Данные верхнего уровня, анимации, в основном представляют собой административные данные - Boundingbox обозначает координаты метки вокруг транспортного средства/здания, когда оно выбрано, и одновременно указывает, какая область должна быть кликабельной.
Смещение в первую очередь определяет "нулевую точку"; точку, к которой нужно прибавить или вычесть игровые координаты. Можно также сказать математически: смещение здесь обозначает начало координат.
В окнах, так же как и в случае со смещением, содержится по 4 значения uint(32) для каждого окна, которые указывают область, пригодную для отдельных подрамок. За пределами окон не должно быть рисования, если это не предусмотрено для битовой карты.
Рамка
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(8) | Количество подрамников и переключатель для Опционального 1, 2 | Это значение содержит:
|
0x0001 | uint(8) | Неизвестный 1 и переключатель для Опциональных 3, 4 | Это значение содержит:
|
0x0002 | uint(8) | Дополнительно 1 | Неизвестно |
0x0003 | uint(8) | Необязательный 2 | Неизвестно |
0x0004 | uint(8) | Необязательный 3 | Неизвестно |
0x0005 | uint(8) | Опционально 4 | Неизвестно |
Субрамка
Адр | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF | симв. | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0x0000 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . |
Смещение | Тип данных | Наименование | Объяснение |
---|---|---|---|
0x0000 | uint(16) | Идентификатор битмапа | Указывает, какая битмап должна использоваться для этого подфрейма |
0x0002 | uint(8) | Неизвестно 1 | Неизвестно - однако я сильно подозреваю, что это связано с приоритетом рендеринга (Z-слой). |
0x0003 | uint(8) | Идентификатор подрамника | Указывает, в каком подфрейме мы находимся |
0x0004 | sint(16) | Смещение - Горизонтальное | Указывает, где внутри фрейма должно быть размещено подфрейм, или на сколько пикселей битмап должен быть смещен по горизонтали. |
0x0006 | sint(16) | Смещение - Вертикальное | Указывает, где внутри фрейма следует разместить подфрейм, или на сколько пикселей битмап следует сместить вертикально |
Теперь мы можем собирать отдельные кадры, а также целые анимации, как это демонстрируется на более сложной анимации с индексом 500
Анимация 500
Анимация 500 показывает, как грузовик Plymouth, загруженный обычным рудами, разгружается. Это одна из немногих анимаций, использующих функцию окон.
Таким образом, можно собрать всю анимацию вместе.
К сожалению, есть еще одна проблема с верхним люком, так как соответствующий
бит в информации о типе графики не установлен.
Вот еще несколько прекрасно анимированных спрайтов из игры:
Пользовательский интерфейс
Теперь осталось только пользовательское интерфейс игры, выполненное в матовом металле.
Но и здесь видно, что Dynamix не пришлось изобретать велосипед; здесь не просто используются стандартные API User32 и GDI32, предоставленные Windows — также используется управление ресурсами от User32.
Их можно, например, извлечь с помощью программы Resource Hacker, разработанной Ангусом Джонсоном в качестве бесплатного ПО, или - если вы избегаете использования Wine под Linux / Mac OS - с помощью wrestool, входящего в состав icoutils.
Имя файла | Содержимое |
---|---|
Outpost2.exe | Содержит лишь иконку игры, показывающую космическую станцию перед New Terra |
op2shres.dll | Содержит графику для элементов управления, таких как рамки, кнопки, радиокнопки и флажки, а также фоны диалогов, сопроводительные изображения для текстов сюжетных миссий и фоновую графику главного меню |
out2res.dll | Содержит декорации окон в игре, иконки для обычного и специального металла, экран загрузки, графику для диалогов, а также дополнительные графики курсоров, помимо анимированных в игровом каталоге |