Created
April 29, 2022 18:31
-
-
Save mbikovitsky/89a285d489feb2b7e0ec1c01fab60991 to your computer and use it in GitHub Desktop.
010 Editor template for Still Life 2 .PFF files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------ | |
//--- 010 Editor v12.0.1 Binary Template | |
// | |
// File: PFF.bt | |
// Authors: Michael Bikovitsky | |
// Version: 0.1 | |
// Purpose: Parses Still Life 2 cutscene files | |
// Category: Game | |
// File Mask: *.pff | |
// ID Bytes: 50 46 46 30 2E 30 00 | |
// History: | |
//------------------------------------------------ | |
// MIT License | |
// | |
// Copyright (c) 2022 Michael Bikovitsky | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in all | |
// copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
// SOFTWARE. | |
LittleEndian(); | |
#define VIDEO_SECTION_MAGIC "VIDEO" | |
#define SOUND_SECTION_MAGIC "SOUND" | |
#define FILE_FOOTER_MAGIC "ENDFILE" | |
struct DDS_PIXELFORMAT | |
{ | |
DWORD dwSize; | |
Assert(32 == dwSize, "Invalid pixel format structure size"); | |
DWORD dwFlags; | |
char dwFourCC[4]; | |
DWORD dwRGBBitCount; | |
DWORD dwRBitMask; | |
DWORD dwGBitMask; | |
DWORD dwBBitMask; | |
DWORD dwABitMask; | |
}; | |
struct DDS_HEADER | |
{ | |
DWORD dwSize; | |
Assert(124 == dwSize, "Invalid DDS header size"); | |
DWORD dwFlags; | |
DWORD dwHeight; | |
DWORD dwWidth; | |
DWORD dwPitchOrLinearSize; | |
DWORD dwDepth; | |
DWORD dwMipMapCount; | |
DWORD dwReserved1[11]; | |
DDS_PIXELFORMAT ddspf; | |
DWORD dwCaps; | |
DWORD dwCaps2; | |
DWORD dwCaps3; | |
DWORD dwCaps4; | |
DWORD dwReserved2; | |
}; | |
local byte first_video_section = true; | |
struct VIDEO_SECTION | |
{ | |
string szVideo; | |
Assert(szVideo == VIDEO_SECTION_MAGIC, "Invalid video header magic"); | |
DWORD cbSize; | |
local int64 header_end_pos = FTell(); | |
if (first_video_section) | |
{ | |
first_video_section = false; | |
struct | |
{ | |
DWORD cbDecompressed; | |
char dwDDSMagic[4]; | |
Assert("DDS " == dwDDSMagic, "Invalid DDS header magic"); | |
DDS_HEADER tDDS; | |
Assert(tDDS.ddspf.dwFlags & 0x4); // DDPF_FOURCC | |
Assert("DXT1" == tDDS.ddspf.dwFourCC); | |
} tMetadata; | |
} | |
struct | |
{ | |
UBYTE bIntermediate : 1; | |
UBYTE bCompressed : 1; | |
UBYTE bRLE : 1; | |
UBYTE bTwoParts : 1; | |
} fFlags; | |
UBYTE acData[cbSize - (FTell() - header_end_pos)]; | |
}; | |
struct SOUND_SECTION | |
{ | |
string szSound; | |
Assert(szSound == SOUND_SECTION_MAGIC, "Invalid sound section magic"); | |
DWORD cbSize; | |
UBYTE nTrackIndex; | |
UBYTE acData[cbSize - sizeof(nTrackIndex)]; | |
}; | |
struct PFF_HEADER | |
{ | |
string szMagic; | |
Assert(szMagic == "PFF0.0", "Invalid file header magic"); | |
if (ReadString(FTell(), 5) == "VIDEO") | |
{ | |
string szVideoFormat; | |
Assert(szVideoFormat == "VIDEO_DDS", "Unsupported video format"); | |
} | |
while (ReadString(FTell(), 5) == "SOUND") | |
{ | |
struct | |
{ | |
string szSoundFormat; | |
Assert(szSoundFormat == "SOUND_VORBIS", "Unsupported audio format"); | |
string szLang; | |
} tSound; | |
} | |
string szEndHeader; | |
Assert(szEndHeader == "ENDHEADER", "Invalid end-of-header magic"); | |
}; | |
struct FRAME | |
{ | |
string szFrame; | |
Assert(szFrame == "FRAME", "Invalid frame header magic"); | |
DWORD cbSize; | |
double nTimestamp; | |
if (ReadString(FTell()) == VIDEO_SECTION_MAGIC) | |
{ | |
VIDEO_SECTION tVideo; | |
} | |
while (ReadString(FTell()) == SOUND_SECTION_MAGIC) | |
{ | |
SOUND_SECTION atSound; | |
} | |
string szEndFrame; | |
Assert(szEndFrame == "ENDFRAME", "Invalid end-of-frame magic"); | |
}; | |
struct PFF_FOOTER | |
{ | |
string szEndFile; | |
Assert(szEndFile == FILE_FOOTER_MAGIC, "Invalid file footer magic"); | |
}; | |
PFF_HEADER header; | |
while (ReadString(FTell()) != FILE_FOOTER_MAGIC) | |
{ | |
FRAME frame; | |
} | |
PFF_FOOTER footer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment