Skip to content

Instantly share code, notes, and snippets.

@playday3008
Created July 27, 2024 17:07
Show Gist options
  • Select an option

  • Save playday3008/3a3b20d95bb1f31fc289272065c63905 to your computer and use it in GitHub Desktop.

Select an option

Save playday3008/3a3b20d95bb1f31fc289272065c63905 to your computer and use it in GitHub Desktop.
ProfileOptions file pattern using ImHex (FBCHUNKS)
#include <type/magic.pat>
#include <std/io.pat>
#include <std/hash.pat>
#include <std/sys.pat>
#include <std/mem.pat>
#pragma loop_limit 131072
#define CRC32POLY_ZIP 0xEDB88320
/// ======= CRC32 =======
fn byte_lookup_uint32_lsb_first(u32 poly) {
std::mem::Section lookup_crc32_zip = std::mem::create_section("lookup_crc32_zip");
std::mem::set_section_size(lookup_crc32_zip, 0x100);
u32 lookup[0x100] @ 0x00 in lookup_crc32_zip;
for (u32 b = 0, b < 256, b = b + 1) {
u32 x = b;
for (u32 i = 0, i < 8, i = i + 1) {
x = (x >> 1) ^ ((x & 1) == 0 ? 0 : poly);
}
lookup[b] = x;
}
return lookup_crc32_zip;
};
std::mem::Section lookup_crc32_zip = byte_lookup_uint32_lsb_first(CRC32POLY_ZIP);
fn crc32_lsb_first(u32 addr, u32 size, u32 crc, std::mem::Section lookup_crc32_zip) {
u32 lookup[0x100] @ 0x00 in lookup_crc32_zip;
str data = std::mem::read_string(addr, size);
for (u32 i = 0, i < size, i = i + 1) {
u8 b = u8(data[i]);
crc = (crc >> 8) ^ lookup[u8(crc) ^ b];
}
return crc;
};
fn crc32_zip(u32 addr, u32 size, u32 crc = 0) {
return ~crc32_lsb_first(addr, size, ~crc, lookup_crc32_zip);
};
fn fb_crc32(str name, u32 expected, u32 address, u32 size) {
str pattern = std::mem::read_string(address, size);
u32 checksum = crc32_zip(address, size, 0x12345678);
std::assert_warn(
checksum == expected,
std::format("{:} expected checksum 0x{:08X}, actual 0x{:08X}", name, expected, checksum)
);
};
/// ======= Data =======
enum DataType : u32 {
Int = 0x1,
Float = 0x2,
};
struct Setting {
DataType type;
u32 name_size;
char name[name_size];
u32 value_size;
char value[value_size];
std::assert_warn(
type == DataType::Int
|| type == DataType::Float,
std::format("DataType is {:d} ({:}) at address 0x{:X}", u32(type), type, addressof(type))
);
};
struct Group {
u32 count;
Setting settings[count];
};
struct Header {
u32 checksum;
u32 group_count;
fb_crc32("Header", checksum, addressof(this) + sizeof(checksum), sizeof(this) - sizeof(checksum));
};
u32 data_total_size;
u32 data_groups_count;
struct Data {
u32 checksum;
Group groups[data_groups_count];
padding[data_total_size - sizeof(this)];
fb_crc32(std::format("Data<{}>", data_groups_count), checksum, addressof(this) + sizeof(checksum), sizeof(this) - sizeof(checksum));
};
struct ProfileOptions {
type::Magic<"FBCHUNKS"> magic;
u16 version;
u32 header_size;
u32 data_size;
Header header;
std::assert_warn(
sizeof(header) == header_size,
std::format("Header size mismatch, actual {} expected {}", sizeof(header), header_size)
);
data_total_size = data_size;
data_groups_count = header.group_count;
Data data;
std::assert_warn(
sizeof(data) == data_size,
std::format("Data size mismatch, actual {} expected {}", sizeof(data), data_size)
);
};
ProfileOptions profile_options @ 0x0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment