Archive Library¶
The Archive Library supports reading and writing files from the PC releases of the game.
File List contains one or more path strings. Each starting with C:\ff8\Data\ ending with \r\n. These are in the same order as
the File Index. You scan the File List to find the items you want, while doing this you would increment a counter. The counter is
used to know which entry to get from File Index. Lastly, you use the File Index to read from the File Source.
ZZZ contains multiple files including FLFIFS archives of different languages. The ZZZ header starts with the number of entries followed by FileData entries. File Source functions can accept FileData entries to extract from ZZZ files.
References:
Archives¶
The Archives object plays a crucial role in locating and organizing archives within a specified directory. Its primary function involves indexing these archives and facilitating a straightforward interface for reading the contained files.
-
struct Archives¶
Reads a path looking for ZZZ or FIFLFS archives. It remembers the locations of the archives, and serves serves as a front end to access them.
Public Functions
- template<ArchiveTypeT archiveTypeT> inline requires valid_archive_type_t< archiveTypeT > const auto & get () const noexcept
Get archive via ArchiveTypeT
- Template Parameters:
archiveTypeT –
- Returns:
- template<ArchiveTypeT archiveTypeT> inline requires valid_archive_type_t< archiveTypeT > auto & get () noexcept
Get archive via ArchiveTypeT
- Template Parameters:
archiveTypeT –
- Returns:
-
inline explicit operator bool() const noexcept¶
convert to bool
- Returns:
-
inline auto get_nested(const std::initializer_list<std::string_view> &nested_archive) const¶
Gets the nested FIFLFS files from Field archive.
- Parameters:
nestedArchive – string to filter results. {} will get all nested archives.
- Returns:
all results.
-
Archives() = default¶
This will be in an invalid state but it’s so I can default construct and move in valid values later.
-
inline Archives(const std::filesystem::path &path, std::string_view lang)¶
Preloads all archives in the path.
- Parameters:
path – that contains FIFLFS files or ZZZ files.
- template<std::intmax_t minT = static_cast<std::intmax_t>(ArchiveTypeT::begin), std::intmax_t maxT = static_cast<std::intmax_t>(ArchiveTypeT::end), typename lambdaT> inline requires valid_archive_type_t< minT > &&valid_archive_type_t< maxT, true > &&valid_lambda< lambdaT > bool loop (const lambdaT &lambda) const
Loop through each of the archives.
- Template Parameters:
minT – min archive
maxT – max archive
lambdaT – type of lambda function that returns bool and takes archive types. The bool returned short circuits the loop.
- Parameters:
lambda – lambda of type lambdaT
- Returns:
true if ran to completion
- template<ArchiveTypeT... aT, typename lambdaT> inline requires valid_archive_type_t_v< aT... > bool specify (const lambdaT &lambda)
run lambda on listed types.
- Template Parameters:
aT –
lambdaT –
- Parameters:
lambda –
- Returns:
-
inline bool test_set() const¶
if true all archives are valid.
- Returns:
- template<ArchiveTypeT... aT> inline requires not_zero< aT... > bool test_set ()
if true listed archives are valid
- Template Parameters:
aT –
- Returns:
- template<bool nested = true, typename lambdaT, typename filterT = decltype(default_filter_lambda)> inline requires valid_execute_on_lambda< lambdaT > &&valid_filter_lambda< filterT > bool execute_on (const std::initializer_list< std::string_view > &filename, lambdaT &&lambda, filterT &&filter_lambda={}) const
execute on all archives the following lambda.
- Template Parameters:
nested –
lambdaT –
- Parameters:
filename –
lambda –
- Returns:
- template<bool nested = true, ArchiveTypeT... aT, typename lambdaT, typename filterT = decltype(default_filter_lambda)> inline requires not_zero< aT... > &&valid_execute_on_lambda< lambdaT > &&valid_filter_lambda< filterT > bool execute_on (const std::initializer_list< std::string_view > &filename, lambdaT &&lambda, filterT &&filter_lambda={}) const
execute on all listed archives the following lambda.
- Template Parameters:
nested –
aT –
lambdaT –
- Parameters:
filename –
lambda –
- Returns:
ArchiveTypeT¶
The ArchiveTypeT enum encapsulates identifiers for different archive types in Final Fantasy VIII. There are six primary FIFLFS archives: battle, field, magic, main, menu, and world. Additionally, there are two main zzz archives for the FF8 remaster: zzz_main and zzz_other. These enums serve as convenient references for utilizing the “get<>” function in archives, allowing users to specify the desired archive type when interacting with the archives in the game code. The enum also provides utility constants such as ‘count,’ ‘first,’ ‘last,’ ‘begin,’ and ‘end’ for easy enumeration management.
-
enum class open_viii::archive::ArchiveTypeT : std::uint8_t¶
There are 6 main FIFLFS archives for ff8 and 2 2 main zzz archives for ff8 remaster. These enums are for get<> in archives to ask for the one you want.
Values:
-
enumerator battle¶
-
enumerator field¶
-
enumerator magic¶
-
enumerator main¶
-
enumerator world¶
-
enumerator zzz_main¶
-
enumerator zzz_other¶
-
enumerator count¶
-
enumerator first¶
-
enumerator last¶
-
enumerator begin¶
-
enumerator end¶
-
enumerator battle¶
FIFLFS¶
The FIFLFS archive format in Final Fantasy VIII for PC consists of three main components: File Index (FI), File Source (FS), and File List (FL). FI stores offset and size information, FS contains raw bytes, and FL holds virtual file paths. These elements collectively structure the archive, facilitating organized storage and retrieval of game assets.
-
template<bool HasNested>
struct FIFLFS : public open_viii::archive::FIFLFSBase¶ A class representing a FIFLFS archive.
Forward declaration of the FIFLFS template struct.
This class provides methods to access and manipulate FIFLFS archives, with support for both nested and non-nested archives.
- Template Parameters:
HasNested – A boolean flag indicating whether the archive has nested archives.
Grouping¶
Grouping is essentially an object that stores information about different components of the archive, serving as a reference for later reading. This includes details like file paths and offsets, enabling easy retrieval and interpretation.
-
template<std::ranges::contiguous_range T>
struct Grouping¶ Grouping contains the location of the file and/or the raw data.
Public Functions
-
inline const std::filesystem::path &path() const noexcept¶
get path to file containing archive
- Returns:
-
inline std::size_t offset() const noexcept¶
get offset in bytes to start
- Returns:
-
inline std::size_t size() const noexcept¶
get Size of file / also defaults size if value is 0.
- Returns:
size_t
-
inline const std::string &base() const noexcept¶
stem of filename upper cased
- Returns:
-
inline const std::filesystem::path &nested_path() const noexcept¶
get path inside file
- Returns:
-
inline explicit operator bool() const¶
convert to bool
- Returns:
true means value is set and loaded.
-
inline const std::filesystem::path &path() const noexcept¶
File List¶
The File List (FL) consists of entries with virtual paths starting with c:\ff8. Each path is separated by a new line in Windows format (CRLF), maintaining the same order as the File Index (FI) entries.
-
namespace fl¶
Functions
-
inline constexpr void clean_path_string(std::string &input) noexcept¶
FL files contain internal file structure paths. As a flat text file. This class is used to search the strings for a filename or grab all the entries. The entry will be a string paired with an int that is the line number. This is used to ID the FI entries.
- Todo:
refactor this to reduce parameters and reduce functions.
- Parameters:
input – updates this string
skipFixed – if false skip removing the \r from end and skip replacing slashes.
- Returns:
void
-
inline std::string clean_path_string(std::string &&input) noexcept¶
Remove the C:\ from the start, remove the \r from the end, and change \ to the correct slash. added skipFixed if data is set then i probably fixed slashes already.
- Parameters:
input – updates this string
skipFixed – if false skip removing the \r from end and skip replacing slashes.
- Returns:
modified input
-
inline std::string clean_buffer(std::string &&in_buffer)¶
Take out carriage returns and replace slashes.
- Parameters:
in_buffer – multi line string of paths.
- Returns:
cleaned.
-
inline constexpr std::size_t get_max(const std::size_t &count, const std::size_t &limit)¶
Decide how much to reserve based on known count or a set limit.
- Parameters:
count – computed max count
limit – manual limit placed
- Returns:
0 or count or limit;
-
inline void sort_entries(std::span<std::pair<std::uint32_t, std::string>> vector)¶
Sort the strings. to make it easier to choose the correct string first. shorter length and then what ever str < str2 does.
- Parameters:
vector – pairs of ints and paths
-
inline auto sort_entries(std::vector<std::pair<std::uint32_t, std::string>> &&vector)¶
Sort the strings. to make it easier to choose the correct string first. shorter length and then what ever str < str2 does.
- Parameters:
vector – pairs of ints and paths
- Returns:
sorted vector
-
inline std::vector<std::string> get_all_entry_strings(const tl::read::input &cont, const size_t &offset, const size_t &size = 0U, const size_t &count = 0U, const std::initializer_list<std::string_view> &needle = {}, const size_t &limit = 0U)¶
Eagerly populate a vector with strings of paths, then sort it.
- Todo:
make needle a predicate lambda.
Note
If size, limit, count are all 0 it’ll read till end of file. Or till it reads an empty line.
- Parameters:
cont – wrapper on istream or span. For the source data.
offset – to start of data.
size – + offset is the end of the data.
count – max count detected from FI filesize / 12U.
needle – set of strings to search for.
limit – manually set max count.
- template<typename path_t> inline auto get_all_entry_strings (const path_t &path, const size_t &offset, const size_t &size=0U, const size_t &count=0U, const std::initializer_list< std::string_view > &needle={}, const size_t &limit=0U) requires(std
- template<typename path_t> inline std::vector< std::string > get_all_entry_strings (const path_t &path, const std::string &data, const std::size_t &offset, const std::size_t &size=0U, const std::size_t &count=0U, const std::initializer_list< std::string_view > &needle={}, const std::size_t &limit=0U) requires(std
Get All entries sorted from file or data buffer.
- Parameters:
path – filename path.
data – buffer of bytes.
offset – bytes from start of data to start looking.
size – of FL file if known; 0 == unlimited
count – expected number of matches; calculated from FI file size / 12; 0 == unlimited
needle – possible string matches; {} == all
limit – max matches; 0 == unlimited
- Returns:
matches
-
inline std::vector<std::pair<std::uint32_t, std::string>> get_all_entries(const tl::read::input &cont, const size_t &offset, const size_t &size = 0U, const size_t &count = 0U, const std::initializer_list<std::string_view> &needle = {}, const size_t &limit = 0U)¶
Eagerly populate a vector with pairs of (id,path), then sort it.
- Todo:
make needle a predicate lambda.
Note
If size, limit, count are all 0 it’ll read till end of file. Or till it reads an empty line.
- Parameters:
cont – wrapper on istream or span. For the source data.
offset – to start of data.
size – + offset is the end of the data.
count – max count detected from FI filesize / 12U.
needle – set of strings to search for.
limit – manually set max count.
- template<typename path_t> inline auto get_all_entries (const path_t &path, const size_t &offset, const size_t &size=0U, const size_t &count=0U, const std::initializer_list< std::string_view > &needle={}, const size_t &limit=0U) requires(std
-
inline std::vector<std::pair<std::uint32_t, std::string>> get_all_entries(const std::string &data, const size_t &offset, const size_t &size, const size_t &count, const std::initializer_list<std::string_view> &needle, const size_t &limit)¶
-
inline std::vector<std::pair<std::uint32_t, std::string>> get_all_entries(const std::filesystem::path &path, const std::string &data, const size_t &offset, const size_t &size = 0U, const size_t &count = 0U, const std::initializer_list<std::string_view> &needle = {}, const size_t &limit = 0U)¶
Get All entries sorted from file or data buffer.
- Parameters:
path – filename path.
data – buffer of bytes.
offset – bytes from start of data to start looking.
size – of FL file if known; 0 == unlimited
count – expected number of matches; calculated from FI file size / 12; 0 == unlimited
needle – possible string matches; {} == all
limit – max matches; 0 == unlimited
- Returns:
matches
-
template<typename T>
inline std::pair<std::uint32_t, std::string> get_entry(const T &data, const std::initializer_list<std::string_view> &needle, const size_t &offset = 0U, const size_t &size = 0U, const size_t &count = 0U)¶ Get a single entry that is the first match for needle.
- Parameters:
data – contains buffer of chars
needle – is a group of strings to filter the output with.
offset – is the number of bytes to skip.
size – is max number of bytes. 0 is unlimited.
count – is max results returned. 0 is unlimited.
-
inline std::pair<std::uint32_t, std::string> get_entry(const std::filesystem::path &path, const std::string &data, const std::initializer_list<std::string_view> &needle, const size_t &offset = 0U, const size_t &size = 0U, const size_t &count = 0U)¶
Get a single entry that is the first match for needle.
- Parameters:
path – contains path to file
data – contains buffer of chars
needle – is a group of strings to filter the output with.
offset – is the number of bytes to skip.
size – is max number of bytes. 0 is unlimited.
count – is max results returned. 0 is unlimited.
Variables
-
static constexpr auto EXT = std::string_view(".fl")¶
File extension
-
inline constexpr void clean_path_string(std::string &input) noexcept¶
File Index¶
The File Index (FI) contains information such as the offset, uncompressed file size, and compression type, with each entry occupying 12 bytes. To determine the total number of files, divide the size of the FI file by 12.
-
struct FI¶
FI is the file index for the FL and FS files.
Public Functions
-
inline constexpr auto uncompressed_size() const noexcept -> std::uint32_t¶
Get the uncompressed size of the data represented by this block.
- Returns:
The size of the block’s data after decompression, in bytes.
-
inline constexpr auto offset() const noexcept -> std::uint32_t¶
Get the offset of the block within the compressed file.
- Returns:
The offset in bytes from the beginning of the compressed file where this block’s compressed data can be found.
-
inline constexpr auto compression_type() const noexcept -> CompressionTypeT¶
Get the compression algorithm used to compress this block’s data.
- Returns:
The type of compression used to compress the data in this block, as defined by the
CompressionTypeTenum. Possible values arenone(for uncompressed data),lzss, orlz4.
Public Static Attributes
-
static constexpr auto SIZE = std::size_t{12U}¶
The size of the
FIstruct in bytes.This constant stores the expected size of the
FIstruct, in bytes. It is used in a static assertion to ensure that the size of theFIstruct matches the expected size at compile time.
-
static constexpr auto EXT = std::string_view{".fi"}¶
The file extension for files containing
FIdata.This constant stores the file extension for files containing
FIdata. The extension is stored as astd::string_viewfor efficiency and ease of use.
-
inline constexpr auto uncompressed_size() const noexcept -> std::uint32_t¶
File Source¶
File Source (FS) files store raw bytes of entries. For LZSS entries, the file begins with 4 bytes indicating the compressed file size. L4Z entries have a 12-byte header, including section size, an unused 4 bytes, and uncompressed size. The compressed size can be calculated by subtracting 8 from the section size.
-
namespace FS¶
Functions
- template<is_default_constructible_has_data_size_resize outputT = std::vector<char>, typename input_t = tl::read::input> static outputT get_entry_lzss (input_t &input, const std::uint32_t uncompressed_size) requires(std
Get entry and uncompress via lzss
Note
not meant to be used directly
Note
lzss doesn’t need the uncompressed size to extract the data but it’s used to reserve the memory before uncompressing.
- Template Parameters:
outputT – type to be returned: example std::string, std::vector<char>
fiT – FI or FI compatible type.
- Parameters:
input – buffer adapter that holds a std::span<char> or a std::istream
uncompressed_size – number of bytes expected to expand to.
- Returns:
output() filled with uncompressed data.
- template<is_default_constructible_has_data_size_resize outputT = std::vector<char>, typename input_t = tl::read::input> static outputT get_entry_lz4 (input_t &input) requires(std
Get entry and uncompress via lz4
Note
not meant to be used directly
Note
L4Z header contains size of total section as uint32, 4 byte string, and a uint32 of the uncompressed size.
- Template Parameters:
outputT – type to be returned: example std::string, std::vector<char>
fiT – FI or FI compatible type.
- Parameters:
input – buffer adapter that holds a std::span<char> or a std::istream
uncompressed_size – number of bytes expected to expand to.
- Returns:
output() filled with uncompressed data.
- template<is_default_constructible_has_data_size_resize outputT = std::vector<char>, FI_Like fiT = FI, typename input_t = tl::read::input> static outputT get_entry (input_t input, const fiT fi, const std::size_t offset=0U) requires(std
Get entry and uncompress via lz4
- Template Parameters:
outputT – type to be returned: example std::string, std::vector<char>
fiT – FI or FI compatible type.
- Parameters:
input – buffer adapter that holds a std::span<char> or a std::istream
fi – contains compression type, uncompressed size, and offset
offset – additional offset value added to fi.offset()
- Returns:
output() filled with uncompressed data.
- template<is_default_constructible_has_data_size_resize outputT = std::vector<char>, FI_Like fiT = FI, typename path_t = std::filesystem::path> static outputT get_entry (const std::filesystem::path &path, const fiT &fi, const size_t &offset=0U) requires(std
get file entry and decompress it
- Template Parameters:
outputT – type being returned
fiT – type of FI or FileData that contains offset, size, compression.
- Parameters:
path – to file
fi – FI or FileData
offset – to file data in bytes
- Returns:
uncompressed file
- template<is_default_constructible_has_data_size_resize outputT = std::vector<char>, FI_Like fiT = FI, typename span_t = std::span<const char>> static outputT get_entry (span_t data, const fiT &fi, const size_t offset=0U) requires(std
get file entry and decompress it
- Template Parameters:
outputT – type being returned
fiT – type of FI or FileData that contains offset, size, compression.
- Parameters:
data – buffer with embedded file
fi – FI or FileData
offset – to file data in bytes
- Returns:
uncompressed file
Variables
-
static constexpr auto EXT = std::string_view(".fs")¶
File Source
See also
http://wiki.ffrtt.ru/index.php?title=FF8/PC_Media#.fs_.28File_Source.29 Extension
ZZZ¶
ZZZ files initiate with a 4-byte file count, representing the number of File Data entries that follow. All entries within a ZZZ file remain uncompressed. To access an FS file within the ZZZ file, combine a given FI offset with the corresponding File Data offset.
-
struct ZZZ¶
ZZZ file archive from FF8 remaster.
See also
File Data¶
File Data entries feature variable sizes, requiring a one-at-a-time reading approach. To streamline this process, caching is employed. Each entry commences with a 32-bit size of the virtual file paths, where these paths are relative, such as data\disk\disk1. The entry then includes the corresponding virtual file paths, a 64-bit file offset, and a 32-bit file size.
-
struct FileData¶
FileData is an FI Like that contains the filepath, offset and size.
Public Functions
-
inline FileData(decltype(m_filename) filename, const std::unsigned_integral auto offset, const std::unsigned_integral auto size)¶
Piecemeal constructor
- Parameters:
filename – path to file
offset – path to
size –
-
inline constexpr auto total_size() const noexcept¶
size of this file entry in the zzz file. This is for appending a new entry. I don’t know if it works.
- Todo:
used in tests no where else. might want to make this a free function of the tests.
- Returns:
-
inline auto get_path() const¶
gets path as a std::filesystem::path
-
inline constexpr auto uncompressed_size() const noexcept¶
alias for Size that should mirror FI
-
inline constexpr auto offset() const noexcept¶
get offset of file
-
inline auto get_path_string_view() const¶
gets path as a std::string_view
-
inline auto get_path_string() const¶
gets path as a std::string
-
template<std::size_t I>
inline auto get() const noexcept¶ gets member variables
Note
required to structured binding support
Public Static Functions
-
static inline constexpr auto compression_type() noexcept¶
Compression type required to match FI like concept.
- Returns:
no compression
-
inline FileData(decltype(m_filename) filename, const std::unsigned_integral auto offset, const std::unsigned_integral auto size)¶