mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-11-06 17:01:58 +00:00
fix: zone pointer offset bit count may be independent from platform pointer size
This commit is contained in:
29 files changed
+171
-74
No files matched your search
@@ -208,7 +208,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -376,7 +376,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -277,7 +277,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -82,7 +82,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -85,7 +85,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -91,7 +91,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -348,7 +348,8 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_OFFSET_BIT_COUNT,
|
||||
ZoneConstants::ZONE_POINTER_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr,
|
||||
std::move(progressCallback)));
|
||||
|
||||
@@ -9,13 +9,15 @@ namespace
|
||||
public:
|
||||
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
const unsigned zonePointerOffsetBitCount,
|
||||
const unsigned zonePointerBlockBitCount,
|
||||
const block_t insertBlock,
|
||||
Zone* zone,
|
||||
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
|
||||
: m_entry_point_factory(std::move(entryPointFactory)),
|
||||
m_pointer_bit_count(pointerBitCount),
|
||||
m_offset_block_bit_count(offsetBlockBitCount),
|
||||
m_zone_pointer_offset_bit_count(zonePointerOffsetBitCount),
|
||||
m_zone_pointer_block_bit_count(zonePointerBlockBitCount),
|
||||
m_insert_block(insertBlock),
|
||||
m_zone(zone),
|
||||
m_progress_callback(std::move(progressCallback))
|
||||
@@ -31,8 +33,14 @@ namespace
|
||||
for (size_t i = 0; i < blockCount; ++i)
|
||||
m_blocks.emplace_back(zoneMemory.GetBlock(i));
|
||||
|
||||
const auto inputStream = ZoneInputStream::Create(
|
||||
m_pointer_bit_count, m_offset_block_bit_count, m_blocks, m_insert_block, stream, m_zone->Memory(), std::move(m_progress_callback));
|
||||
const auto inputStream = ZoneInputStream::Create(m_pointer_bit_count,
|
||||
m_zone_pointer_offset_bit_count,
|
||||
m_zone_pointer_block_bit_count,
|
||||
m_blocks,
|
||||
m_insert_block,
|
||||
stream,
|
||||
m_zone->Memory(),
|
||||
std::move(m_progress_callback));
|
||||
|
||||
const auto entryPoint = m_entry_point_factory(*inputStream);
|
||||
assert(entryPoint);
|
||||
@@ -43,7 +51,8 @@ namespace
|
||||
private:
|
||||
std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> m_entry_point_factory;
|
||||
unsigned m_pointer_bit_count;
|
||||
unsigned m_offset_block_bit_count;
|
||||
unsigned m_zone_pointer_offset_bit_count;
|
||||
unsigned m_zone_pointer_block_bit_count;
|
||||
block_t m_insert_block;
|
||||
Zone* m_zone;
|
||||
std::vector<XBlock*> m_blocks;
|
||||
@@ -55,12 +64,13 @@ namespace step
|
||||
{
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
const unsigned zonePointerOffsetBitCount,
|
||||
const unsigned zonePointerBlockBitCount,
|
||||
const block_t insertBlock,
|
||||
Zone* zone,
|
||||
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
|
||||
{
|
||||
return std::make_unique<StepLoadZoneContent>(
|
||||
std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, zone, std::move(progressCallback));
|
||||
std::move(entryPointFactory), pointerBitCount, zonePointerOffsetBitCount, zonePointerBlockBitCount, insertBlock, zone, std::move(progressCallback));
|
||||
}
|
||||
} // namespace step
|
||||
@@ -11,7 +11,8 @@ namespace step
|
||||
{
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
unsigned pointerBitCount,
|
||||
unsigned offsetBlockBitCount,
|
||||
unsigned zonePointerOffsetBitCount,
|
||||
unsigned zonePointerBlockBitCount,
|
||||
block_t insertBlock,
|
||||
Zone* zone,
|
||||
std::optional<std::unique_ptr<ProgressCallback>> progressCallback);
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace
|
||||
{
|
||||
public:
|
||||
XBlockInputStream(const unsigned pointerBitCount,
|
||||
const unsigned blockBitCount,
|
||||
const unsigned zonePointerOffsetBitCount,
|
||||
const unsigned zonePointerBlockBitCount,
|
||||
std::vector<XBlock*>& blocks,
|
||||
const block_t insertBlock,
|
||||
ILoadingStream& stream,
|
||||
@@ -57,15 +58,17 @@ namespace
|
||||
m_stream(stream),
|
||||
m_memory(memory),
|
||||
m_pointer_byte_count(pointerBitCount / 8u),
|
||||
m_block_mask((std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - blockBitCount)) << (pointerBitCount - blockBitCount)),
|
||||
m_block_shift(pointerBitCount - blockBitCount),
|
||||
m_offset_mask(std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - (pointerBitCount - blockBitCount))),
|
||||
m_zone_pointer_block_mask((std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerBlockBitCount))
|
||||
<< zonePointerOffsetBitCount),
|
||||
m_zone_pointer_block_shift(zonePointerOffsetBitCount),
|
||||
m_zone_pointer_offset_mask(std::numeric_limits<uintptr_t>::max() >> (sizeof(uintptr_t) * 8 - zonePointerOffsetBitCount)),
|
||||
m_last_fill_size(0),
|
||||
m_has_progress_callback(false),
|
||||
m_progress_current_size(0uz),
|
||||
m_progress_total_size(0uz)
|
||||
{
|
||||
assert(pointerBitCount % 8u == 0u);
|
||||
assert(zonePointerOffsetBitCount + zonePointerBlockBitCount <= pointerBitCount);
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
|
||||
std::memset(m_block_offsets.data(), 0, sizeof(decltype(m_block_offsets)::value_type) * m_block_offsets.size());
|
||||
@@ -292,7 +295,7 @@ namespace
|
||||
|
||||
const auto blockNum = m_insert_block->m_index;
|
||||
const auto blockOffset = static_cast<uintptr_t>(m_block_offsets[m_insert_block->m_index]);
|
||||
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_block_shift) | (blockOffset & m_offset_mask);
|
||||
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_zone_pointer_block_shift) | (blockOffset & m_zone_pointer_offset_mask);
|
||||
|
||||
IncBlockPos(*m_insert_block, m_pointer_byte_count);
|
||||
|
||||
@@ -301,7 +304,7 @@ namespace
|
||||
|
||||
void SetInsertedPointerAliasLookup(const uintptr_t zonePtr, void* value) override
|
||||
{
|
||||
assert((static_cast<block_t>((zonePtr & m_block_mask) >> m_block_shift)) < m_blocks.size());
|
||||
assert((static_cast<block_t>((zonePtr & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift)) < m_blocks.size());
|
||||
m_alias_redirect_lookup.emplace(zonePtr, value);
|
||||
}
|
||||
|
||||
@@ -311,8 +314,8 @@ namespace
|
||||
// So all offsets are moved by 1.
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@@ -330,8 +333,8 @@ namespace
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@@ -356,7 +359,7 @@ namespace
|
||||
|
||||
const auto blockNum = block->m_index;
|
||||
const auto blockOffset = static_cast<uintptr_t>(static_cast<const uint8_t*>(blockPtr) - block->m_buffer.get());
|
||||
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_block_shift) | (blockOffset & m_offset_mask);
|
||||
const auto zonePtr = (static_cast<uintptr_t>(blockNum) << m_zone_pointer_block_shift) | (blockOffset & m_zone_pointer_offset_mask);
|
||||
m_pointer_redirect_lookup.emplace(zonePtr, alias);
|
||||
}
|
||||
|
||||
@@ -365,8 +368,8 @@ namespace
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@@ -388,8 +391,8 @@ namespace
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_block_mask) >> m_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_offset_mask);
|
||||
const auto blockNum = static_cast<block_t>((offsetInt & m_zone_pointer_block_mask) >> m_zone_pointer_block_shift);
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & m_zone_pointer_offset_mask);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@@ -496,9 +499,9 @@ namespace
|
||||
MemoryManager& m_memory;
|
||||
|
||||
unsigned m_pointer_byte_count;
|
||||
uintptr_t m_block_mask;
|
||||
unsigned m_block_shift;
|
||||
uintptr_t m_offset_mask;
|
||||
uintptr_t m_zone_pointer_block_mask;
|
||||
unsigned m_zone_pointer_block_shift;
|
||||
uintptr_t m_zone_pointer_offset_mask;
|
||||
XBlock* m_insert_block;
|
||||
|
||||
std::vector<uint8_t> m_fill_buffer;
|
||||
@@ -515,12 +518,14 @@ namespace
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(const unsigned pointerBitCount,
|
||||
const unsigned blockBitCount,
|
||||
const unsigned zonePointerOffsetBitCount,
|
||||
const unsigned zonePointerBlockBitCount,
|
||||
std::vector<XBlock*>& blocks,
|
||||
const block_t insertBlock,
|
||||
ILoadingStream& stream,
|
||||
MemoryManager& memory,
|
||||
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
|
||||
{
|
||||
return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory, std::move(progressCallback));
|
||||
return std::make_unique<XBlockInputStream>(
|
||||
pointerBitCount, zonePointerOffsetBitCount, zonePointerBlockBitCount, blocks, insertBlock, stream, memory, std::move(progressCallback));
|
||||
}
|
||||
@@ -240,8 +240,21 @@ public:
|
||||
virtual void DebugOffsets(size_t assetIndex) const = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Creates a new ZoneInputStream with given parameters.
|
||||
* \param pointerBitCount The bit count of a pointer of the platform the zone data comes from.
|
||||
* \param zonePointerBlockBitCount The bit count of the offset in a zone pointer. offsetBitCount + blockBitCount <= pointerBitCount
|
||||
* \param zonePointerOffsetBitCount The bitcount of a block index in a zone pointer. offsetBitCount + blockBitCount <= pointerBitCount
|
||||
* \param blocks The blocks of the zone.
|
||||
* \param insertBlock The block index that is used when inserting a pointer. Should be the default normal block.
|
||||
* \param stream The stream to load data from.
|
||||
* \param memory The memory manager to use for allocating new memory.
|
||||
* \param progressCallback An optional callback to call on progress.
|
||||
* \return
|
||||
*/
|
||||
static std::unique_ptr<ZoneInputStream> Create(unsigned pointerBitCount,
|
||||
unsigned blockBitCount,
|
||||
unsigned zonePointerOffsetBitCount,
|
||||
unsigned zonePointerBlockBitCount,
|
||||
std::vector<XBlock*>& blocks,
|
||||
block_t insertBlock,
|
||||
ILoadingStream& stream,
|
||||
|
||||
Reference in new issue
Block a user