Outpost 2 파일 형식 · bei.pm

이 텍스트는 OpenAI GPT-4o Mini에 의해 자동으로 번역되었습니다.

이 페이지에 설명된 파일 형식은 Dynamix, Inc.Sierra Entertainment의 지적 재산에 대한 기술 분석을 기반으로 합니다.
현재 이 지적 재산은 Activision Publishing, Inc.Activision Blizzard, Inc.의 자산에 포함되어 있으며, 현재 Microsoft Corp.가 소유하고 있습니다.

정보는 아카이빙 및 역사적 데이터와의 상호 운용성을 위해 리버스 엔지니어링데이터 분석을 통해 수집되었습니다.
특허가 있는 비공식 사양은 사용되지 않았습니다.

현재 게임은 gog.com에서 다운로드로 구매할 수 있습니다.

게임 아트워크

다음의 기사 시리즈는 1997년 시에라에 의해 출시되고 다이나믹스에 의해 개발된 실시간 전략 게임 "Outpost 2: Divided Destiny"의 데이터 형식에 대한 나의 발견을 문서화합니다.

나는 2015년 11월 1일부터 2015년 11월 14일까지 주로 게임 데이터의 분석과 그것이 무엇을 하는지에 대해 연구했습니다.

내가 지금까지 얻은 정보에 따르면, 다이나믹스는 많은 상업적 기업들처럼 일부 데이터 형식을 "Outpost 2"를 위해 특별히 개발하지 않았고, 대신에 mechwarrior 시리즈와 같은 다른 개발에서도 변형하여 사용했습니다.
그와는 별도로 데이터 형식의 혁신성은 실질적으로 한계가 있으며, 종종 JFIF 및 RIFF와 같은 기존 형식의 오랜 개념에 기반하고 있다는 것을 알 수 있습니다.

테이블 및 데이터 형식의 해석에 대한 추가 정보는 무엇이 무엇인가?에 준비되어 있습니다.
여기에서 제공되는 데이터는 일반적으로 리틀 엔디안으로 이해되어야 합니다.

결론적으로, 리버스 엔지니어링은 매우 재미있었으며, 비록 완전하진 않지만 말입니다.
물론, 게임 자체를 플레이하는 것도 추천합니다. 흥미로운 게임 메커니즘을 제공합니다.

소개

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에서는 이 형식이 파일만 포함하고 있으며 - 폴더는 없습니다. 하지만 적절한 파일 이름을 통해 이러한 폴더를 시뮬레이션할 수 있을 것입니다.

볼륨은 볼륨 헤더와 여러 개의 볼륨 블록으로 구성되며, 이 블록은 구체적인 파일에 해당합니다.

"Volumes"는 게임 디렉토리 내에서 '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) 파일 이름 오프셋

파일 이름 목록(볼륨 문자열) 내에서 파일 이름이 위치하는 오프셋(!)을 지정합니다.

이는 데이터 블록의 시작을 기준으로 합니다.

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) 국기

타일은 아웃포스트-2 특정 비트맵 그래픽 포맷입니다. 이는 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 맵의 극관을 포함하며 밝은 암석을 바탕으로 함

정확한 구현을 위해 타일을 미리 렌더링하여 캐시하는 것은 권장하지 않습니다. 왜냐하면 주/야 주기에 대한 데이터는 아직 처리해야 하며, 매우 많은 데이터가 발생할 수 있기 때문입니다.

타일은 각각 32x32 픽셀 해상도의 인덱스 팔레트를 가진 8bpp 그래픽으로 서로 배열되어 있습니다. 이렇게 생성된 타일셋에는 훨씬 더 많은

주 컨테이너는 두 개의 섹션으로 구성되어 있습니다: headdata.

타일 헤더

주소 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개의 타일의 경계가 존재한다는 점을 고려해야 합니다 (이는 유닛의 보이지 않는 스폰을 위해 필요합니다).

