A modern C++20 library for reading and writing the .big file archive format used by Command & Conquer Generals and other Westwood Studios games.
- Zero-copy file access - Memory-mapped I/O for efficient handling of large archives
- Full read/write support - Create, read, and modify BIG archives
- Cross-platform - Windows, Linux, macOS
- Header-only public API - Simple integration with
#include <bigx/bigx.hpp> - Case-insensitive file lookup - Compatible with original game behavior
- No external dependencies - Standard library only (except for testing)
# Configure
cmake -B build -DCMAKE_BUILD_TYPE=Release
# Build library only
cmake --build build
# Build with tests
cmake -B build -DBUILD_TESTING=ON
cmake --build build
# Build with examples
cmake -B build -DBUILD_EXAMPLES=ON
cmake --build build
# Run tests
ctest --test-dir buildcmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build
cmake --install build# Add as subdirectory
add_subdirectory(external/BigXtractor)
# Link against the library
target_link_libraries(mytool PRIVATE bigx::bigx)git submodule add https://github.com/ViTeXFTW/BigXtractor.git external/BigXtractor
git submodule update --init --recursiveThen use Option 1 above.
include(FetchContent)
FetchContent_Declare(
bigx
GIT_REPOSITORY https://github.com/ViTeXFTW/BigXtractor.git
GIT_TAG main
)
FetchContent_MakeAvailable(bigx)
target_link_libraries(mytool PRIVATE bigx::bigx)vcpkg install bigxfind_package(bigx CONFIG REQUIRED)
target_link_libraries(mytool PRIVATE bigx::bigx)#include <bigx/bigx.hpp>
// Open archive
auto archive = bigx::Archive::open("archive.big");
if (!archive) {
std::cerr << "Failed to open archive\n";
return 1;
}
// List all files
for (const auto& file : archive->files()) {
std::cout << file.path << " (" << file.size << " bytes)\n";
}
// Find a file (case-insensitive)
const auto* file = archive->findFile("Data/Texture.tga");
if (file) {
// Extract to disk
archive->extract(*file, "output.tga");
// Or read into memory
auto data = archive->extractToMemory(*file);
if (data) {
// Use data->data(), data->size()
}
}#include <bigx/bigx.hpp>
auto archive = bigx::Archive::create();
// Add files from disk
archive.addFile("source.txt", "data/source.txt");
// Add files from memory
std::vector<uint8_t> data = {0, 1, 2, 3};
archive.addFile(data, "binary/data.bin");
// Write to disk
std::string error;
if (!archive.write("output.big", &error)) {
std::cerr << "Error: " << error << "\n";
}For more control, use the Reader and Writer classes directly:
#include <bigx/reader.hpp>
auto reader = bigx::Reader::open("archive.big");
if (reader) {
// Get zero-copty view of a file
const auto* file = reader->findFile("path/file.txt");
auto view = reader->getFileView(*file);
// view.data() and view.size() give direct access
}Header (16 bytes):
+0x00 char[4] Magic: "BIGF"
+0x04 uint32 Archive size (big-endian, mostly unused)
+0x08 uint32 Number of files (big-endian)
+0x0C uint32 Padding
File Entries (starting at 0x10):
+0x00 uint32 File offset in archive (big-endian)
+0x04 uint32 File size in bytes (big-endian)
+0x08 char[] Null-terminated full path
Contributions are welcome! Please ensure tests pass before submitting a PR