mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 10:19:47 -04:00
49 lines
2.1 KiB
C++
49 lines
2.1 KiB
C++
#pragma once
|
|
// Neversoft's HED format: NUL-terminated name, word padding, offset/size,
|
|
// terminated by 0xff. Only the archive format is shared; title lookup and
|
|
// request/completion contracts remain with the game.
|
|
#include <cstdint>
|
|
#include <unordered_map>
|
|
|
|
class PSXNamedWadIndex {
|
|
std::unordered_map<uint32_t, uint32_t> extents;
|
|
static uint32_t word(const uint8_t* p) {
|
|
return uint32_t(p[0]) | uint32_t(p[1]) << 8 |
|
|
uint32_t(p[2]) << 16 | uint32_t(p[3]) << 24;
|
|
}
|
|
public:
|
|
bool assign(const uint8_t* hed, uint32_t size, uint32_t wad_size) {
|
|
extents.clear();
|
|
if (!hed) return false;
|
|
uint32_t cursor = 0;
|
|
while (cursor < size && hed[cursor] != 0xff) {
|
|
uint32_t end = cursor;
|
|
while (end < size && hed[end]) ++end;
|
|
if (end == size || end == cursor) { extents.clear(); return false; }
|
|
const uint64_t fields = (uint64_t(end) + 4) & ~uint64_t(3);
|
|
if (fields > size || size - fields < 8) { extents.clear(); return false; }
|
|
const uint32_t offset = word(hed + fields), bytes = word(hed + fields + 4);
|
|
const uint64_t padded = (uint64_t(bytes) + 2047) & ~uint64_t(2047);
|
|
if ((offset & 2047) || offset > wad_size || padded > wad_size - offset) {
|
|
extents.clear(); return false;
|
|
}
|
|
const auto found = extents.find(offset);
|
|
if (found != extents.end() && found->second != bytes) {
|
|
extents.clear(); return false;
|
|
}
|
|
extents[offset] = bytes;
|
|
cursor = uint32_t(fields + 8);
|
|
}
|
|
if (cursor >= size || hed[cursor] != 0xff || extents.empty()) {
|
|
extents.clear(); return false;
|
|
}
|
|
return true;
|
|
}
|
|
bool matches(uint32_t offset, uint32_t padded_bytes, uint32_t sectors) const {
|
|
const auto found = extents.find(offset);
|
|
return found != extents.end() && padded_bytes != 0 &&
|
|
uint64_t(padded_bytes) == ((uint64_t(found->second) + 2047) & ~uint64_t(2047)) &&
|
|
sectors == padded_bytes / 2048;
|
|
}
|
|
};
|