mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-01-24 17:03:05 +00:00
refactor: implement base x64 fastfile loading for iw4
This commit is contained in:
@@ -1,15 +1,22 @@
|
||||
#include "ContentLoaderBase.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
||||
const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast<void*>(-2);
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
|
||||
: varXString(nullptr),
|
||||
m_zone(zone),
|
||||
m_memory(zone.Memory()),
|
||||
m_stream(stream)
|
||||
m_stream(stream),
|
||||
|
||||
// -1
|
||||
m_zone_ptr_following(
|
||||
reinterpret_cast<const void*>(std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount()))),
|
||||
|
||||
// -2
|
||||
m_zone_ptr_insert(
|
||||
reinterpret_cast<const void*>((std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount())) - 1u))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,9 +29,9 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const
|
||||
|
||||
if (*varXString != nullptr)
|
||||
{
|
||||
if (*varXString == PTR_FOLLOWING)
|
||||
if (GetZonePointerType(*varXString) == ZonePointerType::FOLLOWING)
|
||||
{
|
||||
*varXString = m_stream.Alloc<const char>(alignof(const char));
|
||||
*varXString = m_stream.Alloc<const char>(1);
|
||||
m_stream.LoadNullTerminated(const_cast<char*>(*varXString));
|
||||
}
|
||||
else
|
||||
@@ -39,7 +46,12 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
|
||||
assert(varXString != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream.Load<const char*>(varXString, count);
|
||||
{
|
||||
const auto fill = m_stream.LoadWithFill(4u * count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
fill.FillPtr(varXString[index], 4u * index);
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@@ -47,3 +59,13 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
|
||||
varXString++;
|
||||
}
|
||||
}
|
||||
|
||||
ZonePointerType ContentLoaderBase::GetZonePointerType(const void* zonePtr) const
|
||||
{
|
||||
if (zonePtr == m_zone_ptr_following)
|
||||
return ZonePointerType::FOLLOWING;
|
||||
if (zonePtr == m_zone_ptr_insert)
|
||||
return ZonePointerType::INSERT;
|
||||
|
||||
return ZonePointerType::OFFSET;
|
||||
}
|
||||
|
||||
@@ -3,12 +3,17 @@
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
#include "Zone/Zone.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class ZonePointerType : std::uint8_t
|
||||
{
|
||||
FOLLOWING,
|
||||
INSERT,
|
||||
OFFSET
|
||||
};
|
||||
|
||||
class ContentLoaderBase
|
||||
{
|
||||
protected:
|
||||
static const void* PTR_FOLLOWING;
|
||||
static const void* PTR_INSERT;
|
||||
|
||||
public:
|
||||
virtual ~ContentLoaderBase() = default;
|
||||
ContentLoaderBase(const ContentLoaderBase& other) = default;
|
||||
@@ -22,9 +27,20 @@ protected:
|
||||
void LoadXString(bool atStreamStart) const;
|
||||
void LoadXStringArray(bool atStreamStart, size_t count);
|
||||
|
||||
[[nodiscard]] ZonePointerType GetZonePointerType(const void* zonePtr) const;
|
||||
|
||||
template<typename T> [[nodiscard]] ZonePointerType GetZonePointerType(T* zonePtr) const
|
||||
{
|
||||
return GetZonePointerType(reinterpret_cast<const void*>(zonePtr));
|
||||
}
|
||||
|
||||
const char** varXString;
|
||||
|
||||
Zone& m_zone;
|
||||
MemoryManager& m_memory;
|
||||
ZoneInputStream& m_stream;
|
||||
|
||||
private:
|
||||
const void* m_zone_ptr_following;
|
||||
const void* m_zone_ptr_insert;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "InvalidAliasLookupException.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
InvalidAliasLookupException::InvalidAliasLookupException(const size_t lookupIndex, const size_t lookupCount)
|
||||
: m_lookup_index(lookupIndex),
|
||||
m_lookup_count(lookupCount)
|
||||
{
|
||||
}
|
||||
|
||||
std::string InvalidAliasLookupException::DetailedMessage()
|
||||
{
|
||||
return std::format("Tried to resolve zone alias lookup {} when there are only {} entries in the lookup", m_lookup_index, m_lookup_count);
|
||||
}
|
||||
|
||||
char const* InvalidAliasLookupException::what() const noexcept
|
||||
{
|
||||
return "Tried to resolve invalid zone alias lookup";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "LoadingException.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
class InvalidAliasLookupException final : public LoadingException
|
||||
{
|
||||
public:
|
||||
InvalidAliasLookupException(size_t lookupIndex, size_t lookupCount);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
[[nodiscard]] char const* what() const noexcept override;
|
||||
|
||||
private:
|
||||
size_t m_lookup_index;
|
||||
size_t m_lookup_count;
|
||||
};
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr uint64_t MAX_XBLOCK_SIZE = 0x3C000000;
|
||||
constexpr uint64_t MAX_XBLOCK_SIZE = 0x3C000000; // ~1GB
|
||||
|
||||
class StepAllocXBlocks final : public ILoadingStep
|
||||
{
|
||||
|
||||
@@ -10,17 +10,20 @@ namespace
|
||||
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
const block_t insertBlock)
|
||||
const block_t insertBlock,
|
||||
MemoryManager& memory)
|
||||
: m_entry_point_factory(std::move(entryPointFactory)),
|
||||
m_pointer_bit_count(pointerBitCount),
|
||||
m_offset_block_bit_count(offsetBlockBitCount),
|
||||
m_insert_block(insertBlock)
|
||||
m_insert_block(insertBlock),
|
||||
m_memory(memory)
|
||||
{
|
||||
}
|
||||
|
||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
|
||||
{
|
||||
const auto inputStream = ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream);
|
||||
const auto inputStream =
|
||||
ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory);
|
||||
|
||||
const auto entryPoint = m_entry_point_factory(*inputStream);
|
||||
assert(entryPoint);
|
||||
@@ -33,6 +36,7 @@ namespace
|
||||
unsigned m_pointer_bit_count;
|
||||
unsigned m_offset_block_bit_count;
|
||||
block_t m_insert_block;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@@ -41,8 +45,9 @@ namespace step
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
const block_t insertBlock)
|
||||
const block_t insertBlock,
|
||||
MemoryManager& memory)
|
||||
{
|
||||
return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock);
|
||||
return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory);
|
||||
}
|
||||
} // namespace step
|
||||
|
||||
@@ -12,5 +12,6 @@ namespace step
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
unsigned pointerBitCount,
|
||||
unsigned offsetBlockBitCount,
|
||||
block_t insertBlock);
|
||||
block_t insertBlock,
|
||||
MemoryManager& memory);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user