mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-20 19:35:41 +00:00
Merge pull request #445 from Laupetin/feature/x64-zcg-loading
refactor: load iw4 x86 fastfiles in x64 environment
This commit is contained in:
commit
45cb454d63
@ -132,11 +132,52 @@ namespace IW3
|
||||
};
|
||||
|
||||
typedef char cbrushedge_t;
|
||||
typedef float vec2_t[2];
|
||||
typedef float vec3_t[3];
|
||||
typedef float vec4_t[4];
|
||||
typedef tdef_align32(128) unsigned int raw_uint128;
|
||||
|
||||
union vec2_t
|
||||
{
|
||||
float v[2];
|
||||
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
};
|
||||
|
||||
union vec3_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
float v[3];
|
||||
};
|
||||
|
||||
union vec4_t
|
||||
{
|
||||
float v[4];
|
||||
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
};
|
||||
|
||||
struct XModelPiece
|
||||
{
|
||||
XModel* model;
|
||||
@ -214,7 +255,10 @@ namespace IW3
|
||||
XAnimPartTransData u;
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat[2];
|
||||
struct type_align(4) XQuat
|
||||
{
|
||||
int16_t value[4];
|
||||
};
|
||||
|
||||
union XAnimDynamicIndicesQuat
|
||||
{
|
||||
@ -231,7 +275,7 @@ namespace IW3
|
||||
union XAnimDeltaPartQuatData
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames frames;
|
||||
int16_t frame0[2];
|
||||
XQuat frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat
|
||||
|
@ -161,9 +161,50 @@ namespace IW4
|
||||
typedef tdef_align32(128) unsigned int raw_uint128;
|
||||
typedef unsigned char cbrushedge_t;
|
||||
typedef unsigned short r_index_t;
|
||||
typedef float vec2_t[2];
|
||||
typedef float vec3_t[3];
|
||||
typedef float vec4_t[4];
|
||||
|
||||
union vec2_t
|
||||
{
|
||||
float v[2];
|
||||
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
};
|
||||
|
||||
union vec3_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
float v[3];
|
||||
};
|
||||
|
||||
union vec4_t
|
||||
{
|
||||
float v[4];
|
||||
|
||||
struct
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float w;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
};
|
||||
};
|
||||
|
||||
struct PhysPreset
|
||||
{
|
||||
@ -330,7 +371,10 @@ namespace IW4
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat2[2];
|
||||
struct type_align(4) XQuat2
|
||||
{
|
||||
int16_t value[2];
|
||||
};
|
||||
|
||||
struct type_align32(4) XAnimDeltaPartQuatDataFrames2
|
||||
{
|
||||
@ -341,7 +385,7 @@ namespace IW4
|
||||
union XAnimDeltaPartQuatData2
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames2 frames;
|
||||
int16_t frame0[2];
|
||||
XQuat2 frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat2
|
||||
@ -356,7 +400,10 @@ namespace IW4
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat[4];
|
||||
struct type_align(4) XQuat
|
||||
{
|
||||
int16_t value[4];
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuatDataFrames
|
||||
{
|
||||
@ -367,7 +414,7 @@ namespace IW4
|
||||
union XAnimDeltaPartQuatData
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames frames;
|
||||
int16_t frame0[4];
|
||||
XQuat frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat
|
||||
|
@ -379,7 +379,10 @@ namespace IW5
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat2[2];
|
||||
struct type_align(4) XQuat2
|
||||
{
|
||||
int16_t value[2];
|
||||
};
|
||||
|
||||
struct type_align32(4) XAnimDeltaPartQuatDataFrames2
|
||||
{
|
||||
@ -390,7 +393,7 @@ namespace IW5
|
||||
union XAnimDeltaPartQuatData2
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames2 frames;
|
||||
short frame0[2];
|
||||
XQuat2 frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat2
|
||||
@ -405,7 +408,10 @@ namespace IW5
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat[4];
|
||||
struct type_align(4) XQuat
|
||||
{
|
||||
int16_t value[4];
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuatDataFrames
|
||||
{
|
||||
@ -416,7 +422,7 @@ namespace IW5
|
||||
union XAnimDeltaPartQuatData
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames frames;
|
||||
short frame0[4];
|
||||
XQuat frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat
|
||||
|
@ -385,7 +385,10 @@ namespace T5
|
||||
XAnimPartTransData u;
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) short XQuat[2];
|
||||
struct type_align(4) XQuat
|
||||
{
|
||||
int16_t value[4];
|
||||
};
|
||||
|
||||
union XAnimDynamicIndicesQuat
|
||||
{
|
||||
@ -402,7 +405,7 @@ namespace T5
|
||||
union XAnimDeltaPartQuatData
|
||||
{
|
||||
XAnimDeltaPartQuatDataFrames frames;
|
||||
int16_t frame0[2];
|
||||
XQuat frame0;
|
||||
};
|
||||
|
||||
struct XAnimDeltaPartQuat
|
||||
|
@ -5650,7 +5650,10 @@ namespace T6
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) int16_t XQuat2[2];
|
||||
struct type_align(4) XQuat2
|
||||
{
|
||||
int16_t value[2];
|
||||
};
|
||||
|
||||
struct type_align32(4) XAnimDeltaPartQuatDataFrames2
|
||||
{
|
||||
@ -5676,7 +5679,10 @@ namespace T6
|
||||
uint16_t _2[1];
|
||||
};
|
||||
|
||||
typedef tdef_align32(4) int16_t XQuat[4];
|
||||
struct type_align(4) XQuat
|
||||
{
|
||||
int16_t value[4];
|
||||
};
|
||||
|
||||
struct type_align32(4) XAnimDeltaPartQuatDataFrames
|
||||
{
|
||||
|
@ -382,8 +382,8 @@ namespace
|
||||
for (auto i = 0u; i < originalGraphKnotCount; i++)
|
||||
{
|
||||
const auto& commonKnot = graph.knots[i];
|
||||
originalGraphKnots[i][0] = static_cast<float>(commonKnot.x);
|
||||
originalGraphKnots[i][1] = static_cast<float>(commonKnot.y);
|
||||
originalGraphKnots[i].x = static_cast<float>(commonKnot.x);
|
||||
originalGraphKnots[i].y = static_cast<float>(commonKnot.y);
|
||||
}
|
||||
|
||||
graphKnots = originalGraphKnots;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "AssetDumperLoadedSound.h"
|
||||
|
||||
#include "Sound/WavTypes.h"
|
||||
#include "Sound/WavWriter.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
using namespace IW3;
|
||||
|
||||
@ -9,37 +12,22 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream)
|
||||
void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
|
||||
{
|
||||
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm)
|
||||
+ sizeof(WavChunkHeader) + sizeof(asset->sound.info.data_len);
|
||||
const WavWriter writer(stream);
|
||||
|
||||
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
|
||||
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
|
||||
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
|
||||
const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
|
||||
.samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
|
||||
.bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
|
||||
|
||||
const WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)};
|
||||
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
|
||||
|
||||
WavFormatChunkPcm formatChunk{
|
||||
WavFormat::PCM,
|
||||
static_cast<uint16_t>(asset->sound.info.channels),
|
||||
asset->sound.info.rate,
|
||||
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
|
||||
static_cast<uint16_t>(asset->sound.info.block_size),
|
||||
static_cast<uint16_t>(asset->sound.info.bits),
|
||||
};
|
||||
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
|
||||
|
||||
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, asset->sound.info.data_len};
|
||||
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
|
||||
stream.write(asset->sound.data, asset->sound.info.data_len);
|
||||
writer.WritePcmHeader(metaData, asset->sound.info.data_len);
|
||||
writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
|
||||
}
|
||||
|
||||
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
|
||||
{
|
||||
const auto* loadedSound = asset->Asset();
|
||||
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name);
|
||||
const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
|
||||
|
||||
if (!assetFile)
|
||||
return;
|
||||
@ -48,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
|
||||
switch (static_cast<WavFormat>(loadedSound->sound.info.format))
|
||||
{
|
||||
case WavFormat::PCM:
|
||||
DumpWavPcm(context, loadedSound, stream);
|
||||
DumpWavPcm(loadedSound, stream);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ namespace IW3
|
||||
{
|
||||
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
|
||||
{
|
||||
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream);
|
||||
static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
|
||||
|
||||
protected:
|
||||
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "Sound/WavTypes.h"
|
||||
#include "Sound/WavWriter.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
|
||||
@ -10,12 +12,13 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream)
|
||||
void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
|
||||
{
|
||||
const WavWriter writer(stream);
|
||||
|
||||
const WavMetaData metaData{
|
||||
static_cast<unsigned>(asset->sound.info.channels), static_cast<unsigned>(asset->sound.info.rate), static_cast<unsigned>(asset->sound.info.bits)};
|
||||
const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
|
||||
.samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
|
||||
.bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
|
||||
|
||||
writer.WritePcmHeader(metaData, asset->sound.info.data_len);
|
||||
writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
|
||||
@ -24,7 +27,7 @@ void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const Load
|
||||
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
|
||||
{
|
||||
const auto* loadedSound = asset->Asset();
|
||||
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name);
|
||||
const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
|
||||
|
||||
if (!assetFile)
|
||||
return;
|
||||
@ -33,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
|
||||
switch (static_cast<WavFormat>(loadedSound->sound.info.format))
|
||||
{
|
||||
case WavFormat::PCM:
|
||||
DumpWavPcm(context, loadedSound, stream);
|
||||
DumpWavPcm(loadedSound, stream);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ namespace IW4
|
||||
{
|
||||
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
|
||||
{
|
||||
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream);
|
||||
static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
|
||||
|
||||
protected:
|
||||
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;
|
||||
|
@ -231,8 +231,8 @@ namespace IW4
|
||||
for (auto i = 0u; i < originalKnotCount; i++)
|
||||
{
|
||||
auto& knot = graph.knots[i];
|
||||
knot.x = originalKnots[i][0];
|
||||
knot.y = originalKnots[i][1];
|
||||
knot.x = originalKnots[i].x;
|
||||
knot.y = originalKnots[i].y;
|
||||
}
|
||||
|
||||
return graph;
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "AssetDumperLoadedSound.h"
|
||||
|
||||
#include "Sound/WavTypes.h"
|
||||
#include "Sound/WavWriter.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
@ -9,35 +12,22 @@ bool AssetDumperLoadedSound::ShouldDump(XAssetInfo<LoadedSound>* asset)
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream)
|
||||
void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream)
|
||||
{
|
||||
const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm)
|
||||
+ sizeof(WavChunkHeader) + sizeof(asset->sound.info.data_len);
|
||||
const WavWriter writer(stream);
|
||||
|
||||
stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
|
||||
stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
|
||||
stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
|
||||
const WavMetaData metaData{.channelCount = static_cast<unsigned>(asset->sound.info.channels),
|
||||
.samplesPerSec = static_cast<unsigned>(asset->sound.info.rate),
|
||||
.bitsPerSample = static_cast<unsigned>(asset->sound.info.bits)};
|
||||
|
||||
const WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)};
|
||||
stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
|
||||
|
||||
WavFormatChunkPcm formatChunk{WavFormat::PCM,
|
||||
static_cast<uint16_t>(asset->sound.info.channels),
|
||||
asset->sound.info.rate,
|
||||
asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8,
|
||||
static_cast<uint16_t>(asset->sound.info.block_size),
|
||||
static_cast<uint16_t>(asset->sound.info.bits)};
|
||||
stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
|
||||
|
||||
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, asset->sound.info.data_len};
|
||||
stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
|
||||
stream.write(asset->sound.data, asset->sound.info.data_len);
|
||||
writer.WritePcmHeader(metaData, asset->sound.info.data_len);
|
||||
writer.WritePcmData(asset->sound.data, asset->sound.info.data_len);
|
||||
}
|
||||
|
||||
void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<LoadedSound>* asset)
|
||||
{
|
||||
const auto* loadedSound = asset->Asset();
|
||||
const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name);
|
||||
const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name));
|
||||
|
||||
if (!assetFile)
|
||||
return;
|
||||
@ -46,11 +36,11 @@ void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo<
|
||||
switch (static_cast<WavFormat>(loadedSound->sound.info.format))
|
||||
{
|
||||
case WavFormat::PCM:
|
||||
DumpWavPcm(context, loadedSound, stream);
|
||||
DumpWavPcm(loadedSound, stream);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ namespace IW5
|
||||
{
|
||||
class AssetDumperLoadedSound final : public AbstractAssetDumper<LoadedSound>
|
||||
{
|
||||
static void DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream);
|
||||
static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream);
|
||||
|
||||
protected:
|
||||
bool ShouldDump(XAssetInfo<LoadedSound>* asset) override;
|
||||
|
@ -7,31 +7,31 @@ WavWriter::WavWriter(std::ostream& stream)
|
||||
|
||||
void WavWriter::WritePcmHeader(const WavMetaData& metaData, const size_t dataLen) const
|
||||
{
|
||||
constexpr auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm)
|
||||
+ sizeof(WavChunkHeader) + sizeof(dataLen);
|
||||
constexpr auto riffMasterChunkSize = static_cast<uint32_t>(sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader)
|
||||
+ sizeof(WavFormatChunkPcm) + sizeof(WavChunkHeader) + sizeof(uint32_t));
|
||||
|
||||
m_stream.write(reinterpret_cast<const char*>(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF));
|
||||
m_stream.write(reinterpret_cast<const char*>(&riffMasterChunkSize), sizeof(riffMasterChunkSize));
|
||||
m_stream.write(reinterpret_cast<const char*>(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID));
|
||||
|
||||
constexpr WavChunkHeader formatChunkHeader{WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm)};
|
||||
constexpr WavChunkHeader formatChunkHeader{.chunkID = WAV_CHUNK_ID_FMT, .chunkSize = sizeof(WavFormatChunkPcm)};
|
||||
m_stream.write(reinterpret_cast<const char*>(&formatChunkHeader), sizeof(formatChunkHeader));
|
||||
|
||||
const WavFormatChunkPcm formatChunk{
|
||||
WavFormat::PCM,
|
||||
static_cast<uint16_t>(metaData.channelCount),
|
||||
metaData.samplesPerSec,
|
||||
metaData.samplesPerSec * metaData.channelCount * metaData.bitsPerSample / 8,
|
||||
static_cast<uint16_t>(metaData.channelCount * (metaData.bitsPerSample / 8)),
|
||||
static_cast<uint16_t>(metaData.bitsPerSample),
|
||||
.wFormatTag = WavFormat::PCM,
|
||||
.nChannels = static_cast<uint16_t>(metaData.channelCount),
|
||||
.nSamplesPerSec = metaData.samplesPerSec,
|
||||
.nAvgBytesPerSec = metaData.samplesPerSec * metaData.channelCount * metaData.bitsPerSample / 8,
|
||||
.nBlockAlign = static_cast<uint16_t>(metaData.channelCount * (metaData.bitsPerSample / 8)),
|
||||
.wBitsPerSample = static_cast<uint16_t>(metaData.bitsPerSample),
|
||||
};
|
||||
m_stream.write(reinterpret_cast<const char*>(&formatChunk), sizeof(formatChunk));
|
||||
|
||||
const WavChunkHeader dataChunkHeader{WAV_CHUNK_ID_DATA, static_cast<unsigned>(dataLen)};
|
||||
const WavChunkHeader dataChunkHeader{.chunkID = WAV_CHUNK_ID_DATA, .chunkSize = static_cast<uint32_t>(dataLen)};
|
||||
m_stream.write(reinterpret_cast<const char*>(&dataChunkHeader), sizeof(dataChunkHeader));
|
||||
}
|
||||
|
||||
void WavWriter::WritePcmData(const void* data, const size_t dataLen) const
|
||||
{
|
||||
m_stream.write(static_cast<const char*>(data), dataLen);
|
||||
m_stream.write(static_cast<const char*>(data), static_cast<std::streamsize>(dataLen));
|
||||
}
|
||||
|
@ -534,7 +534,8 @@ namespace
|
||||
const auto translation = Eigen::Translation3f(bone.globalOffset[0], bone.globalOffset[2], -bone.globalOffset[1]);
|
||||
const auto rotation = Eigen::Quaternionf(bone.globalRotation.w, bone.globalRotation.x, bone.globalRotation.z, -bone.globalRotation.y);
|
||||
|
||||
const auto inverseBindMatrix = (translation * rotation).matrix().inverse();
|
||||
const auto bindMatrix = (translation * rotation);
|
||||
const auto inverseBindMatrix = bindMatrix.matrix().inverse();
|
||||
|
||||
// GLTF matrix is column major
|
||||
inverseBindMatrixData[0] = inverseBindMatrix(0, 0);
|
||||
|
@ -189,13 +189,13 @@ bool MemberComputations::IsInRuntimeBlock() const
|
||||
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
|
||||
}
|
||||
|
||||
bool MemberComputations::IsFirstMember() const
|
||||
bool MemberComputations::IsFirstUsedMember() const
|
||||
{
|
||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
||||
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
|
||||
}
|
||||
|
||||
bool MemberComputations::IsLastMember() const
|
||||
bool MemberComputations::IsLastUsedMember() const
|
||||
{
|
||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
||||
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
[[nodiscard]] bool IsNotInDefaultNormalBlock() const;
|
||||
[[nodiscard]] bool IsInTempBlock() const;
|
||||
[[nodiscard]] bool IsInRuntimeBlock() const;
|
||||
[[nodiscard]] bool IsFirstMember() const;
|
||||
[[nodiscard]] bool IsLastMember() const;
|
||||
[[nodiscard]] bool IsFirstUsedMember() const;
|
||||
[[nodiscard]] bool IsLastUsedMember() const;
|
||||
[[nodiscard]] bool HasDynamicArraySize() const;
|
||||
[[nodiscard]] bool IsDynamicMember() const;
|
||||
[[nodiscard]] bool IsAfterPartialLoad() const;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
||||
#include "Domain/Definition/PointerDeclarationModifier.h"
|
||||
#include "Domain/Definition/TypedefDefinition.h"
|
||||
#include "MemberComputations.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -55,6 +56,18 @@ DeclarationModifier* DeclarationModifierComputations::GetNextDeclarationModifier
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetAllDeclarationModifiers() const
|
||||
{
|
||||
const auto& declarationModifiers = m_information->m_member->m_type_declaration->m_declaration_modifiers;
|
||||
std::vector<DeclarationModifier*> all;
|
||||
all.reserve(declarationModifiers.size());
|
||||
|
||||
for (const auto& mod : declarationModifiers)
|
||||
all.emplace_back(mod.get());
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingDeclarationModifiers() const
|
||||
{
|
||||
std::vector<DeclarationModifier*> following;
|
||||
@ -71,7 +84,7 @@ std::vector<DeclarationModifier*> DeclarationModifierComputations::GetFollowingD
|
||||
return following;
|
||||
}
|
||||
|
||||
std::vector<int> DeclarationModifierComputations::GetArrayIndices() const
|
||||
const std::vector<int>& DeclarationModifierComputations::GetArrayIndices() const
|
||||
{
|
||||
return m_modifier_indices;
|
||||
}
|
||||
@ -241,6 +254,15 @@ const IEvaluation* DeclarationModifierComputations::GetDynamicArraySizeEvaluatio
|
||||
return dynamic_cast<ArrayDeclarationModifier*>(declarationModifier)->m_dynamic_size_evaluation.get();
|
||||
}
|
||||
|
||||
bool DeclarationModifierComputations::HasPointerModifier() const
|
||||
{
|
||||
return std::ranges::any_of(m_information->m_member->m_type_declaration->m_declaration_modifiers,
|
||||
[](const std::unique_ptr<DeclarationModifier>& modifier)
|
||||
{
|
||||
return modifier->GetType() == DeclarationModifierType::POINTER;
|
||||
});
|
||||
}
|
||||
|
||||
unsigned DeclarationModifierComputations::GetAlignment() const
|
||||
{
|
||||
const auto following = GetFollowingDeclarationModifiers();
|
||||
|
@ -12,8 +12,9 @@ public:
|
||||
|
||||
[[nodiscard]] DeclarationModifier* GetDeclarationModifier() const;
|
||||
[[nodiscard]] DeclarationModifier* GetNextDeclarationModifier() const;
|
||||
[[nodiscard]] std::vector<DeclarationModifier*> GetAllDeclarationModifiers() const;
|
||||
[[nodiscard]] std::vector<DeclarationModifier*> GetFollowingDeclarationModifiers() const;
|
||||
[[nodiscard]] std::vector<int> GetArrayIndices() const;
|
||||
[[nodiscard]] const std::vector<int>& GetArrayIndices() const;
|
||||
[[nodiscard]] bool IsArray() const;
|
||||
[[nodiscard]] int GetArraySize() const;
|
||||
[[nodiscard]] bool HasDynamicArrayCount() const;
|
||||
@ -26,6 +27,7 @@ public:
|
||||
[[nodiscard]] const IEvaluation* GetPointerArrayCountEvaluation() const;
|
||||
[[nodiscard]] bool IsDynamicArray() const;
|
||||
[[nodiscard]] const IEvaluation* GetDynamicArraySizeEvaluation() const;
|
||||
[[nodiscard]] bool HasPointerModifier() const;
|
||||
[[nodiscard]] unsigned GetAlignment() const;
|
||||
|
||||
private:
|
||||
|
@ -26,6 +26,18 @@ MemberInformation* StructureComputations::GetDynamicMember() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool StructureComputations::HasNonDynamicMember() const
|
||||
{
|
||||
for (const auto& member : m_info->m_ordered_members)
|
||||
{
|
||||
const MemberComputations memberComputations(member.get());
|
||||
if (!memberComputations.ShouldIgnore() && !memberComputations.IsAfterPartialLoad())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
||||
{
|
||||
std::vector<MemberInformation*> members;
|
||||
@ -49,3 +61,8 @@ std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
bool StructureComputations::IsInTempBlock() const
|
||||
{
|
||||
return m_info->m_block != nullptr && m_info->m_block->m_type == FastFileBlockType::TEMP;
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ public:
|
||||
|
||||
[[nodiscard]] bool IsAsset() const;
|
||||
[[nodiscard]] MemberInformation* GetDynamicMember() const;
|
||||
[[nodiscard]] bool HasNonDynamicMember() const;
|
||||
[[nodiscard]] std::vector<MemberInformation*> GetUsedMembers() const;
|
||||
[[nodiscard]] bool IsInTempBlock() const;
|
||||
|
||||
private:
|
||||
const StructureInformation* m_info;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include <cstdint>
|
||||
|
||||
enum class DeclarationModifierType
|
||||
enum class DeclarationModifierType : std::uint8_t
|
||||
{
|
||||
POINTER,
|
||||
ARRAY
|
||||
|
@ -5,13 +5,13 @@
|
||||
#include <cassert>
|
||||
|
||||
TypeDeclaration::TypeDeclaration(const DataDefinition* type)
|
||||
: m_flags(0),
|
||||
m_size(0),
|
||||
m_alignment(0),
|
||||
m_is_const(false),
|
||||
: m_is_const(false),
|
||||
m_has_custom_bit_size(false),
|
||||
m_type(type),
|
||||
m_custom_bit_size(0)
|
||||
m_custom_bit_size(0),
|
||||
m_flags(0),
|
||||
m_size(0),
|
||||
m_alignment(0)
|
||||
{
|
||||
assert(m_type != nullptr);
|
||||
}
|
||||
|
19
src/ZoneCodeGeneratorLib/Domain/Environment/Architecture.cpp
Normal file
19
src/ZoneCodeGeneratorLib/Domain/Environment/Architecture.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "Architecture.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
unsigned GetPointerSizeForArchitecture(const Architecture architecture)
|
||||
{
|
||||
switch (architecture)
|
||||
{
|
||||
case Architecture::X86:
|
||||
return sizeof(uint32_t);
|
||||
|
||||
case Architecture::X64:
|
||||
return sizeof(uint64_t);
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
enum class Architecture
|
||||
#include <cstdint>
|
||||
|
||||
enum class Architecture : std::uint8_t
|
||||
{
|
||||
UNKNOWN,
|
||||
X86,
|
||||
@ -14,3 +16,5 @@ static constexpr Architecture OWN_ARCHITECTURE =
|
||||
Architecture::X64
|
||||
#endif
|
||||
;
|
||||
|
||||
extern unsigned GetPointerSizeForArchitecture(Architecture architecture);
|
||||
|
@ -26,6 +26,7 @@ public:
|
||||
bool m_requires_marking;
|
||||
bool m_has_matching_cross_platform_structure;
|
||||
|
||||
bool m_embedded_reference_exists;
|
||||
bool m_non_embedded_reference_exists;
|
||||
bool m_single_pointer_reference_exists;
|
||||
bool m_array_pointer_reference_exists;
|
||||
|
@ -18,8 +18,10 @@ RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInform
|
||||
{
|
||||
}
|
||||
|
||||
RenderingContext::RenderingContext(std::string game, std::vector<const FastFileBlock*> fastFileBlocks)
|
||||
RenderingContext::RenderingContext(std::string game, const Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks)
|
||||
: m_game(std::move(game)),
|
||||
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
|
||||
m_pointer_size(GetPointerSizeForArchitecture(gameArchitecture)),
|
||||
m_blocks(std::move(fastFileBlocks)),
|
||||
m_asset(nullptr),
|
||||
m_has_actions(false),
|
||||
@ -190,7 +192,8 @@ bool RenderingContext::UsedTypeHasActions(const RenderingUsedType* usedType) con
|
||||
|
||||
std::unique_ptr<RenderingContext> RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset)
|
||||
{
|
||||
auto context = std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetAllFastFileBlocks()));
|
||||
auto context =
|
||||
std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetArchitecture(), repository->GetAllFastFileBlocks()));
|
||||
|
||||
context->MakeAsset(repository, asset);
|
||||
context->CreateUsedTypeCollections();
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
static std::unique_ptr<RenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
||||
|
||||
std::string m_game;
|
||||
bool m_architecture_mismatch;
|
||||
unsigned m_pointer_size;
|
||||
std::vector<const FastFileBlock*> m_blocks;
|
||||
|
||||
StructureInformation* m_asset;
|
||||
@ -43,7 +45,7 @@ public:
|
||||
const FastFileBlock* m_default_temp_block;
|
||||
|
||||
private:
|
||||
RenderingContext(std::string game, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||
RenderingContext(std::string game, Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||
|
||||
RenderingUsedType* AddUsedType(std::unique_ptr<RenderingUsedType> usedType);
|
||||
RenderingUsedType* GetBaseType(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType);
|
||||
|
@ -136,18 +136,6 @@ std::string
|
||||
return str.str();
|
||||
}
|
||||
|
||||
std::string BaseTemplate::MakeMemberAccess(const std::string& variableName,
|
||||
StructureInformation* info,
|
||||
const MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier)
|
||||
{
|
||||
std::ostringstream str;
|
||||
str << variableName << "->" << member->m_member->m_name;
|
||||
MakeArrayIndicesInternal(modifier, str);
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl)
|
||||
{
|
||||
std::ostringstream str;
|
||||
|
@ -29,10 +29,6 @@ protected:
|
||||
static std::string MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
|
||||
static std::string
|
||||
MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
|
||||
static std::string MakeMemberAccess(const std::string& variableName,
|
||||
StructureInformation* info,
|
||||
const MemberInformation* member,
|
||||
const DeclarationModifierComputations& modifier);
|
||||
static std::string MakeTypeDecl(const TypeDeclaration* decl);
|
||||
static std::string MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers);
|
||||
static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -655,7 +655,7 @@ namespace
|
||||
{
|
||||
const MemberComputations computations(member);
|
||||
|
||||
if (computations.IsFirstMember())
|
||||
if (computations.IsFirstUsedMember())
|
||||
{
|
||||
LINE("")
|
||||
if (member->m_condition)
|
||||
@ -674,7 +674,7 @@ namespace
|
||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
}
|
||||
}
|
||||
else if (computations.IsLastMember())
|
||||
else if (computations.IsLastUsedMember())
|
||||
{
|
||||
if (member->m_condition)
|
||||
{
|
||||
|
@ -874,7 +874,7 @@ namespace
|
||||
{
|
||||
const MemberComputations computations(member);
|
||||
|
||||
if (computations.IsFirstMember())
|
||||
if (computations.IsFirstUsedMember())
|
||||
{
|
||||
LINE("")
|
||||
if (member->m_condition)
|
||||
@ -893,7 +893,7 @@ namespace
|
||||
WriteMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||
}
|
||||
}
|
||||
else if (computations.IsLastMember())
|
||||
else if (computations.IsLastUsedMember())
|
||||
{
|
||||
if (member->m_condition)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "Parsing/Impl/IncludingStreamProxy.h"
|
||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||
#include "Parsing/PostProcessing/CalculateSizeAndAlignPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/CrossPlatformStructurePostProcessor.h"
|
||||
#include "Parsing/PostProcessing/LeafsPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/MarkingRequiredPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/MemberLeafsPostProcessor.h"
|
||||
@ -19,8 +20,8 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_NAME = "__zonecodegenerator";
|
||||
static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_VALUE = "1";
|
||||
constexpr const char* ZONE_CODE_GENERATOR_DEFINE_NAME = "__zonecodegenerator";
|
||||
constexpr const char* ZONE_CODE_GENERATOR_DEFINE_VALUE = "1";
|
||||
} // namespace
|
||||
|
||||
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||
@ -62,6 +63,7 @@ void CommandsFileReader::SetupStreamProxies()
|
||||
void CommandsFileReader::SetupPostProcessors()
|
||||
{
|
||||
// Order is important
|
||||
m_post_processors.emplace_back(std::make_unique<CrossPlatformStructurePostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<CalculateSizeAndAlignPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<UsagesPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<LeafsPostProcessor>());
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "Parsing/Impl/ParserFilesystemStream.h"
|
||||
#include "Parsing/PostProcessing/CreateMemberInformationPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/CreateStructureInformationPostProcessor.h"
|
||||
#include "Parsing/PostProcessing/CrossPlatformStructurePostProcessor.h"
|
||||
#include "Parsing/PostProcessing/IPostProcessor.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -19,8 +18,8 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_NAME = "__zonecodegenerator";
|
||||
static constexpr const char* ZONE_CODE_GENERATOR_DEFINE_VALUE = "1";
|
||||
constexpr const char* ZONE_CODE_GENERATOR_DEFINE_NAME = "__zonecodegenerator";
|
||||
constexpr const char* ZONE_CODE_GENERATOR_DEFINE_VALUE = "1";
|
||||
} // namespace
|
||||
|
||||
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
|
||||
@ -68,7 +67,6 @@ void HeaderFileReader::SetupPostProcessors()
|
||||
// Order is important
|
||||
m_post_processors.emplace_back(std::make_unique<CreateStructureInformationPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<CreateMemberInformationPostProcessor>());
|
||||
m_post_processors.emplace_back(std::make_unique<CrossPlatformStructurePostProcessor>());
|
||||
}
|
||||
|
||||
bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
|
||||
|
@ -12,22 +12,6 @@ namespace
|
||||
bool CalculateFieldsIfNecessary(IDataRepository* repository, const DataDefinition* definition);
|
||||
bool CalculateFields(IDataRepository* repository, TypeDeclaration* declaration);
|
||||
|
||||
unsigned GetPointerSizeForArchitecture(const Architecture architecture)
|
||||
{
|
||||
switch (architecture)
|
||||
{
|
||||
case Architecture::X86:
|
||||
return sizeof(uint32_t);
|
||||
|
||||
case Architecture::X64:
|
||||
return sizeof(uint64_t);
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
bool CalculateAlign(IDataRepository* repository, TypeDeclaration* declaration)
|
||||
{
|
||||
auto hasPointerModifier = false;
|
||||
|
@ -35,6 +35,9 @@ namespace
|
||||
if (computations.ShouldIgnore())
|
||||
continue;
|
||||
|
||||
if (computations.IsArray() || member->m_member->m_type_declaration->m_declaration_modifiers.empty())
|
||||
member->m_type->m_embedded_reference_exists = true;
|
||||
|
||||
if (computations.ContainsNonEmbeddedReference())
|
||||
member->m_type->m_non_embedded_reference_exists = true;
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace IW3
|
||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||
|
||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
||||
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||
};
|
||||
} // namespace IW3
|
||||
|
@ -43,7 +43,7 @@ namespace IW4
|
||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||
|
||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
||||
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||
};
|
||||
} // namespace IW4
|
||||
|
@ -40,7 +40,7 @@ namespace IW5
|
||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||
|
||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
||||
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||
};
|
||||
} // namespace IW5
|
||||
|
@ -20,7 +20,7 @@ namespace T5
|
||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||
|
||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 3;
|
||||
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
|
||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||
};
|
||||
} // namespace T5
|
||||
|
@ -27,7 +27,7 @@ namespace T6
|
||||
static constexpr int XCHUNK_SIZE = 0x8000;
|
||||
static constexpr int XCHUNK_MAX_WRITE_SIZE = XCHUNK_SIZE - 0x40;
|
||||
static constexpr int VANILLA_BUFFER_SIZE = 0x80000;
|
||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 3;
|
||||
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
|
||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||
|
||||
static constexpr size_t FILE_SUFFIX_ZERO_MIN_SIZE = 0x40;
|
||||
|
@ -1,34 +1,23 @@
|
||||
#include "XBlock.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
XBlock::XBlock(const std::string& name, const int index, const Type type)
|
||||
XBlock::XBlock(std::string name, const unsigned index, const XBlockType type)
|
||||
: m_name(std::move(name)),
|
||||
m_index(index),
|
||||
m_type(type),
|
||||
m_buffer_size(0u)
|
||||
{
|
||||
m_name = name;
|
||||
m_index = index;
|
||||
m_type = type;
|
||||
m_buffer = nullptr;
|
||||
m_buffer_size = 0;
|
||||
}
|
||||
|
||||
XBlock::~XBlock()
|
||||
{
|
||||
delete[] m_buffer;
|
||||
m_buffer = nullptr;
|
||||
}
|
||||
|
||||
void XBlock::Alloc(const size_t blockSize)
|
||||
{
|
||||
delete[] m_buffer;
|
||||
|
||||
if (blockSize > 0)
|
||||
{
|
||||
m_buffer = new uint8_t[blockSize];
|
||||
m_buffer = std::make_unique<uint8_t[]>(blockSize);
|
||||
m_buffer_size = blockSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buffer = nullptr;
|
||||
m_buffer.reset();
|
||||
m_buffer_size = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class XBlock
|
||||
enum class XBlockType : std::uint8_t
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
BLOCK_TYPE_TEMP,
|
||||
BLOCK_TYPE_RUNTIME,
|
||||
BLOCK_TYPE_DELAY,
|
||||
BLOCK_TYPE_NORMAL
|
||||
};
|
||||
};
|
||||
|
||||
class XBlock
|
||||
{
|
||||
public:
|
||||
XBlock(std::string name, unsigned index, XBlockType type);
|
||||
|
||||
void Alloc(size_t blockSize);
|
||||
|
||||
std::string m_name;
|
||||
unsigned m_index;
|
||||
Type m_type;
|
||||
XBlockType m_type;
|
||||
|
||||
uint8_t* m_buffer;
|
||||
std::unique_ptr<uint8_t[]> m_buffer;
|
||||
size_t m_buffer_size;
|
||||
|
||||
XBlock(const std::string& name, int index, Type type);
|
||||
~XBlock();
|
||||
|
||||
void Alloc(size_t blockSize);
|
||||
};
|
||||
|
@ -32,8 +32,8 @@
|
||||
|
||||
using namespace IW3;
|
||||
|
||||
ContentLoader::ContentLoader(Zone& zone)
|
||||
: ContentLoaderBase(zone),
|
||||
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varXAsset(nullptr),
|
||||
varScriptStringList(nullptr)
|
||||
{
|
||||
@ -41,16 +41,16 @@ ContentLoader::ContentLoader(Zone& zone)
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
||||
m_stream.Load<ScriptStringList>(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
|
||||
|
||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
|
||||
varXString = varScriptStringList->strings;
|
||||
LoadXStringArray(true, varScriptStringList->count);
|
||||
|
||||
@ -58,7 +58,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
|
||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
@ -68,7 +68,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -79,7 +79,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset);
|
||||
m_stream.Load<XAsset>(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@ -125,7 +125,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset, count);
|
||||
m_stream.Load<XAsset>(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@ -134,26 +134,24 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
void ContentLoader::Load()
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
XAssetList assetList{};
|
||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
varScriptStringList = &assetList.stringList;
|
||||
LoadScriptStringList(false);
|
||||
|
||||
if (assetList.assets != nullptr)
|
||||
{
|
||||
assert(assetList.assets == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
|
||||
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
|
||||
varXAsset = assetList.assets;
|
||||
LoadXAssetArray(true, assetList.assetCount);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ namespace IW3
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -44,15 +44,15 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
@ -85,8 +85,15 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(
|
||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
||||
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||
[&zonePtr](ZoneInputStream& stream)
|
||||
{
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr->Memory()));
|
||||
|
||||
return zoneLoader;
|
||||
}
|
||||
|
@ -42,8 +42,9 @@
|
||||
|
||||
using namespace IW4;
|
||||
|
||||
ContentLoader::ContentLoader(Zone& zone)
|
||||
: ContentLoaderBase(zone),
|
||||
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varXAssetList(nullptr),
|
||||
varXAsset(nullptr),
|
||||
varScriptStringList(nullptr)
|
||||
{
|
||||
@ -51,16 +52,17 @@ ContentLoader::ContentLoader(Zone& zone)
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
||||
assert(!atStreamStart);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
|
||||
|
||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
#ifdef ARCH_x86
|
||||
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
|
||||
#else
|
||||
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
|
||||
#endif
|
||||
varXString = varScriptStringList->strings;
|
||||
LoadXStringArray(true, varScriptStringList->count);
|
||||
|
||||
@ -68,8 +70,6 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
|
||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -89,7 +89,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset);
|
||||
m_stream.Load<XAsset>(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@ -145,35 +145,66 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset, count);
|
||||
{
|
||||
#ifdef ARCH_x86
|
||||
m_stream.Load<XAsset>(varXAsset, count);
|
||||
#else
|
||||
const auto fill = m_stream.LoadWithFill(8u * count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
fill.Fill(varXAsset[index].type, 8u * index);
|
||||
fill.FillPtr(varXAsset[index].header.data, 8u * index + 4u);
|
||||
m_stream.AddPointerLookup(&varXAsset[index].header.data, fill.BlockBuffer(8u * index + 4u));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
LoadXAsset(false);
|
||||
varXAsset++;
|
||||
|
||||
#ifdef DEBUG_OFFSETS
|
||||
m_stream.DebugOffsets(index);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
void ContentLoader::Load()
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
XAssetList assetList{};
|
||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
||||
varXAssetList = &assetList;
|
||||
|
||||
#ifdef ARCH_x86
|
||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||
#else
|
||||
const auto fillAccessor = m_stream.LoadWithFill(16u);
|
||||
varScriptStringList = &varXAssetList->stringList;
|
||||
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||
fillAccessor.FillPtr(varScriptStringList->strings, 4u);
|
||||
|
||||
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||
fillAccessor.FillPtr(varXAssetList->assets, 12u);
|
||||
#endif
|
||||
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
varScriptStringList = &assetList.stringList;
|
||||
LoadScriptStringList(false);
|
||||
|
||||
if (assetList.assets != nullptr)
|
||||
{
|
||||
assert(assetList.assets == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
|
||||
#ifdef ARCH_x86
|
||||
assetList.assets = m_stream.Alloc<XAsset>(4);
|
||||
#else
|
||||
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
|
||||
#endif
|
||||
varXAsset = assetList.assets;
|
||||
LoadXAssetArray(true, assetList.assetCount);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ namespace IW4
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
@ -19,6 +18,7 @@ namespace IW4
|
||||
void LoadXAsset(bool atStreamStart) const;
|
||||
void LoadXAssetArray(bool atStreamStart, size_t count);
|
||||
|
||||
XAssetList* varXAssetList;
|
||||
XAsset* varXAsset;
|
||||
ScriptStringList* varScriptStringList;
|
||||
};
|
||||
|
@ -80,14 +80,14 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(IW4::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
@ -207,8 +207,15 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(
|
||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
||||
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||
[zonePtr](ZoneInputStream& stream)
|
||||
{
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr->Memory()));
|
||||
|
||||
return zoneLoader;
|
||||
}
|
||||
|
@ -47,8 +47,8 @@
|
||||
|
||||
using namespace IW5;
|
||||
|
||||
ContentLoader::ContentLoader(Zone& zone)
|
||||
: ContentLoaderBase(zone),
|
||||
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varXAsset(nullptr),
|
||||
varScriptStringList(nullptr)
|
||||
{
|
||||
@ -56,16 +56,16 @@ ContentLoader::ContentLoader(Zone& zone)
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
||||
m_stream.Load<ScriptStringList>(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
|
||||
|
||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
|
||||
varXString = varScriptStringList->strings;
|
||||
LoadXStringArray(true, varScriptStringList->count);
|
||||
|
||||
@ -73,7 +73,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
|
||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
@ -83,7 +83,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -94,7 +94,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset);
|
||||
m_stream.Load<XAsset>(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@ -154,7 +154,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
assert(count == 0 || varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset, count);
|
||||
m_stream.Load<XAsset>(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@ -163,26 +163,24 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
void ContentLoader::Load()
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
XAssetList assetList{};
|
||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
varScriptStringList = &assetList.stringList;
|
||||
LoadScriptStringList(false);
|
||||
|
||||
if (assetList.assets != nullptr)
|
||||
{
|
||||
assert(assetList.assets == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
|
||||
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
|
||||
varXAsset = assetList.assets;
|
||||
LoadXAssetArray(true, assetList.assetCount);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ namespace IW5
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -63,15 +63,15 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
@ -184,8 +184,15 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(
|
||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
||||
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||
[&zonePtr](ZoneInputStream& stream)
|
||||
{
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr->Memory()));
|
||||
|
||||
return zoneLoader;
|
||||
}
|
||||
|
@ -39,8 +39,8 @@
|
||||
|
||||
using namespace T5;
|
||||
|
||||
ContentLoader::ContentLoader(Zone& zone)
|
||||
: ContentLoaderBase(zone),
|
||||
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varXAsset(nullptr),
|
||||
varScriptStringList(nullptr)
|
||||
{
|
||||
@ -48,16 +48,16 @@ ContentLoader::ContentLoader(Zone& zone)
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
||||
m_stream.Load<ScriptStringList>(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
|
||||
|
||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
|
||||
varXString = varScriptStringList->strings;
|
||||
LoadXStringArray(true, varScriptStringList->count);
|
||||
|
||||
@ -65,7 +65,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
|
||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
@ -75,7 +75,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -86,7 +86,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset);
|
||||
m_stream.Load<XAsset>(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@ -138,7 +138,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset, count);
|
||||
m_stream.Load<XAsset>(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@ -147,26 +147,24 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
void ContentLoader::Load()
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
XAssetList assetList{};
|
||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
varScriptStringList = &assetList.stringList;
|
||||
LoadScriptStringList(false);
|
||||
|
||||
if (assetList.assets != nullptr)
|
||||
{
|
||||
assert(assetList.assets == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
|
||||
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
|
||||
varXAsset = assetList.assets;
|
||||
LoadXAssetArray(true, assetList.assetCount);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ namespace T5
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -46,13 +46,13 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
@ -85,8 +85,15 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(
|
||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
||||
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||
[&zonePtr](ZoneInputStream& stream)
|
||||
{
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr->Memory()));
|
||||
|
||||
return zoneLoader;
|
||||
}
|
||||
|
@ -55,8 +55,8 @@
|
||||
|
||||
using namespace T6;
|
||||
|
||||
ContentLoader::ContentLoader(Zone& zone)
|
||||
: ContentLoaderBase(zone),
|
||||
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||
: ContentLoaderBase(zone, stream),
|
||||
varXAsset(nullptr),
|
||||
varScriptStringList(nullptr)
|
||||
{
|
||||
@ -64,16 +64,16 @@ ContentLoader::ContentLoader(Zone& zone)
|
||||
|
||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
{
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
||||
m_stream.Load<ScriptStringList>(varScriptStringList);
|
||||
|
||||
if (varScriptStringList->strings != nullptr)
|
||||
{
|
||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING);
|
||||
|
||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
varScriptStringList->strings = m_stream.Alloc<const char*>(alignof(const char*));
|
||||
varXString = varScriptStringList->strings;
|
||||
LoadXStringArray(true, varScriptStringList->count);
|
||||
|
||||
@ -81,7 +81,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
|
||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||
}
|
||||
@ -91,7 +91,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
#define LOAD_ASSET(type_index, typeName, headerEntry) \
|
||||
case type_index: \
|
||||
{ \
|
||||
Loader_##typeName loader(m_zone, *m_stream); \
|
||||
Loader_##typeName loader(m_zone, m_stream); \
|
||||
loader.Load(&varXAsset->header.headerEntry); \
|
||||
break; \
|
||||
}
|
||||
@ -99,7 +99,7 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset);
|
||||
m_stream.Load<XAsset>(varXAsset);
|
||||
|
||||
switch (varXAsset->type)
|
||||
{
|
||||
@ -167,7 +167,7 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
assert(varXAsset != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<XAsset>(varXAsset, count);
|
||||
m_stream.Load<XAsset>(varXAsset, count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@ -176,35 +176,33 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
||||
}
|
||||
}
|
||||
|
||||
void ContentLoader::Load(ZoneInputStream& stream)
|
||||
void ContentLoader::Load()
|
||||
{
|
||||
m_stream = &stream;
|
||||
|
||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
XAssetList assetList{};
|
||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
||||
m_stream.LoadDataRaw(&assetList, sizeof(assetList));
|
||||
|
||||
varScriptStringList = &assetList.stringList;
|
||||
LoadScriptStringList(false);
|
||||
|
||||
if (assetList.depends != nullptr)
|
||||
{
|
||||
assert(assetList.depends == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.depends) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.depends = m_stream->Alloc<const char*>(alignof(const char*));
|
||||
assetList.depends = m_stream.Alloc<const char*>(alignof(const char*));
|
||||
varXString = assetList.depends;
|
||||
LoadXStringArray(true, assetList.dependCount);
|
||||
}
|
||||
|
||||
if (assetList.assets != nullptr)
|
||||
{
|
||||
assert(assetList.assets == PTR_FOLLOWING);
|
||||
assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING);
|
||||
|
||||
assetList.assets = m_stream->Alloc<XAsset>(alignof(XAsset));
|
||||
assetList.assets = m_stream.Alloc<XAsset>(alignof(XAsset));
|
||||
varXAsset = assetList.assets;
|
||||
LoadXAssetArray(true, assetList.assetCount);
|
||||
}
|
||||
|
||||
m_stream->PopBlock();
|
||||
m_stream.PopBlock();
|
||||
}
|
||||
|
@ -9,9 +9,8 @@ namespace T6
|
||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
explicit ContentLoader(Zone& zone);
|
||||
|
||||
void Load(ZoneInputStream& stream) override;
|
||||
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||
void Load() override;
|
||||
|
||||
private:
|
||||
void LoadScriptStringList(bool atStreamStart);
|
||||
|
@ -93,14 +93,14 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
zoneLoader.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
@ -203,8 +203,15 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||
|
||||
// Start of the zone content
|
||||
zoneLoader->AddLoadingStep(
|
||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
||||
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||
[&zonePtr](ZoneInputStream& stream)
|
||||
{
|
||||
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||
},
|
||||
32u,
|
||||
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||
ZoneConstants::INSERT_BLOCK,
|
||||
zonePtr->Memory()));
|
||||
|
||||
if (isSecure)
|
||||
{
|
||||
|
@ -1,23 +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);
|
||||
|
||||
ContentLoaderBase::ContentLoaderBase(Zone& zone)
|
||||
: varXString(nullptr),
|
||||
m_zone(zone),
|
||||
m_memory(zone.Memory()),
|
||||
m_stream(nullptr)
|
||||
{
|
||||
}
|
||||
#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))
|
||||
{
|
||||
}
|
||||
|
||||
@ -26,18 +25,18 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const
|
||||
assert(varXString != nullptr);
|
||||
|
||||
if (atStreamStart)
|
||||
m_stream->Load<const char*>(varXString);
|
||||
m_stream.Load<const char*>(varXString);
|
||||
|
||||
if (*varXString != nullptr)
|
||||
{
|
||||
if (*varXString == PTR_FOLLOWING)
|
||||
if (GetZonePointerType(*varXString) == ZonePointerType::FOLLOWING)
|
||||
{
|
||||
*varXString = m_stream->Alloc<const char>(alignof(const char));
|
||||
m_stream->LoadNullTerminated(const_cast<char*>(*varXString));
|
||||
*varXString = m_stream.Alloc<const char>(1);
|
||||
m_stream.LoadNullTerminated(const_cast<char*>(*varXString));
|
||||
}
|
||||
else
|
||||
{
|
||||
*varXString = m_stream->ConvertOffsetToPointer<const char>(*varXString);
|
||||
*varXString = m_stream.ConvertOffsetToPointerNative<const char>(*varXString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,8 +45,21 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
|
||||
{
|
||||
assert(varXString != nullptr);
|
||||
|
||||
#ifdef ARCH_x86
|
||||
if (atStreamStart)
|
||||
m_stream->Load<const char*>(varXString, count);
|
||||
m_stream.Load<const char*>(varXString, count);
|
||||
#else
|
||||
if (atStreamStart)
|
||||
{
|
||||
const auto fill = m_stream.LoadWithFill(4u * count);
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
fill.FillPtr(varXString[index], 4u * index);
|
||||
m_stream.AddPointerLookup(&varXString[index], fill.BlockBuffer(4u * index));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t index = 0; index < count; index++)
|
||||
{
|
||||
@ -55,3 +67,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;
|
||||
@ -17,15 +22,25 @@ public:
|
||||
ContentLoaderBase& operator=(ContentLoaderBase&& other) noexcept = delete;
|
||||
|
||||
protected:
|
||||
explicit ContentLoaderBase(Zone& zone);
|
||||
ContentLoaderBase(Zone& zone, ZoneInputStream& stream);
|
||||
|
||||
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;
|
||||
ZoneInputStream& m_stream;
|
||||
|
||||
private:
|
||||
const void* m_zone_ptr_following;
|
||||
const void* m_zone_ptr_insert;
|
||||
};
|
||||
|
@ -0,0 +1,19 @@
|
||||
#include "InvalidLookupPositionException.h"
|
||||
|
||||
#include <format>
|
||||
|
||||
InvalidLookupPositionException::InvalidLookupPositionException(block_t block, size_t offset)
|
||||
: m_block(block),
|
||||
m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
std::string InvalidLookupPositionException::DetailedMessage()
|
||||
{
|
||||
return std::format("Zone tried to lookup at block {}, offset {} that was not recorded", m_block, m_offset);
|
||||
}
|
||||
|
||||
char const* InvalidLookupPositionException::what() const noexcept
|
||||
{
|
||||
return "Zone tried to lookup at zone offset that is not recorded";
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "LoadingException.h"
|
||||
#include "Zone/ZoneTypes.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
class InvalidLookupPositionException final : public LoadingException
|
||||
{
|
||||
public:
|
||||
InvalidLookupPositionException(block_t block, size_t offset);
|
||||
|
||||
std::string DetailedMessage() override;
|
||||
char const* what() const noexcept override;
|
||||
|
||||
private:
|
||||
block_t m_block;
|
||||
size_t m_offset;
|
||||
};
|
@ -1,7 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
|
||||
class IContentLoadingEntryPoint
|
||||
{
|
||||
public:
|
||||
@ -12,5 +10,5 @@ public:
|
||||
IContentLoadingEntryPoint& operator=(const IContentLoadingEntryPoint& other) = default;
|
||||
IContentLoadingEntryPoint& operator=(IContentLoadingEntryPoint&& other) noexcept = default;
|
||||
|
||||
virtual void Load(ZoneInputStream& stream) = 0;
|
||||
virtual void Load() = 0;
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -7,32 +7,47 @@ namespace
|
||||
class StepLoadZoneContent final : public ILoadingStep
|
||||
{
|
||||
public:
|
||||
StepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, const int offsetBlockBitCount, const block_t insertBlock)
|
||||
: m_content_loader(std::move(entryPoint)),
|
||||
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
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(zoneLoader.m_blocks, stream, m_offset_block_bit_count, m_insert_block);
|
||||
const auto inputStream =
|
||||
ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream, m_memory);
|
||||
|
||||
m_content_loader->Load(*inputStream);
|
||||
const auto entryPoint = m_entry_point_factory(*inputStream);
|
||||
assert(entryPoint);
|
||||
|
||||
entryPoint->Load();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<IContentLoadingEntryPoint> m_content_loader;
|
||||
int m_offset_block_bit_count;
|
||||
std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> m_entry_point_factory;
|
||||
unsigned m_pointer_bit_count;
|
||||
unsigned m_offset_block_bit_count;
|
||||
block_t m_insert_block;
|
||||
MemoryManager& m_memory;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
namespace step
|
||||
{
|
||||
std::unique_ptr<ILoadingStep>
|
||||
CreateStepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, const int offsetBlockBitCount, const block_t insertBlock)
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
const unsigned pointerBitCount,
|
||||
const unsigned offsetBlockBitCount,
|
||||
const block_t insertBlock,
|
||||
MemoryManager& memory)
|
||||
{
|
||||
return std::make_unique<StepLoadZoneContent>(std::move(entryPoint), offsetBlockBitCount, insertBlock);
|
||||
return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock, memory);
|
||||
}
|
||||
} // namespace step
|
||||
|
@ -2,11 +2,16 @@
|
||||
|
||||
#include "Loading/IContentLoadingEntryPoint.h"
|
||||
#include "Loading/ILoadingStep.h"
|
||||
#include "Zone/Stream/ZoneInputStream.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace step
|
||||
{
|
||||
std::unique_ptr<ILoadingStep>
|
||||
CreateStepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, int offsetBlockBitCount, block_t insertBlock);
|
||||
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||
unsigned pointerBitCount,
|
||||
unsigned offsetBlockBitCount,
|
||||
block_t insertBlock,
|
||||
MemoryManager& memory);
|
||||
}
|
||||
|
@ -8,27 +8,72 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <unordered_map>
|
||||
|
||||
ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(void* blockBuffer, const size_t bufferSize, const unsigned pointerByteCount, const size_t offset)
|
||||
: m_block_buffer(blockBuffer),
|
||||
m_buffer_size(bufferSize),
|
||||
m_pointer_byte_count(pointerByteCount),
|
||||
m_offset(offset)
|
||||
{
|
||||
// Otherwise we cannot insert alias
|
||||
assert(m_pointer_byte_count <= sizeof(uintptr_t));
|
||||
}
|
||||
|
||||
ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const
|
||||
{
|
||||
assert(offset <= m_buffer_size);
|
||||
return ZoneStreamFillReadAccessor(static_cast<char*>(m_block_buffer) + offset, m_buffer_size - offset, m_pointer_byte_count, m_offset + offset);
|
||||
}
|
||||
|
||||
size_t ZoneStreamFillReadAccessor::Offset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
void* ZoneStreamFillReadAccessor::BlockBuffer(const size_t offset) const
|
||||
{
|
||||
return static_cast<uint8_t*>(m_block_buffer) + offset;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class XBlockInputStream final : public ZoneInputStream
|
||||
{
|
||||
public:
|
||||
XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream& stream, const unsigned blockBitCount, const block_t insertBlock)
|
||||
XBlockInputStream(const unsigned pointerBitCount,
|
||||
const unsigned blockBitCount,
|
||||
std::vector<XBlock*>& blocks,
|
||||
const block_t insertBlock,
|
||||
ILoadingStream& stream,
|
||||
MemoryManager& memory)
|
||||
: m_blocks(blocks),
|
||||
m_stream(stream)
|
||||
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_last_fill_size(0)
|
||||
{
|
||||
assert(pointerBitCount % 8u == 0u);
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
|
||||
const auto blockCount = static_cast<unsigned>(blocks.size());
|
||||
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
||||
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
||||
|
||||
m_block_bit_count = blockBitCount;
|
||||
|
||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||
m_insert_block = blocks[insertBlock];
|
||||
}
|
||||
|
||||
[[nodiscard]] unsigned GetPointerBitCount() const override
|
||||
{
|
||||
return m_pointer_byte_count * 8u;
|
||||
}
|
||||
|
||||
void PushBlock(const block_t block) override
|
||||
{
|
||||
assert(block < static_cast<block_t>(m_blocks.size()));
|
||||
@ -38,7 +83,7 @@ namespace
|
||||
|
||||
m_block_stack.push(newBlock);
|
||||
|
||||
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
m_temp_offsets.push(m_block_offsets[newBlock->m_index]);
|
||||
}
|
||||
|
||||
@ -54,7 +99,7 @@ namespace
|
||||
m_block_stack.pop();
|
||||
|
||||
// If the temp block is not used anymore right now, reset it to the buffer start since as the name suggests, the data inside is temporary.
|
||||
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
m_block_offsets[poppedBlock->m_index] = m_temp_offsets.top();
|
||||
m_temp_offsets.pop();
|
||||
@ -72,7 +117,7 @@ namespace
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
Align(align);
|
||||
Align(*block, align);
|
||||
|
||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
@ -80,6 +125,23 @@ namespace
|
||||
return &block->m_buffer[m_block_offsets[block->m_index]];
|
||||
}
|
||||
|
||||
void* AllocOutOfBlock(const unsigned align, const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return nullptr;
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
Align(*block, align);
|
||||
|
||||
if (m_block_offsets[block->m_index] > block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
|
||||
return m_memory.AllocRaw(size);
|
||||
}
|
||||
|
||||
void LoadDataRaw(void* dst, const size_t size) override
|
||||
{
|
||||
m_stream.Load(dst, size);
|
||||
@ -87,50 +149,26 @@ namespace
|
||||
|
||||
void LoadDataInBlock(void* dst, const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
// If no block has been pushed, load raw
|
||||
if (!m_block_stack.empty())
|
||||
{
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
if (block->m_buffer.get() > dst || block->m_buffer.get() + block->m_buffer_size < dst)
|
||||
throw OutOfBlockBoundsException(block);
|
||||
|
||||
if (static_cast<uint8_t*>(dst) + size > block->m_buffer + block->m_buffer_size)
|
||||
if (static_cast<uint8_t*>(dst) + size > block->m_buffer.get() + block->m_buffer_size)
|
||||
throw BlockOverflowException(block);
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
switch (block->m_type)
|
||||
LoadDataFromBlock(*block, dst, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
case XBlock::Type::BLOCK_TYPE_TEMP:
|
||||
case XBlock::Type::BLOCK_TYPE_NORMAL:
|
||||
m_stream.Load(dst, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||
memset(dst, 0, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
IncBlockPos(size);
|
||||
}
|
||||
|
||||
void IncBlockPos(const size_t size) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
if (m_block_stack.empty())
|
||||
return;
|
||||
|
||||
const auto* block = m_block_stack.top();
|
||||
m_block_offsets[block->m_index] += size;
|
||||
}
|
||||
|
||||
void LoadNullTerminated(void* dst) override
|
||||
@ -142,14 +180,14 @@ namespace
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||
if (block->m_buffer.get() > dst || block->m_buffer.get() + block->m_buffer_size < dst)
|
||||
throw OutOfBlockBoundsException(block);
|
||||
|
||||
// Theoretically ptr should always be at the current block offset.
|
||||
assert(dst == &block->m_buffer[m_block_offsets[block->m_index]]);
|
||||
|
||||
uint8_t byte;
|
||||
auto offset = static_cast<size_t>(static_cast<uint8_t*>(dst) - block->m_buffer);
|
||||
auto offset = static_cast<size_t>(static_cast<uint8_t*>(dst) - block->m_buffer.get());
|
||||
do
|
||||
{
|
||||
if (offset >= block->m_buffer_size)
|
||||
@ -162,32 +200,108 @@ namespace
|
||||
m_block_offsets[block->m_index] = offset;
|
||||
}
|
||||
|
||||
void** InsertPointer() override
|
||||
ZoneStreamFillReadAccessor LoadWithFill(const size_t size) override
|
||||
{
|
||||
m_block_stack.push(m_insert_block);
|
||||
m_last_fill_size = size;
|
||||
|
||||
Align(alignof(void*));
|
||||
// If no block has been pushed, load raw
|
||||
if (!m_block_stack.empty())
|
||||
{
|
||||
const auto* block = m_block_stack.top();
|
||||
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]];
|
||||
|
||||
if (m_block_offsets[m_insert_block->m_index] + sizeof(void*) > m_insert_block->m_buffer_size)
|
||||
LoadDataFromBlock(*block, blockBufferForFill, size);
|
||||
|
||||
return ZoneStreamFillReadAccessor(blockBufferForFill, size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
m_fill_buffer.resize(size);
|
||||
m_stream.Load(m_fill_buffer.data(), size);
|
||||
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
ZoneStreamFillReadAccessor AppendToFill(const size_t appendSize) override
|
||||
{
|
||||
const auto appendOffset = m_last_fill_size;
|
||||
m_last_fill_size += appendSize;
|
||||
|
||||
// If no block has been pushed, load raw
|
||||
if (!m_block_stack.empty())
|
||||
{
|
||||
const auto* block = m_block_stack.top();
|
||||
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]] - appendOffset;
|
||||
LoadDataFromBlock(*block, &block->m_buffer[m_block_offsets[block->m_index]], appendSize);
|
||||
|
||||
return ZoneStreamFillReadAccessor(blockBufferForFill, m_last_fill_size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
m_fill_buffer.resize(appendOffset + appendSize);
|
||||
m_stream.Load(m_fill_buffer.data() + appendOffset, appendSize);
|
||||
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), m_last_fill_size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
ZoneStreamFillReadAccessor GetLastFill() override
|
||||
{
|
||||
assert(!m_fill_buffer.empty());
|
||||
|
||||
if (!m_block_stack.empty())
|
||||
{
|
||||
const auto* block = m_block_stack.top();
|
||||
auto* blockBufferForFill = &block->m_buffer[m_block_offsets[block->m_index]] - m_last_fill_size;
|
||||
|
||||
return ZoneStreamFillReadAccessor(blockBufferForFill, m_last_fill_size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
assert(m_fill_buffer.size() == m_last_fill_size);
|
||||
return ZoneStreamFillReadAccessor(m_fill_buffer.data(), m_last_fill_size, m_pointer_byte_count, 0);
|
||||
}
|
||||
|
||||
void* InsertPointerNative() override
|
||||
{
|
||||
// Alignment of pointer should always be its size
|
||||
Align(*m_insert_block, m_pointer_byte_count);
|
||||
|
||||
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
||||
throw BlockOverflowException(m_insert_block);
|
||||
|
||||
auto* ptr = reinterpret_cast<void**>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||
|
||||
IncBlockPos(sizeof(void*));
|
||||
|
||||
m_block_stack.pop();
|
||||
IncBlockPos(*m_insert_block, m_pointer_byte_count);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* ConvertOffsetToPointer(const void* offset) override
|
||||
uintptr_t InsertPointerAliasLookup() override
|
||||
{
|
||||
// Alignment of pointer should always be its size
|
||||
Align(*m_insert_block, m_pointer_byte_count);
|
||||
|
||||
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
||||
throw BlockOverflowException(m_insert_block);
|
||||
|
||||
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);
|
||||
|
||||
IncBlockPos(*m_insert_block, m_pointer_byte_count);
|
||||
|
||||
return zonePtr;
|
||||
}
|
||||
|
||||
void SetInsertedPointerAliasLookup(const uintptr_t zonePtr, void* value) override
|
||||
{
|
||||
assert((static_cast<block_t>((zonePtr & m_block_mask) >> m_block_shift)) < m_blocks.size());
|
||||
m_alias_redirect_lookup.emplace(zonePtr, value);
|
||||
}
|
||||
|
||||
void* ConvertOffsetToPointerNative(const void* offset) override
|
||||
{
|
||||
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
|
||||
// So all offsets are moved by 1.
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count));
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count));
|
||||
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);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@ -200,13 +314,13 @@ namespace
|
||||
return &block->m_buffer[blockOffset];
|
||||
}
|
||||
|
||||
void* ConvertOffsetToAlias(const void* offset) override
|
||||
void* ConvertOffsetToAliasNative(const void* offset) override
|
||||
{
|
||||
// For details see ConvertOffsetToPointer
|
||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||
|
||||
const auto blockNum = static_cast<block_t>(offsetInt >> (sizeof(offsetInt) * 8u - m_block_bit_count));
|
||||
const auto blockOffset = static_cast<size_t>(offsetInt & (UINTPTR_MAX >> m_block_bit_count));
|
||||
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);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
@ -219,14 +333,124 @@ namespace
|
||||
return *reinterpret_cast<void**>(&block->m_buffer[blockOffset]);
|
||||
}
|
||||
|
||||
private:
|
||||
void Align(const unsigned align)
|
||||
void AddPointerLookup(void* alias, const void* blockPtr) override
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
const auto* block = m_block_stack.top();
|
||||
assert(blockPtr >= block->m_buffer.get() && blockPtr < block->m_buffer.get() + block->m_buffer_size);
|
||||
|
||||
// Non-normal blocks cannot be referenced via zone pointer anyway
|
||||
if (block->m_type != XBlockType::BLOCK_TYPE_NORMAL)
|
||||
return;
|
||||
|
||||
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);
|
||||
m_pointer_redirect_lookup.emplace(zonePtr, alias);
|
||||
}
|
||||
|
||||
MaybePointerFromLookup<void> ConvertOffsetToPointerLookup(const void* offset) override
|
||||
{
|
||||
// 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);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
|
||||
auto* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset + sizeof(void*))
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
|
||||
const auto foundPointerLookup = m_pointer_redirect_lookup.find(offsetInt);
|
||||
if (foundPointerLookup != m_pointer_redirect_lookup.end())
|
||||
return MaybePointerFromLookup<void>(foundPointerLookup->second);
|
||||
|
||||
return MaybePointerFromLookup<void>(&block->m_buffer[blockOffset], blockNum, blockOffset);
|
||||
}
|
||||
|
||||
void* ConvertOffsetToAliasLookup(const void* offset) override
|
||||
{
|
||||
// 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);
|
||||
|
||||
if (blockNum < 0 || blockNum >= static_cast<block_t>(m_blocks.size()))
|
||||
throw InvalidOffsetBlockException(blockNum);
|
||||
|
||||
auto* block = m_blocks[blockNum];
|
||||
|
||||
if (block->m_buffer_size <= blockOffset + sizeof(uintptr_t))
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
|
||||
const auto foundAliasLookup = m_alias_redirect_lookup.find(offsetInt);
|
||||
if (foundAliasLookup != m_alias_redirect_lookup.end())
|
||||
return foundAliasLookup->second;
|
||||
|
||||
const auto foundPointerLookup = m_pointer_redirect_lookup.find(offsetInt);
|
||||
if (foundPointerLookup != m_pointer_redirect_lookup.end())
|
||||
return *static_cast<void**>(foundPointerLookup->second);
|
||||
|
||||
assert(false);
|
||||
throw InvalidOffsetBlockOffsetException(block, blockOffset);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OFFSETS
|
||||
void DebugOffsets(const size_t assetIndex) const override
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "Asset " << assetIndex;
|
||||
for (const auto& block : m_blocks)
|
||||
{
|
||||
if (block->m_type != XBlockType::BLOCK_TYPE_NORMAL)
|
||||
continue;
|
||||
|
||||
ss << " " << m_block_offsets[block->m_index];
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
std::cout << ss.str();
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
void LoadDataFromBlock(const XBlock& block, void* dst, const size_t size)
|
||||
{
|
||||
switch (block.m_type)
|
||||
{
|
||||
case XBlockType::BLOCK_TYPE_TEMP:
|
||||
case XBlockType::BLOCK_TYPE_NORMAL:
|
||||
m_stream.Load(dst, size);
|
||||
break;
|
||||
|
||||
case XBlockType::BLOCK_TYPE_RUNTIME:
|
||||
std::memset(dst, 0, size);
|
||||
break;
|
||||
|
||||
case XBlockType::BLOCK_TYPE_DELAY:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
IncBlockPos(block, size);
|
||||
}
|
||||
|
||||
void IncBlockPos(const XBlock& block, const size_t size)
|
||||
{
|
||||
m_block_offsets[block.m_index] += size;
|
||||
}
|
||||
|
||||
void Align(const XBlock& block, const unsigned align)
|
||||
{
|
||||
if (align > 0)
|
||||
{
|
||||
const auto blockIndex = m_block_stack.top()->m_index;
|
||||
const auto blockIndex = block.m_index;
|
||||
m_block_offsets[blockIndex] = utils::Align(m_block_offsets[blockIndex], static_cast<size_t>(align));
|
||||
}
|
||||
}
|
||||
@ -238,12 +462,28 @@ namespace
|
||||
std::stack<size_t> m_temp_offsets;
|
||||
ILoadingStream& m_stream;
|
||||
|
||||
unsigned m_block_bit_count;
|
||||
MemoryManager& m_memory;
|
||||
|
||||
unsigned m_pointer_byte_count;
|
||||
uintptr_t m_block_mask;
|
||||
unsigned m_block_shift;
|
||||
uintptr_t m_offset_mask;
|
||||
XBlock* m_insert_block;
|
||||
|
||||
std::vector<uint8_t> m_fill_buffer;
|
||||
size_t m_last_fill_size;
|
||||
// These lookups map a block offset to a pointer in case of a platform mismatch
|
||||
std::unordered_map<uintptr_t, void*> m_pointer_redirect_lookup;
|
||||
std::unordered_map<uintptr_t, void*> m_alias_redirect_lookup;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock)
|
||||
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(const unsigned pointerBitCount,
|
||||
const unsigned blockBitCount,
|
||||
std::vector<XBlock*>& blocks,
|
||||
const block_t insertBlock,
|
||||
ILoadingStream& stream,
|
||||
MemoryManager& memory)
|
||||
{
|
||||
return std::make_unique<XBlockInputStream>(blocks, stream, blockBitCount, insertBlock);
|
||||
return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream, memory);
|
||||
}
|
||||
|
@ -1,26 +1,178 @@
|
||||
#pragma once
|
||||
|
||||
#include "Loading/Exception/InvalidLookupPositionException.h"
|
||||
#include "Loading/ILoadingStream.h"
|
||||
#include "Utils/MemoryManager.h"
|
||||
#include "Zone/Stream/IZoneStream.h"
|
||||
#include "Zone/XBlock.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
// #define DEBUG_OFFSETS 1
|
||||
|
||||
class ZoneStreamFillReadAccessor
|
||||
{
|
||||
public:
|
||||
ZoneStreamFillReadAccessor(void* blockBuffer, size_t bufferSize, unsigned pointerByteCount, size_t offset);
|
||||
|
||||
[[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const;
|
||||
[[nodiscard]] size_t Offset() const;
|
||||
[[nodiscard]] void* BlockBuffer(size_t offset) const;
|
||||
|
||||
template<typename T> void Fill(T& value, const size_t offset) const
|
||||
{
|
||||
assert(offset + sizeof(T) <= m_buffer_size);
|
||||
|
||||
value = *reinterpret_cast<const T*>(static_cast<const char*>(m_block_buffer) + offset);
|
||||
}
|
||||
|
||||
template<typename T, size_t S> void FillArray(T (&value)[S], const size_t offset) const
|
||||
{
|
||||
assert(offset + sizeof(T) * S <= m_buffer_size);
|
||||
|
||||
std::memcpy(value, static_cast<const char*>(m_block_buffer) + offset, sizeof(T) * S);
|
||||
}
|
||||
|
||||
template<typename T> void FillPtr(T*& value, const size_t offset) const
|
||||
{
|
||||
assert(offset + m_pointer_byte_count <= m_buffer_size);
|
||||
assert(m_pointer_byte_count <= sizeof(uintptr_t));
|
||||
|
||||
value = nullptr;
|
||||
std::memcpy(&value, static_cast<const char*>(m_block_buffer) + offset, m_pointer_byte_count);
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_block_buffer;
|
||||
size_t m_buffer_size;
|
||||
unsigned m_pointer_byte_count;
|
||||
size_t m_offset;
|
||||
};
|
||||
|
||||
template<typename T> class MaybePointerFromLookup
|
||||
{
|
||||
public:
|
||||
explicit MaybePointerFromLookup(void* ptr)
|
||||
: m_valid(true),
|
||||
m_ptr(ptr),
|
||||
m_block(0),
|
||||
m_offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
MaybePointerFromLookup(void* ptr, const block_t block, const size_t offset)
|
||||
: m_valid(false),
|
||||
m_ptr(ptr),
|
||||
m_block(block),
|
||||
m_offset(offset)
|
||||
{
|
||||
}
|
||||
|
||||
explicit MaybePointerFromLookup(const MaybePointerFromLookup<void>& other)
|
||||
: m_valid(other.m_valid),
|
||||
m_ptr(static_cast<T*>(other.m_ptr)),
|
||||
m_block(other.m_block),
|
||||
m_offset(other.m_offset)
|
||||
{
|
||||
}
|
||||
|
||||
[[nodiscard]] T* Expect() const
|
||||
{
|
||||
if (!m_valid)
|
||||
throw InvalidLookupPositionException(m_block, m_offset);
|
||||
|
||||
return static_cast<T*>(m_ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* The original linker does an annoying optimization where ConvertOffsetToPointer makes structs
|
||||
* reuse data across non-matching types.
|
||||
* E.g. a pointer array reuses memory of a scriptstring array.
|
||||
* Since cross-platform the sizes of the types do not match anymore, this has to be handled differently.
|
||||
* The scenario seems to realistically only happen when the data is nulled so just alloc a nulled memory block.
|
||||
* If this strategy fails, in the future it might need to realloc and load existing block data with fill.
|
||||
*/
|
||||
[[nodiscard]] T* OrNulled(const size_t gameSize, const size_t size, MemoryManager& memory) const
|
||||
{
|
||||
if (m_valid)
|
||||
return static_cast<T*>(m_ptr);
|
||||
|
||||
auto* result = static_cast<T*>(memory.AllocRaw(size));
|
||||
|
||||
// We expect the original game buffer to also have been nulled
|
||||
assert(gameSize < size);
|
||||
assert(memcmp(result, m_ptr, gameSize) == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool m_valid;
|
||||
void* m_ptr;
|
||||
block_t m_block;
|
||||
size_t m_offset;
|
||||
};
|
||||
|
||||
class ZoneInputStream : public IZoneStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Returns the configured bits that make up a pointer.
|
||||
*/
|
||||
[[nodiscard]] virtual unsigned GetPointerBitCount() const = 0;
|
||||
|
||||
/**
|
||||
* \brief Retrieves the new read position in the current block by aligning the position with the specified value and then returning the current read
|
||||
* position in the block.
|
||||
* \param align The alignment value that the read position is aligned with before being returned. This should typically be the alignment of the struct that
|
||||
* should be read afterward.
|
||||
* \return A pointer to the memory in which following load calls will load data to.
|
||||
*/
|
||||
virtual void* Alloc(unsigned align) = 0;
|
||||
|
||||
/**
|
||||
* \copydoc ZoneInputStream#Alloc(unsigned)
|
||||
*/
|
||||
template<typename T> T* Alloc(const unsigned align)
|
||||
{
|
||||
return static_cast<T*>(Alloc(align));
|
||||
}
|
||||
|
||||
virtual void* AllocOutOfBlock(unsigned align, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* \copydoc ZoneInputStream#AllocOutOfBlock(unsigned)
|
||||
*/
|
||||
template<typename T> T* AllocOutOfBlock(const unsigned align, const size_t arraySize = 1u)
|
||||
{
|
||||
return static_cast<T*>(AllocOutOfBlock(align, sizeof(T) * arraySize));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Loads data from the underlying stream without considering the current block or advancing the block position.
|
||||
* The data is read directly to the specified location instead of block memory.
|
||||
* \param dst The memory location to load data to.
|
||||
* \param size The amount of data to load.
|
||||
*/
|
||||
virtual void LoadDataRaw(void* dst, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* \brief Loads data with the current blocks read operation into its block memory.
|
||||
* Depending on the block type, the underlying stream might be read from or not.
|
||||
* The current block position is advanced by the number of bytes read.
|
||||
* The destination must be inside the current block's memory space, otherwise an exception is thrown.
|
||||
* \param dst The destination where the data is loaded to. Must be inside the current block's memory bounds.
|
||||
* \param size The amount of data to load.
|
||||
*/
|
||||
virtual void LoadDataInBlock(void* dst, size_t size) = 0;
|
||||
virtual void IncBlockPos(size_t size) = 0;
|
||||
virtual void LoadNullTerminated(void* dst) = 0;
|
||||
virtual ZoneStreamFillReadAccessor LoadWithFill(size_t size) = 0;
|
||||
virtual ZoneStreamFillReadAccessor AppendToFill(size_t appendSize) = 0;
|
||||
virtual ZoneStreamFillReadAccessor GetLastFill() = 0;
|
||||
|
||||
template<typename T> void Load(T* dst)
|
||||
{
|
||||
@ -37,26 +189,55 @@ public:
|
||||
LoadDataInBlock(const_cast<void*>(reinterpret_cast<const void*>(dst)), size);
|
||||
}
|
||||
|
||||
virtual void** InsertPointer() = 0;
|
||||
virtual void* InsertPointerNative() = 0;
|
||||
|
||||
template<typename T> T** InsertPointer()
|
||||
template<typename T> T** InsertPointerNative()
|
||||
{
|
||||
return reinterpret_cast<T**>(InsertPointer());
|
||||
return static_cast<T**>(InsertPointerNative());
|
||||
}
|
||||
|
||||
virtual void* ConvertOffsetToPointer(const void* offset) = 0;
|
||||
virtual uintptr_t InsertPointerAliasLookup() = 0;
|
||||
virtual void SetInsertedPointerAliasLookup(uintptr_t lookupEntry, void* value) = 0;
|
||||
|
||||
template<typename T> T* ConvertOffsetToPointer(T* offset)
|
||||
virtual void* ConvertOffsetToPointerNative(const void* offset) = 0;
|
||||
|
||||
template<typename T> T* ConvertOffsetToPointerNative(T* offset)
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToPointer(static_cast<const void*>(offset)));
|
||||
return static_cast<T*>(ConvertOffsetToPointerNative(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
virtual void* ConvertOffsetToAlias(const void* offset) = 0;
|
||||
virtual void* ConvertOffsetToAliasNative(const void* offset) = 0;
|
||||
|
||||
template<typename T> T* ConvertOffsetToAlias(T* offset)
|
||||
template<typename T> T* ConvertOffsetToAliasNative(T* offset)
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToAlias(static_cast<const void*>(offset)));
|
||||
return static_cast<T*>(ConvertOffsetToAliasNative(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
static std::unique_ptr<ZoneInputStream> Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock);
|
||||
/**
|
||||
* \brief Adds a lookup from a block pointer to out of block data
|
||||
* \param redirectTo A pointer to the out of block data to redirect to
|
||||
* \param redirectFrom A pointer to the block data to redirect from
|
||||
*/
|
||||
virtual void AddPointerLookup(void* redirectTo, const void* redirectFrom) = 0;
|
||||
|
||||
virtual MaybePointerFromLookup<void> ConvertOffsetToPointerLookup(const void* offset) = 0;
|
||||
|
||||
template<typename T> MaybePointerFromLookup<T> ConvertOffsetToPointerLookup(T* offset)
|
||||
{
|
||||
return MaybePointerFromLookup<T>(ConvertOffsetToPointerLookup(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
virtual void* ConvertOffsetToAliasLookup(const void* offset) = 0;
|
||||
|
||||
template<typename T> T* ConvertOffsetToAliasLookup(T* offset)
|
||||
{
|
||||
return static_cast<T*>(ConvertOffsetToAliasLookup(static_cast<const void*>(offset)));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_OFFSETS
|
||||
virtual void DebugOffsets(size_t assetIndex) const = 0;
|
||||
#endif
|
||||
|
||||
static std::unique_ptr<ZoneInputStream> Create(
|
||||
unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, ILoadingStream& stream, MemoryManager& memory);
|
||||
};
|
||||
|
@ -22,15 +22,15 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(IW3::XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
@ -24,15 +24,15 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_CALLBACK, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_VERTEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_INDEX, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(XFILE_BLOCK_SCRIPT, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL_RUNTIME, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_LARGE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T5::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
@ -29,14 +29,14 @@ namespace
|
||||
{
|
||||
#define XBLOCK_DEF(name, type) std::make_unique<XBlock>(STR(name), name, type)
|
||||
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlock::Type::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlock::Type::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlock::Type::BLOCK_TYPE_DELAY));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlock::Type::BLOCK_TYPE_DELAY));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlock::Type::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_TEMP, XBlockType::BLOCK_TYPE_TEMP));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_VIRTUAL, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_RUNTIME_PHYSICAL, XBlockType::BLOCK_TYPE_RUNTIME));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_VIRTUAL, XBlockType::BLOCK_TYPE_DELAY));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_DELAY_PHYSICAL, XBlockType::BLOCK_TYPE_DELAY));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_VIRTUAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_PHYSICAL, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
writer.AddXBlock(XBLOCK_DEF(T6::XFILE_BLOCK_STREAMER_RESERVE, XBlockType::BLOCK_TYPE_NORMAL));
|
||||
|
||||
#undef XBLOCK_DEF
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ void InMemoryZoneOutputStream::PushBlock(const block_t block)
|
||||
|
||||
m_block_stack.push(newBlock);
|
||||
|
||||
if (newBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
if (m_temp_sizes.empty())
|
||||
m_temp_sizes.push(0);
|
||||
@ -50,7 +50,7 @@ block_t InMemoryZoneOutputStream::PopBlock()
|
||||
m_block_stack.pop();
|
||||
|
||||
// If temp block is popped, see if its size is bigger than the current maximum temp size
|
||||
if (poppedBlock->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
const auto tempSize = m_temp_sizes.top();
|
||||
m_temp_sizes.pop();
|
||||
@ -70,7 +70,7 @@ void InMemoryZoneOutputStream::Align(const int align)
|
||||
{
|
||||
auto* block = m_block_stack.top();
|
||||
|
||||
if (block->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
m_temp_sizes.top() = (m_temp_sizes.top() + align - 1) / align * align;
|
||||
else
|
||||
block->m_buffer_size = (block->m_buffer_size + align - 1) / align * align;
|
||||
@ -96,16 +96,16 @@ void* InMemoryZoneOutputStream::WriteDataInBlock(const void* src, const size_t s
|
||||
void* result = nullptr;
|
||||
switch (block->m_type)
|
||||
{
|
||||
case XBlock::Type::BLOCK_TYPE_TEMP:
|
||||
case XBlock::Type::BLOCK_TYPE_NORMAL:
|
||||
case XBlockType::BLOCK_TYPE_TEMP:
|
||||
case XBlockType::BLOCK_TYPE_NORMAL:
|
||||
result = m_zone_data->GetBufferOfSize(size);
|
||||
memcpy(result, src, size);
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||
case XBlockType::BLOCK_TYPE_RUNTIME:
|
||||
break;
|
||||
|
||||
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||
case XBlockType::BLOCK_TYPE_DELAY:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
@ -122,7 +122,7 @@ void InMemoryZoneOutputStream::IncBlockPos(const size_t size)
|
||||
return;
|
||||
|
||||
auto* block = m_block_stack.top();
|
||||
if (block->m_type == XBlock::Type::BLOCK_TYPE_TEMP)
|
||||
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||
{
|
||||
m_temp_sizes.top() += size;
|
||||
}
|
||||
@ -141,7 +141,7 @@ void InMemoryZoneOutputStream::WriteNullTerminated(const void* src)
|
||||
uintptr_t InMemoryZoneOutputStream::GetCurrentZonePointer()
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
assert(m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_NORMAL);
|
||||
assert(m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_NORMAL);
|
||||
|
||||
uintptr_t ptr = 0;
|
||||
ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (sizeof(uintptr_t) * 8 - m_block_bit_count);
|
||||
@ -168,7 +168,7 @@ void InMemoryZoneOutputStream::MarkFollowing(void** pPtr)
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
assert(pPtr != nullptr);
|
||||
*pPtr = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING;
|
||||
*pPtr = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING;
|
||||
}
|
||||
|
||||
bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type)
|
||||
@ -202,7 +202,7 @@ void InMemoryZoneOutputStream::ReusableAddOffset(void* ptr, size_t size, size_t
|
||||
{
|
||||
assert(!m_block_stack.empty());
|
||||
|
||||
const auto inTemp = m_block_stack.top()->m_type == XBlock::Type::BLOCK_TYPE_TEMP;
|
||||
const auto inTemp = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP;
|
||||
auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer();
|
||||
const auto foundEntriesForType = m_reusable_entries.find(type);
|
||||
if (foundEntriesForType == m_reusable_entries.end())
|
||||
|
Loading…
x
Reference in New Issue
Block a user