2022-09-04 17:11:14 -04:00
|
|
|
//
|
|
|
|
// EuropaTools
|
|
|
|
//
|
|
|
|
// (C) 2021-2022 modeco80 <lily.modeco80@protonmail.ch>
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef EUROPA_STRUCTS_PAK_H
|
|
|
|
#define EUROPA_STRUCTS_PAK_H
|
|
|
|
|
|
|
|
#include <europa/structs/ImHexAdapter.h>
|
|
|
|
|
2022-09-05 20:59:46 -04:00
|
|
|
#include <cstdint>
|
|
|
|
#include <cstring>
|
|
|
|
|
2022-09-04 17:11:14 -04:00
|
|
|
namespace europa::structs {
|
|
|
|
|
2022-09-05 20:59:46 -04:00
|
|
|
struct [[gnu::packed]] PakHeader {
|
2022-09-04 17:11:14 -04:00
|
|
|
constexpr static const char VALID_MAGIC[16] = "Europa Packfile";
|
|
|
|
|
2022-09-21 03:31:33 -04:00
|
|
|
enum class Version : u16 {
|
|
|
|
Ver4 = 0x4,
|
|
|
|
Ver5 = 0x5
|
|
|
|
};
|
|
|
|
|
2022-09-04 17:11:14 -04:00
|
|
|
char magic[16]; // "Europa Packfile\0"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Header size. Doesn't include the magic.
|
|
|
|
*/
|
|
|
|
u16 headerSize;
|
|
|
|
|
2022-09-21 03:31:33 -04:00
|
|
|
Version version;
|
2022-09-04 17:11:14 -04:00
|
|
|
u8 pad;
|
|
|
|
|
|
|
|
u32 tocOffset;
|
|
|
|
|
2022-09-15 05:11:53 -04:00
|
|
|
u32 tocSize;
|
2022-09-04 17:11:14 -04:00
|
|
|
|
|
|
|
u32 fileCount;
|
|
|
|
|
2022-09-15 05:11:53 -04:00
|
|
|
u32 creationUnixTime;
|
2022-09-04 17:11:14 -04:00
|
|
|
|
2022-09-21 03:31:33 -04:00
|
|
|
// Zeroes.
|
2022-09-04 17:11:14 -04:00
|
|
|
u32 reservedPad;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the real header size (including the magic).
|
|
|
|
*/
|
|
|
|
[[nodiscard]] constexpr std::size_t RealHeaderSize() const {
|
|
|
|
return sizeof(magic) + static_cast<std::size_t>(headerSize);
|
|
|
|
}
|
2022-09-05 20:59:46 -04:00
|
|
|
|
2022-09-07 05:07:40 -04:00
|
|
|
/**
|
|
|
|
* Initialize this header (used when writing).
|
|
|
|
*/
|
2022-09-21 03:31:33 -04:00
|
|
|
void Init(Version ver) noexcept {
|
2022-09-07 05:07:40 -04:00
|
|
|
// clear any junk
|
|
|
|
memset(this, 0, sizeof(PakHeader));
|
|
|
|
|
|
|
|
// Copy important things.
|
|
|
|
std::memcpy(&magic[0], &VALID_MAGIC[0], sizeof(VALID_MAGIC));
|
|
|
|
|
|
|
|
// Set proper header size.
|
|
|
|
headerSize = sizeof(PakHeader) - (sizeof(PakHeader::VALID_MAGIC) - 1);
|
|
|
|
|
|
|
|
// Set archive version
|
|
|
|
version = ver;
|
|
|
|
}
|
|
|
|
|
|
|
|
[[nodiscard]] bool Valid() const noexcept {
|
|
|
|
// Magic must match.
|
|
|
|
if(std::strcmp(magic, VALID_MAGIC) != 0)
|
|
|
|
return false;
|
|
|
|
|
2022-09-21 03:31:33 -04:00
|
|
|
// Check header size.
|
|
|
|
if(headerSize != sizeof(PakHeader) - (sizeof(PakHeader::VALID_MAGIC) - 1))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
using enum Version;
|
2022-09-05 20:59:46 -04:00
|
|
|
|
2022-09-07 05:07:40 -04:00
|
|
|
// Version must match ones we support,
|
|
|
|
// otherwise it's invalid.
|
|
|
|
switch(version) {
|
2022-09-21 03:31:33 -04:00
|
|
|
case Ver4:
|
|
|
|
case Ver5:
|
|
|
|
return true;
|
2022-09-05 20:59:46 -04:00
|
|
|
|
2022-09-07 05:07:40 -04:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2022-09-04 17:11:14 -04:00
|
|
|
};
|
|
|
|
|
2022-09-07 05:07:40 -04:00
|
|
|
// A Toc entry (without string. Needs to be read in separately)
|
2022-09-04 17:11:14 -04:00
|
|
|
struct [[gnu::packed]] PakTocEntry {
|
|
|
|
u32 offset;
|
|
|
|
u32 size;
|
2022-09-15 05:11:53 -04:00
|
|
|
u32 creationUnixTime;
|
2022-09-04 17:11:14 -04:00
|
|
|
};
|
|
|
|
|
2022-09-21 03:31:33 -04:00
|
|
|
|
2022-09-07 05:07:40 -04:00
|
|
|
static_assert(sizeof(PakHeader) == 0x29, "PakHeader wrong size!!");
|
|
|
|
static_assert(sizeof(PakHeader) - (sizeof(PakHeader::VALID_MAGIC) - 1) == 0x1a, "PakHeader::headerSize will be invalid when writing archives.");
|
2022-09-04 17:11:14 -04:00
|
|
|
static_assert(sizeof(PakTocEntry) == 0xc, "PakTocEntry wrong size!");
|
|
|
|
|
2022-09-05 20:59:46 -04:00
|
|
|
} // namespace europa::structs
|
2022-09-04 17:11:14 -04:00
|
|
|
|
|
|
|
#endif // EUROPA_STRUCTS_PAK_H
|