Outpost 2 Формати файлів · bei.pm

Цей текст був автоматично перекладений за допомогою OpenAI GPT-4o Mini.

Описані на цій сторінці формати файлів базуються на технічному аналізі інтелектуальної власності Dynamix, Inc. та Sierra Entertainment.
Інтелектуальна власність сьогодні є частиною маси Activision Publishing, Inc. / Activision Blizzard, Inc. і наразі належить Microsoft Corp..

Інформація була зібрана за допомогою реверс-інженерії та аналізу даних з метою архівування та взаємодії з історичними даними.
Не використовувалися жодні власницькі або конфіденційні специфікації.

Гру наразі можна придбати на gog.com як завантаження.

Мистецтво гри

Наступна серія статей документує мої знання про формати даних у грі в реальному часі "Outpost 2: Divided Destiny", яка була випущена Sierra у 1997 році і розроблена компанією 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) Магічні байти

Містить інформацію про те, чого очікувати в наступному блокові даних.

Відомі значення:

  • 0x204C4F56 ('VOL '):
    Обсяг
  • 0x686C6F76 ('VOLH'):
    Заголовок обсягу
  • 0x736C6F76 ('VOLS'):
    Строки обсягу
  • 0x696C6F76 ('VOLI'):
    Інформація про обсяг
  • 0x4B4C4256 ('BLCK'):
    Блок обсягу
  • 0x504D4250 ('PBMP'):
    Графічні дані
  • 0x4C415050 ('PPAL'):
    Колірна палітра
  • 0x4C415043 ('CPAL'):
    Контейнер кольорових палітр
  • 0x64616568 ('head'):
    Заголовок
  • 0x61746164 ('data'):
    Користувацькі дані
0x0004 uint(24) Блок-довжина

Містить інформацію про те, який розмір (в байтах) має наступний блок даних.

При цьому маються на увазі лише корисні дані - 8 байтів заголовка в них не включені.

0x0007 uint(8) Прапори?

Невідомо, для чого саме призначений цей блок.

У томах це значення часто становить 0x80, а в інших файлах - 0x00. Це свідчить про те, що йдеться про набір прапорців.

Том

Обсяги - це контейнери даних для гри, схожі на архівний формат, наприклад, 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)[] Список імен файлів

Йдеться про список імен файлів, термінований 0-байтом, який - принаймні в даному елементі даних - очікує лише символи 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) Індекс імен файлів

Вказує, на якому зсуві (!) у списку імен файлів (Volume-Strings) розташоване ім'я файлу.

Це стосується початку блоку корисних даних.

0x0004 uint(32) Файл-офсет

Вказує, на якому зсуві в межах усієї об'ємної файлу знаходиться файл.

0x0008 uint(32) Розмір файлу

Вказує, який розмір файлу в байтах.

0x000c uint(16) Прапори?

Здається, є додаткова інформація про кодування файлів.

  • 0x03 встановлено, якщо файл стиснутий. Тут, очевидно, використовується дерево Хаффмана.
  • 0x80 здається завжди встановленим.

Об'ємний блок

Адр 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 форматом bitmap-графіки. Вони охоплюють 13 тайлсетів, названих "колодязями" (well0000.bmp до well0012.bmp), які містяться у обсязі maps.vol.

При цьому тайлсети / колодязі містять наступне:

Ім'я файлу Зміст
well0000.bmp Графіка розміром 32x32px, синя - ідеальна для тестування роботи вашого завантажувача зображень
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 Містить полярні шапки карти, з світлим камінням як основою

Рекомендується для точної реалізації не рендерити тайли заздалегідь для кешування, оскільки дані для циклу день/ніч ще потрібно обробити - і виникне дуже-дуже багато даних.

Тайли - це 8bpp-графіки з індексованою палітрою розміром 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) Версія / Прапори?

Це може бути вказівкою версії формату файлу; у всіх наявних у мене файлах тут було значення 0x02

0x000c uint(32) Ширина (Горизонтальний розділ)

Вказує, наскільки широка файл зображення (в пікселях).

У всіх колодязях з Outpost 2 тут очікується значення 0x20 або 32.

0x0010 uint(32) Висота (Вертикальне розділення)

Вказує, яка висота зображення (в пікселях).

У всіх колодязях Outpost 2 тут слід очікувати значення 0x20 або 32.

0x0014 uint(32) Глибина кольору?

Значення цього параметра невідоме.

Оскільки він містить значення 8 у всіх перевірених файлах, це може бути вказівкою на глибину кольору.

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) Прапори

Напевно, як звичайно, флаги.

Однак мені не відомі ніякі флаги; оскільки всі відомі мені значення відповідають 0x00, також потенційно можливо, що кількість паліт може бути просто uint(32).

Що саме означає PRT мені невідомо; можливо, це може бути 'Таблиця палітри та ресурсів' - оскільки цей файл, який можна знайти як 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) Прапори

Ймовірно, як зазвичай, це прапори.

Проте мені не відомі жодні прапори; оскільки всі відомі мені значення відповідають 0x00, також потенційно можливо, що кількість палітрових просто є uint(32).

Інформацію про палети дуже легко прочитати.
Вона складається з заголовка та сегмента даних.

Заголовок палет

Адр 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) Прапори

Ймовірно, як зазвичай, це прапори.

Проте мені не відомі жодні прапори; оскільки всі відомі мені значення відповідають 0x00, також потенційно можливо, що кількість палітрових просто є uint(32).

0x0008 uint(32) Версія формату палет?

Ймовірно, визначає, якій версії формату палет відповідає палета.