추가로, 낮과 밤의 주기는 게임 사이클당 맵의 한 열만 업데이트하는 것 같습니다.
가속화된 낮과 밤의 주기는 다음과 같이 보입니다:

낮과 밤의 주기 시각화

PRT

주소 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.prtmaps.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 파일에서 오프셋 + uint32 오프셋 위치에 있으며, 이 값은 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) 바운딩 박스: 왼쪽

바운딩 박스의 왼쪽 시작 부분(픽셀 단위)을 지정합니다.

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에 대한 토글

이 값은 다음을 포함합니다:

  • 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) 비트맵 ID

이 서브프레임에 사용할 비트맵을 지정합니다.

0x0002 uint(8) 알 수 없음 1

알려지지 않았습니다 - 하지만 저는 이것이 렌더 우선순위(Z-레이어)와 관련이 있다고 강하게 추측합니다.

0x0003 uint(8) 서브프레임 ID

현재 우리가 있는 서브프레임을 나타냅니다

0x0004 sint(16) 오프셋 - 수평

프레임 내에서 서브프레임이 배치될 위치를 지정하거나 비트맵을 수평으로 몇 픽셀 이동할지를 나타냅니다.

0x0006 sint(16) 오프셋 - 수직

프레임 내에서 서브프레임이 어디에 배치되어야 하는지, 또는 비트맵이 수직으로 몇 픽셀 이동해야 하는지를 지정합니다.

이를 통해 우리는 개별 프레임뿐만 아니라 전체 애니메이션을 적절하게 조합할 수 있습니다. 여기서는 인덱스 500의 복잡한 애니메이션을 예로 들어 설명합니다.

애니메이션 500

애니메이션 500은 일반 광석이 실린 플리머스 화물차가 하역되는 모습을 보여줍니다. 이는 창 관리 기능을 활용하는 몇 안 되는 애니메이션 중 하나입니다.

이렇게 전체 애니메이션을 조합할 수 있습니다.
안타깝게도 상단 적재구에 문제가 있는데, 여기서 그래픽 유형 정보의 해당 비트가 설정되지 않았습니다.

게임에서의 아름답게 애니메이션된 스프라이트 몇 개를 더 소개합니다:

애니메이션 500의 렌더링이 설명됨

완전하게 조합된 애니메이션 500

플리머스 건물 공장

에덴 우주항

에덴 의료 센터

SCAT

플리머스 우주항

이스터 에그:
산타클로스

이스터 에그:
Dans Dog

사용자 인터페이스

이제 게임의 사용자 인터페이스가 남았으며, 이는 브러시드 메탈 느낌으로 디자인되었습니다.

하지만 여기서도 Dynamix가 새로운 바퀴를 발명할 필요는 없었습니다; 여기서는 Windows에서 제공하는 User32 및 GDI32 API를 단순히 사용하는 것이 아니라, 특히 User32의 리소스 관리도 활용되고 있습니다.

예를 들어, Angus Johnson이 무료 소프트웨어로 개발한 Resource Hacker와 같은 프로그램을 통해 추출할 수 있으며, Linux / Mac OS에서 Wine 사용을 꺼리는 경우에는 icoutils에 포함된 wrestool을 사용할 수 있습니다.

파일 이름 내용
Outpost2.exe 게임의 아이콘만 포함되어 있으며, 이는 New Terra 앞의 우주 정거장을 보여줍니다.
op2shres.dll 테두리, 버튼, 라디오 버튼, 체크박스와 같은 조작 요소의 그래픽 외에도 스토리 미션 텍스트에 대한 배경 이미지와 메인 메뉴 배경 그래픽을 포함합니다.
out2res.dll 인게임 윈도우 장식, 일반 및 특수 금속 아이콘, 로딩 화면, 대화 그래픽 및 기타 커서 그래픽을 포함하며, 게임 디렉토리에 있는 애니메이션 그래픽도 추가됩니다.