Skip to content

Instantly share code, notes, and snippets.

@mbikovitsky
Created April 29, 2022 18:31
Show Gist options
  • Save mbikovitsky/89a285d489feb2b7e0ec1c01fab60991 to your computer and use it in GitHub Desktop.
Save mbikovitsky/89a285d489feb2b7e0ec1c01fab60991 to your computer and use it in GitHub Desktop.
010 Editor template for Still Life 2 .PFF files
//------------------------------------------------
//--- 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