Усі палети Outpost2, здається, мають версію 0x01.

Дані палет

Адр 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) Невідомо - Прапори?

Невідомо, що означає це значення, оскільки воно, здається, в основному 0x04.

Щодо палітри, слід зазначити, що для палітр, які використовуються в анімаціях, діють такі правила:

  • Перший колір завжди є прозорим, незалежно від вказаного значення.
  • Записи палітри з 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) Тип

Вказує тип зображення. Йдеться, ймовірно, про бітову маску:

  • 0x04 встановлено, якщо це графіка з роздільною здатністю 1bpp.
  • 0x40 встановлено, якщо це графіка, яка повинна реалізовувати віконний режим.
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 рівні:

  1. Анімація
    Анімація є найвищою інстанцією; вона представляє анімацію одиниці, будівлі або "частинкову анімацію" (удар комети, погода, вибух) у певній початковій ситуації.
  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) Обмежуючий прямокутник: Зліва

Вказує лівий початок (в пікселях) Bounding Box.

0x0008 uint(32) Обмежувальний прямокутник: Верхня частина

Вказує верхній початок (в пікселях) Bounding Box.

0x000c uint(32) Обмежувальна рамка: Ширина

Вказує ширину (в пікселях) обмежувальної рамки.

0x0010 uint(32) Обмежувальний прямокутник: висота

Вказує висоту (в пікселях) Bounding Box.

0x0014 uint(32) Зсув: X

Вказує горизонтальний центр анімації

0x0018 uint(32) Зсув: Y

Вказує вертикальний центр анімації

0x001c uint(32) Невідомо 2

Невідома інформація

0x0020 uint(32) Кількість кадрів

Вказує, скільки анімаційних кадрів міститься в цій анімації

0x0024 uint(32) Кількість вікон

Вказує, скільки вікон слід використовувати під час малювання

Дані верхнього шару, анімації, є переважно адміністративними даними - Boundingbox позначає координати мітки навколо транспортного засобу/будівлі, коли вона вибрана, і також вказує, яка область має бути активною для кліку.

Зміщення (offset) в основному визначає "нулеву точку"; точку, яку потрібно враховувати або віднімати для внутрішніх координат гри. Можна також сказати більш математично: зміщення тут позначає координатний початок.

Вікна аналогічно до зміщення складаються з 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

Це значення містить:

  • 0x7F (Бітова маска): Кількість підрамок, які використовуються в цьому кадрі
  • 0x80: Інформація про те, чи присутні Опціональні 1 та 2
0x0001 uint(8) Невідомий 1 та перемикач для необов'язкових 3, 4

Це значення містить:

  • 0x7F (Бітова маска): Невідомо - Я сильно підозрюю, що це кількість ігрових тактів, які проходять, поки не буде показано наступний кадр
  • 0x80: Інформація про те, чи присутні Опціональні 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) Bitmap-Ідентифікатор

Вказує, яка бітова мапа має використовуватися для цього підфрейму

0x0002 uint(8) Невідомий 1

Невідомо - проте я сильно підозрюю, що це стосується пріоритету рендерингу (Z-слой).

0x0003 uint(8) Підрамник-Ідентифікатор

Вказує, у якому підфреймі ми знаходимося

0x0004 sint(16) Зсув - Горизонтальний

Вказує, де всередині фрейма має бути розміщено підфрейм, або на скільки пікселів бітмап має бути горизонтально зсунуто.

0x0006 sint(16) Зсув - Вертикальний

Вказує, де всередині фрейму слід розмістити підфрейм, або на скільки пікселів бітмапу потрібно змістити вертикально.

Тепер ми можемо складати окремі кадри, а також цілі анімації відповідно, на прикладі більш складної анімації з індексом 500, продемонстровано

Анімація 500

Анімація 500 показує, як вантажівка Plymouth, завантажена звичайною рудою, розвантажується. Це одна з небагатьох анімацій, яка використовує функціональність вікон.

Отже, можна зібрати всю анімацію разом.
На жаль, є ще одна проблема з верхнім люком, оскільки відповідний біт у інформації про тип графіки не встановлений.

Ось ще кілька інших, чудово анімованих спрайтів з гри:

Візуалізація анімації 500 ілюструє

Анімація 500 завершена

Фабрика будівель Plymouth

Космопорт Eden

Медичний центр Eden

SCAT

Космопорт Plymouth

Секрет:
Дід Мороз

Секрет:
Собака Дена

Користувацький інтерфейс

Тепер залишилося ще інтерфейс користувача гри, який виконаний у стилі шліфованого металу.

Але й тут видно, що Dynamix не потрібно було винаходити велосипед заново; тут використовуються не лише прості функції, надані API User32 та GDI32 від Windows - зокрема, також використовується управління ресурсами User32.

Ці ресурси можна, наприклад, витягнути за допомогою програм, таких як Resource Hacker, що розроблений Angus Johnson як безкоштовне програмне забезпечення, або - якщо ви уникаєте використання Wine під Linux / Mac OS - за допомогою wrestool, що входить до складу icoutils.

Ім'я файлу Вміст
Outpost2.exe Містить лише іконку гри, яка зображує космічну станцію перед New Terra
op2shres.dll Містить крім графіки для елементів управління, таких як обрамлення, кнопки, радіокнопки та прапорці, також фонові зображення для діалогів, супутні зображення для текстів сюжетних місій і фонову графіку головного меню
out2res.dll Містить оформлення вікон у грі, іконки для звичайного та спеціального металу, екран завантаження, графіки для діалогів, а також додаткові графіки курсора, окрім анімованих у каталозі гри