diff --git a/lib/structs/BoltStructs.hpp b/lib/structs/BoltStructs.hpp index 3c3f171..6061bae 100644 --- a/lib/structs/BoltStructs.hpp +++ b/lib/structs/BoltStructs.hpp @@ -48,6 +48,9 @@ namespace lightningbolt { u32 groupSize; u32 groupOffset; + // PS2 pointer padding; bolt library stuffs something here + u32 pad; + u32 EntryCount() { // Special case: 0x0 == 256 entries. // I have NO idea why they did it like this, @@ -58,7 +61,7 @@ namespace lightningbolt { return entryCount; } - std::span Entries(u8* base) { return { std::bit_cast(base + groupOffset), EntryCount() }; } + std::span Entries(u8* base) { return { std::bit_cast(&base[groupOffset]), EntryCount() }; } }; struct [[gnu::packed]] BoltLibraryHeader { diff --git a/src/main.cpp b/src/main.cpp index 3b618a9..1426d58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,18 +1,19 @@ #include #include +#include +#include #include #include -#include - -#include - -struct ParsedTableEntry { - std::string_view filename; - u16 index; - u32 gid; -}; struct BoltReader { + struct ParsedTableEntry { + std::string_view filename; + u16 index; + u16 gid; + + std::span uncompressedData; + }; + BoltReader() {} ErrorOr OpenBolt(const lightningbolt::fs::path& path) { @@ -29,6 +30,7 @@ struct BoltReader { if(auto error = boltFile.Open(path); error.HasError()) return error; + lib = std::bit_cast(boltFile.GetMapping()); return {}; } @@ -47,27 +49,45 @@ struct BoltReader { if(te.filename == "") break; - std::cout << std::format("te: {} {:04x} {:04x}\n", te.filename, te.index, te.gid); + // std::cout << std::format("te: {} {:04x} {:04x}\n", te.filename, te.index, te.gid); entryTable.emplace_back(te); table++; } - - // The ELF file isn't needed after this so unmap it - elfFile.Close(); } return entryTable; } - template + template void ForEachFile(F f) { - //for()() + for(auto& file : entryTable) { + if(file.uncompressedData.empty()) { + auto gid = (file.gid >> 8); + auto entries = lib->GroupDescriptors()[gid].Entries(boltFile.GetMapping()); + + // std::cout << std::format("ptr: {} {:08x}\n", (void*)entries.data(), (u32)(std::bit_cast(entries.data()) - (usize)lib)); + + auto size = entries[file.index & 0x00ff].fileSize; + auto offset = entries[file.index & 0x00ff].fileOffset; + + file.uncompressedData = { std::bit_cast(boltFile.GetMapping() + offset), size }; + + // for(i32 i = 0; i < entries.size(); ++i) { + // std::cout << std::format("dick {}: {:08x}\n", i, entries[i].fileOffset); + // } + } + + if(!f(file)) + break; + } } private: std::vector entryTable; lightningbolt::MmapFile elfFile; lightningbolt::MmapFile boltFile; + + lightningbolt::BoltLibraryHeader* lib; }; int main() { @@ -76,5 +96,11 @@ int main() { std::cout << "Error opening Bolt file: " << error.Error(); } + reader.ForEachFile([](BoltReader::ParsedTableEntry& ent) { + std::cout << std::format("File: {} magic: ", ent.filename) << ent.uncompressedData[0] << ent.uncompressedData[1] << ent.uncompressedData[2] + << ent.uncompressedData[3] << '\n'; + return true; + }); + return 0; }